Einen solchen Check gibt es für Excel.
Ob das auch für Word funktioniert, müsstest Du testen.
Microsoft Word: Suche und ersetze Text in den Inhalten der VBA-Progammierung (gelöst)
-
-
Vielen Dank für den Hinweis. Ich habe das getestet, doch es hat nicht funktioniert, da nicht die Datei selbst, sondern der VB-Inhalt mit einem Kennwort geschützt wurde.
Code; Open the Document Local $oDoc = _Word_DocOpen($oWord, $sTemplate) If @error Then If @extended = -2147352567 Then ConsoleWrite(" Schreibgeschützt!" & @CRLF) _Word_DocClose($oDoc) EndIf EndIf
Das ist die Consolenausgabe bei dem Fehler:
Code"D:\Documents\VBA\Vorlagen\Vorlagenscript_5.au3" (63) : ==> The requested action with this object has failed.: For $oVBComponent In $oVBProject.VBComponents For $oVBComponent In $oVBProject^ ERROR ->20:46:04 AutoIt3.exe ended.rc:1 +>20:46:04 AutoIt3Wrapper Finished. >Exit code: 1 Time: 653.8
Das hat auch nicht funktioniert:
Code; Open the Document Local $oDoc = _Word_DocOpen($oWord, $sTemplate) If @error Then _Word_DocClose($oDoc)
Was könnte ich noch versuchen, damit ein kennwortgeschütztes Dokument einfach nach dem öffnen wieder schließt und es anschließend mit der Stapelverarbeitung weitergeht?
-
Dann braucht es einen COM error handler. Damit wird der Fehler abgefangen und das Skript crashed nicht mehr. Der Fehlercode kann dann im Skript abgefragt werden und die Funktion _VBAModify mit Return beenet werden.
C
Alles anzeigen#include <Word.au3> #include <MsgBoxConstants.au3> ; ********** Änderungen nur NACH dieser Zeile ********** ; Table with search and replace strings to process Global $aSearchReplace[][] = [ _ ["Tester","Master"], _ ["True","False"], _ ["Maier","Müller"] _ ] ; For code with the following strings no replacement will be done at all Global $aIgnore[] = [ _ 'ActiveDocument.Bookmarks("Amtsleiter")"', _ '.UpdateFieldsAtPrint = True' _ ] Global $sTemplate = @ScriptDir & "\I-Brief" ; Zu verarbeitende Word Vorlagedatei ; ********** Änderungen nur VOR dieser Zeile ********** Global $sExtension = ".dotm" Global $iTotalProjectCount = 0, $iTotalComponentCount = 0, $iTotalReplacementCount = 0 ; Set up debugging Global $__iWord_Debug = 0 ; Debug level. 0 = no debug information, 1 = Debug info to consWorde, 2 = Debug info to MsgBox, 3 = Debug Info to File Global $__sWord_DebugFile = @ScriptDir & "\Word_Debug.txt" ; Debug file when $__iWord_Debug is set to 3 Global $__oWord_Error ; COM Error handler ; Start the MS Word application Global $oWord = _Word_Create() If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_Create: @error=" & @error & ", @extended=" & @extended) _Word_ErrorNotify(2) ; Process the Template _VBAModify($sTemplate) Exit Func _VBAModify($sTemplate) ; Open the Document Global $oDoc = _Word_DocOpen($oWord, $sTemplate & $sExtension) If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_DocOpen: @error=" & @error & ", @extended=" & @extended) ; Collect statistics and output them to the Console ConsoleWrite("PROCESSING: " & $sTemplate & $sExtension & @CRLF) ConsoleWrite(" STATISTICS" & @CRLF & " ==========" & @CRLF) For $oVBProject In $oWord.VBE.VBProjects ConsoleWrite(" VBProject: " & $oVBProject.Name & ", Typ: " & $oVBProject.Type) Switch $oVBProject.Type Case 100 ConsoleWrite(" (vbext_pt_HostProject - Host project)" & @CRLF) Case 101 ConsoleWrite(" (vbext_pt_StandAlone - Standalone Project)" & @CRLF) Case Else ConsoleWrite(" Unknown Project Type!" & @CRLF) EndSwitch For $oVBComponent In $oVBProject.VBComponents ConsoleWrite(" VBComponent: " & $oVBComponent.Name & ", Typ: " & $oVBComponent.Type) Switch $oVBComponent.Type Case 1 ConsoleWrite(" (vbext_ct_StdModule - Standard module)" & @CRLF) Case 2 ConsoleWrite(" (vbext_ct_ClassModule - Class module)" & @CRLF) Case 3 ConsoleWrite(" (vbext_ct_MSForm - Microsoft Form)" & @CRLF) Case 11 ConsoleWrite(" (vbext_ct_ActiveXDesigner - ActiveX Designer)" & @CRLF) Case 100 ConsoleWrite(" (vbext_ct_Document - Document Module)" & @CRLF) Case Else ConsoleWrite(" Unknown Component Type!" & @CRLF) EndSwitch Next Next ; Process all VBProjects and VBComponents ConsoleWrite(" SEARCH & REPLACE" & @CRLF & " ================" & @CRLF) For $oVBProject In $oWord.VBE.VBProjects ConsoleWrite(" VBProject: " & $oVBProject.Name & @CRLF) $iTotalProjectCount += 1 For $oVBComponent In $oVBProject.VBComponents ConsoleWrite(" VBComponent: " & $oVBComponent.Name & @CRLF) $iTotalComponentCount += 1 Switch $oVBComponent.Type ; Only Standard Modules and Microsoft Forms will be processed Case 1, 3 $oCodeModule = $oVBComponent.CodeModule If @error Then Exit MsgBox($MB_ICONERROR, "Error", "CodeModule: @error=" & @error & ", @extended=" & @extended) With $oCodeModule $iReplaceCount = 0 For $i = 1 To .CountOfLines $bIgnore = False For $j = 0 To UBound($aIgnore, 1) - 1 If StringInStr(.Lines($i, 1), $aIgnore[$j]) Then $bIgnore = True Next If $bIgnore = False Then For $j = 0 To UBound($aSearchReplace, 1) - 1 If StringInStr(.Lines($i, 1), $aSearchReplace[$j][0]) Then .ReplaceLine($i, StringReplace(.Lines($i, 1), $aSearchReplace[$j][0], $aSearchReplace[$j][1])) $iReplaceCount = $iReplaceCount + 1 EndIf Next EndIf Next ConsoleWrite(" " & $iReplaceCount & " replacements" & @CRLF) $iTotalReplacementCount = $iTotalReplacementCount + $iReplaceCount EndWith Case Else ConsoleWrite(" Not processed!" & @CRLF) EndSwitch Next Next ; Send total Statistics for this document to the Console ConsoleWrite(" SEARCH & REPLACE - TOTAL STATISTICS" & @CRLF & " ===================================" & @CRLF) ConsoleWrite(" VBProjects processed : " & $iTotalProjectCount & @CRLF) ConsoleWrite(" VBComponents processed: " & $iTotalComponentCount & @CRLF) ConsoleWrite(" Replacements done : " & $iTotalReplacementCount & @CRLF) ; Save as new Document _Word_DocSaveAs($oDoc, $sTemplate & "-NEW" & $sExtension, $WdFormatXMLTemplateMacroEnabled) If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_DocSaveAs: @error=" & @error & ", @extended=" & Hex(@extended)) ; Close Document _Word_DocClose($oDoc) EndFunc ;==>_VBAModify Func _Word_ErrorNotify($iDebug, $sDebugFile = "") If $sDebugFile = Default Then $sDebugFile = "" If Not IsInt($iDebug) Or $iDebug < -1 Or $iDebug > 4 Then Return SetError(1, 0, 0) If $sDebugFile = "" Then $sDebugFile = @ScriptDir & "\Word_Debug.txt" Switch $iDebug Case -1 Local $avDebug[4] = [3] $avDebug[1] = $__iWord_Debug $avDebug[2] = $__sWord_DebugFile $avDebug[3] = IsObj($__oWord_Error) Return $avDebug Case 0 $__iWord_Debug = 0 $__sWord_DebugFile = "" $__oWord_Error = 0 Case Else $__iWord_Debug = $iDebug $__sWord_DebugFile = $sDebugFile ; A COM error handler will be initialized only if one does not exist If ObjEvent("AutoIt.Error") = "" Then $__oWord_Error = ObjEvent("AutoIt.Error", "__Word_ErrorHandler") ; Creates a custom error handler If @error <> 0 Then Return SetError(2, @error, 0) Return SetError(0, 1, 1) ElseIf ObjEvent("AutoIt.Error") = "__Word_ErrorHandler" Then Return SetError(0, 0, 1) ; COM error handler already set by a call to this function Else Return SetError(3, 0, 0) ; COM error handler already set to another function EndIf EndSwitch Return 1 EndFunc ;==>_Word_ErrorNotify Func __Word_ErrorHandler() Local $sError = "COM Error Encountered in " & @ScriptName & @CRLF & _ "@AutoItVersion = " & @AutoItVersion & @CRLF & _ "@AutoItX64 = " & @AutoItX64 & @CRLF & _ "@Compiled = " & @Compiled & @CRLF & _ "@OSArch = " & @OSArch & @CRLF & _ "@OSVersion = " & @OSVersion & @CRLF & _ "Scriptline = " & $__oWord_Error.Scriptline & @CRLF & _ "NumberHex = 0x" & Hex($__oWord_Error.Number, 8) & @CRLF & _ "Number = " & $__oWord_Error.Number & @CRLF & _ "WinDescription = " & StringStripWS($__oWord_Error.WinDescription, $STR_STRIPTRAILING) & @CRLF & _ "Description = " & StringStripWS($__oWord_Error.Description, $STR_STRIPTRAILING) & @CRLF & _ "Source = " & $__oWord_Error.Source & @CRLF & _ "HelpFile = " & $__oWord_Error.HelpFile & @CRLF & _ "HelpContext = " & $__oWord_Error.HelpContext & @CRLF & _ "LastDllError = " & $__oWord_Error.LastDllError If $__iWord_Debug > 0 Then If $__iWord_Debug = 1 Then ConsoleWrite($sError & @CRLF & "========================================================" & @CRLF) If $__iWord_Debug = 2 Then MsgBox($MB_ICONERROR, "Word - Debug Info", $sError) If $__iWord_Debug = 3 Then FileWrite($__sWord_DebugFile, @YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " & @CRLF & _ "-------------------" & @CRLF & $sError & @CRLF & "========================================================" & @CRLF) EndIf EndFunc ;==>__Word_ErrorHandler
-
Dann braucht es einen COM error handler. Damit wird der Fehler abgefangen und das Skript crashed nicht mehr. Der Fehlercode kann dann im Skript abgefragt werden und die Funktion _VBAModify mit Return beenet werden.
Herzlichen Dank für die kompetente und freundliche Hilfe.
Das ist für mich ein mächtig kompliziertes Konstrukt. Das hätte ich niemals alleine geschafft.
Ich teste das ganze am Wochenende in Ruhe und hoffe, dass ich Dich mit meinen immerzu "letzten" Fragen nicht mehr weiter belästige (wobei versprechen kann ich das nicht :-)).
-
Hallo water
Die Fehler werden jetzt Dank Deines "COM error handler" abgefangen und das Skript crashed nicht mehr, sondern läuft nach Bestätigen der Debug-Info weiter bis zum Ende durch.
Ich kann mit dem Skript sehr gut arbeiten und sogar die wenigen geschützten von den ungeschützen Dokumenten aufgrund der Consolenausgabe des Errorhandlings prima separieren.
Zusätzlich werde ich noch den Vorschlag von BugFix aufnehmen und möchte die eh schon vorhandene .txt-Datei (quasi die Datenbank welche alle ca. 400 Benutzer beinhaltet) so aufbereiten, dass die zu suchenden Strings bei zukünftigen Namensänderungen aus der .txt-Datei ausgelesen werden können.
Anbei noch beide Debug Info-Meldungen welche (vom COM error handler) jeweils bei den kennwortgeschützten MS-Word-Vorlagen abgefangen wurden:
Hier das gesamte Skript (mit Stapelverarbeitung). Wenn es noch jemmand nutzen möchte.
C
Alles anzeigen#include <File.au3> #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <Word.au3> #include <WordConstants.au3> ; https://autoit.de/thread/87817-microsoft-word-suche-und-ersetze-text-in-den-inhalten-der-vba-progammierung-gel%C3%B6/?postID=708429#post708429 ; ********** Änderungen nur NACH dieser Zeile ********** ; Table with search and replace strings to process Global $aSearchReplace[][] = [ _ ["Text 1","Text 2"], _ ["",""], _ ["",""] _ ] ; For code with the following strings no replacement will be done at all Global $aIgnore[] = [ _ 'ActiveDocument.Bookmarks("Text")"', _ '.UpdateFieldsAtPrint = True' _ ] ; ********** Änderungen nur VOR dieser Zeile ********** Global $sExtension = ".dotm" ; Verarbeite nur MS-Word Vorlagendatei mit Macros. Global $sTemplate = _FileListToArrayRec(@ScriptDir, "*" & $sExtension, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) ; Auflistung der rekursiv zu verarbeitenden MS-Word Vorlagedateien Global $iTotalProjectCount = 0, $iTotalComponentCount = 0, $iTotalReplacementCount = 0 ; Set up debugging Global $__iWord_Debug = 0 ; Debug level. 0 = no debug information, 1 = Debug info to consWorde, 2 = Debug info to MsgBox, 3 = Debug Info to File Global $__sWord_DebugFile = @ScriptDir & "\Word_Debug.txt" ; Debug file when $__iWord_Debug is set to 3 Global $__oWord_Error ; COM Error handler _ArrayDisplay($sTemplate, "");Ansicht der zu verarbeitenden Dateien anzeigen lassen (optional) ; Start the MS Word application Global $oWord = _Word_Create() If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_Create: @error=" & @error & ", @extended=" & @extended) _Word_ErrorNotify(2) ; Process the Template For $i = 1 to $sTemplate[0] ; rekursives Ermitteln der zu verarbeitenden Dateien _VBAModify($sTemplate[$i]) ; Start der Search & Replace Funktion in Word Next Exit Func _VBAModify($sTemplate) ; Open the Document Local $oDoc = _Word_DocOpen($oWord, $sTemplate) If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_DocOpen: @error=" & @error & ", @extended=" & @extended) ; Collect statistics and output them to the Console ConsoleWrite("PROCESSING: " & $sTemplate & $sExtension & @CRLF) ConsoleWrite(" STATISTICS" & @CRLF & " ==========" & @CRLF) For $oVBProject In $oWord.VBE.VBProjects ConsoleWrite(" VBProject: " & $oVBProject.Name & ", Typ: " & $oVBProject.Type) Switch $oVBProject.Type Case 100 ConsoleWrite(" (vbext_pt_HostProject - Host project)" & @CRLF) Case 101 ConsoleWrite(" (vbext_pt_StandAlone - Standalone Project)" & @CRLF) Case Else ConsoleWrite(" Unknown Project Type!" & @CRLF) EndSwitch For $oVBComponent In $oVBProject.VBComponents ConsoleWrite(" VBComponent: " & $oVBComponent.Name & ", Typ: " & $oVBComponent.Type) Switch $oVBComponent.Type Case 1 ConsoleWrite(" (vbext_ct_StdModule - Standard module)" & @CRLF) Case 2 ConsoleWrite(" (vbext_ct_ClassModule - Class module)" & @CRLF) Case 3 ConsoleWrite(" (vbext_ct_MSForm - Microsoft Form)" & @CRLF) Case 11 ConsoleWrite(" (vbext_ct_ActiveXDesigner - ActiveX Designer)" & @CRLF) Case 100 ConsoleWrite(" (vbext_ct_Document - Document Module)" & @CRLF) Case Else ConsoleWrite(" Unknown Component Type!" & @CRLF) EndSwitch Next Next ; Process all VBProjects and VBComponents ConsoleWrite(" SEARCH & REPLACE" & @CRLF & " ================" & @CRLF) For $oVBProject In $oWord.VBE.VBProjects ConsoleWrite(" VBProject: " & $oVBProject.Name & @CRLF) $iTotalProjectCount += 1 For $oVBComponent In $oVBProject.VBComponents ConsoleWrite(" VBComponent: " & $oVBComponent.Name & @CRLF) $iTotalComponentCount += 1 Switch $oVBComponent.Type ; Only Standard Modules and Microsoft Forms will be processed Case 1, 3 $oCodeModule = $oVBComponent.CodeModule If @error Then Exit MsgBox($MB_ICONERROR, "Error", "CodeModule: @error=" & @error & ", @extended=" & @extended) With $oCodeModule $iReplaceCount = 0 For $i = 1 To .CountOfLines $bIgnore = False For $j = 0 To UBound($aIgnore, 1) - 1 If StringInStr(.Lines($i, 1), $aIgnore[$j]) Then $bIgnore = True Next If $bIgnore = False Then For $j = 0 To UBound($aSearchReplace, 1) - 1 If StringInStr(.Lines($i, 1), $aSearchReplace[$j][0]) Then .ReplaceLine($i, StringReplace(.Lines($i, 1), $aSearchReplace[$j][0], $aSearchReplace[$j][1])) $iReplaceCount = $iReplaceCount + 1 EndIf Next EndIf Next ConsoleWrite(" " & $iReplaceCount & " replacements" & @CRLF) $iTotalReplacementCount = $iTotalReplacementCount + $iReplaceCount EndWith Case Else ConsoleWrite(" Not processed!" & @CRLF) EndSwitch Next Next ; Send total Statistics for this document to the Console ConsoleWrite(" SEARCH & REPLACE - TOTAL STATISTICS" & @CRLF & " ===================================" & @CRLF) ConsoleWrite(" VBProjects processed : " & $iTotalProjectCount & @CRLF) ConsoleWrite(" VBComponents processed: " & $iTotalComponentCount & @CRLF) ConsoleWrite(" Replacements done : " & $iTotalReplacementCount & @CRLF) ; Save as new Document _Word_DocSaveAs($oDoc, $sTemplate, $WdFormatXMLTemplateMacroEnabled) If @error Then Exit MsgBox($MB_ICONERROR, "Error", "_Word_DocSaveAs: @error=" & @error & ", @extended=" & Hex(@extended)) ; Close Document _Word_DocClose($oDoc) EndFunc ;==>_VBAModify Func _Word_ErrorNotify($iDebug, $sDebugFile = "") If $sDebugFile = Default Then $sDebugFile = "" If Not IsInt($iDebug) Or $iDebug < -1 Or $iDebug > 4 Then Return SetError(1, 0, 0) If $sDebugFile = "" Then $sDebugFile = @ScriptDir & "\Word_Debug.txt" Switch $iDebug Case -1 Local $avDebug[4] = [3] $avDebug[1] = $__iWord_Debug $avDebug[2] = $__sWord_DebugFile $avDebug[3] = IsObj($__oWord_Error) Return $avDebug Case 0 $__iWord_Debug = 0 $__sWord_DebugFile = "" $__oWord_Error = 0 Case Else $__iWord_Debug = $iDebug $__sWord_DebugFile = $sDebugFile ; A COM error handler will be initialized only if one does not exist If ObjEvent("AutoIt.Error") = "" Then $__oWord_Error = ObjEvent("AutoIt.Error", "__Word_ErrorHandler") ; Creates a custom error handler If @error <> 0 Then Return SetError(2, @error, 0) Return SetError(0, 1, 1) ElseIf ObjEvent("AutoIt.Error") = "__Word_ErrorHandler" Then Return SetError(0, 0, 1) ; COM error handler already set by a call to this function Else Return SetError(3, 0, 0) ; COM error handler already set to another function EndIf EndSwitch Return 1 EndFunc ;==>_Word_ErrorNotify Func __Word_ErrorHandler() Local $sError = "COM Error Encountered in " & @ScriptName & @CRLF & _ "@AutoItVersion = " & @AutoItVersion & @CRLF & _ "@AutoItX64 = " & @AutoItX64 & @CRLF & _ "@Compiled = " & @Compiled & @CRLF & _ "@OSArch = " & @OSArch & @CRLF & _ "@OSVersion = " & @OSVersion & @CRLF & _ "Scriptline = " & $__oWord_Error.Scriptline & @CRLF & _ "NumberHex = 0x" & Hex($__oWord_Error.Number, 8) & @CRLF & _ "Number = " & $__oWord_Error.Number & @CRLF & _ "WinDescription = " & StringStripWS($__oWord_Error.WinDescription, $STR_STRIPTRAILING) & @CRLF & _ "Description = " & StringStripWS($__oWord_Error.Description, $STR_STRIPTRAILING) & @CRLF & _ "Source = " & $__oWord_Error.Source & @CRLF & _ "HelpFile = " & $__oWord_Error.HelpFile & @CRLF & _ "HelpContext = " & $__oWord_Error.HelpContext & @CRLF & _ "LastDllError = " & $__oWord_Error.LastDllError If $__iWord_Debug > 0 Then If $__iWord_Debug = 1 Then ConsoleWrite($sError & @CRLF & "========================================================" & @CRLF) If $__iWord_Debug = 2 Then MsgBox($MB_ICONERROR, "Word - Debug Info", $sError) If $__iWord_Debug = 3 Then FileWrite($__sWord_DebugFile, @YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " & @CRLF & _ "-------------------" & @CRLF & $sError & @CRLF & "========================================================" & @CRLF) EndIf EndFunc ;==>__Word_ErrorHandler
-
-
Werde ich machen. Herzlichen Dank für den Hinweis.
-
Hallo zusammen!
ich bin eben auf diesen grandiosen Post gestoßen, der mein Problem fast, aber eben nur fast zu lösen vermag.
Mein Anliegen ist eigentlich etwas simpler, der hier angebotene Code allerdings so komplex, dass ich nicht daran herumschrauben (ver)mag.
Hier mein Anliegen:
Ich benötige die gleiche Funktionalität - allerdings nicht im VBA-Modul eines dotm sondern im Body eines docx.
Mein Versuch den Code einfach umzuschreiben scheiterte an meinem mangelhaften Verständnis auf der Objektebene der Word-Dokumente.
Nachdem der Text ersetzt wurde, soll das Dokument als PDF gespeichert werden - das bekäme ich noch hin
Vielleicht kann mir jemand helfen?
-
Body eines docx
Was meinst Du damit?
-
Body ist der Text des Dokumentes ohne Kopf- und Fußzeilen.
-
Also der Textkörper. Ich schau mal was sich machen lässt. Aber erst Samstag nachmittag.
-
MiX-MoX
Wenn Du nur im Body suchen/ersetzen willst, dann verwende die im AutoIt-Standard enthaltene Word UDF, Funktion _Word_DocFindReplace -
M.E. würde dafür VBA reichen. AutoIt wäre dafür überdimensioniert.
-
M.E. würde dafür VBA reichen. AutoIt wäre dafür überdimensioniert.
VBA erfordert aber .dotm Dokumente, die in einigen Unternehmen nicht erlaubt sind.
-
Die Ausswahl der Programmierumgebung bzw. -sprache hängt von vielen Faktoren ab.
Und da der OP im AutoIt-Forum gepostet hat, nehme ich an, dass dies seine bevorzugte Sprache ist.
-
M.E. würde dafür VBA reichen. AutoIt wäre dafür überdimensioniert.
Grundsätzlich ist jede Excel- / Word- etc. Programmierung in der direkt von Haus aus vorhandenen VBA-Umgebung lösbar. Teilweise auch viel direkter. Auch wenn VBA nicht schwierig ist, müsste man sich trotzdem erstmal intensiv damit befassen um eine vernünftige Lösung zu erstellen. Da bleibt zu überlegen, ob man diese Zeit aufwenden möchte oder in der vertrauten (AutoIt) Umgebung das Projekt umsetzt.
Das Gute ist ja, dass beide Varianten innerhalb von AutoIt genutzt werden können. Somit bleibt die freie Wahl nach eigenem Gusto.
-
Habe da ja ganz schön was losgetreten
Ich benötige eine EXE um aus SAP bzw. der CoreSuite heraus einen bestimmten Prozess anzustoßen, den die bei SAP nicht hinbekommen.
Möglicherweise könnte ich in der SAP CoreSuite direkt VBA-Code einbetten - ich finde die Möglichkeit das via AutoIT zu machen "bequemer" und potenter,
denn im Gegensatz zu VB in der SAP - Umgebung weiß ich, dass ich über AutoIT Word-Objekte ansprechen kann.
Mein Anliegen hat sich schon wieder fast erledigt, die Lösung über das hier vorgestellte Skript wäre die Deluxe-Lösung.
Ich habe auf die Schnelle eines in diesem Post der erstgenannten Skripte - das für Excel gedacht war - auf Word-Objekte umgeschrieben.
Dass passt jetzt weitestgehend, wenn auch ohne die ganze Fehlerbetrachtung und statistischen Auswertungen.
Mein Skript wird- wenn es fertig ist - folgendes machen:
Das Skript wird über Parameter aufgerufen.
Die Parameter enthalten Informationen über die eine bestimmte Text-Datei und eine bestimmte Word-Datei geöffnet werden können.
In dieser Textdatei wird ein mehrzeiliger Datensatz bereitgestellt.
Das Skript liest die Textdatei in ein Array, und führt innerhalb des Word-Dokumentes eine Suchen und Ersetzen-Prozedur aus - mit Daten aus dem Array.
Anschließend wird das Word-Dokument unter einem bestimmten Namen als PDF gespeichert.Das ganze steht im Zusammenhang mit REACH und der Verpflichtung der Hersteller, dem Handel Sicherheitsdatenblätter mit Händlerinformationen bereitzustellen.
Serienbriefe oder ähnliches sind kein Lösungsansatz, denn es geht um ca. 8.000 Word -Dokumente (SDB) und einige hundert Händler.
Sowohl die Händlerdaten als auch die Daten in den SDB unterliegen ständigen Änderungen.
Ich stelle das Skript hier rein, wenn es fertig ist.
-
Bei SAP bin ich raus.
-
Hallo zusammen,
hier mein Code:
C
Alles anzeigen#include <File.au3> #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <Word.au3> #include <WordConstants.au3> ; https://autoit.de/thread/87817-microsoft-word-suche-und-ersetze-text-in-den-inhalten-der-vba-progammierung-gel%C3%B6/?postID=708429#post708429 ;~ #DIESE ROUTINE WIRD ÜBER PARAMETER AUFGERUFEN Opt("MustDeclareVars", 1) Local $sSearch_1 = $CmdLine[1] Local $sSearch_2 = $CmdLine[2] global $aTags [1] global $col ;~ File mit den Suchkriterien global $file_s = "f_search.txt" _read_file($file_s,1) ;~ File mit den Replace-Strings global $file_r = $sSearch_2 & ".txt" _read_file($file_r,2) Global $sExtension = ".docx" ; Verarbeite nur MS-Word Dokument ohne Macros. Global $sTemplate = _FileListToArrayRec(@ScriptDir, $sSearch_1 & $sExtension, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) ; Auflistung der rekursiv zu verarbeitenden MS-Word Dateien Global $iTotalProjectCount = 0, $iTotalComponentCount = 0, $iTotalReplacementCount = 0 For $i = 1 To $sTemplate[0] ; rekursives Ermitteln der zu verarbeitenden Dateien _Main($sTemplate[$i]) Next ;Funktion zum Einlesen der Textefiles in Arrays Func _read_file($file_x,$col ) FileOpen($file_x, 0) ReDim $aTags[_FileCountLines($file_x) + 1] [$col] For $i = 1 To _FileCountLines($file_x) $aTags [$i-1][$col-1] = FileReadLine($file_x, $i) Next return $aTags FileClose($file_x) EndFunc Func _Main($sTemplate) Local $oWord = _Word_Create() If @error Then Return SetError(1, 0, MsgBox(16, '_Word_Open', '@error: ' & @error) * 0) If Not IsObj($oWord) Then Return SetError(1, 1, MsgBox(16, '_Word_DocOpen', '$oWord is not an Obj') * 0) Local $oWordDoc = _Word_DocOpen($oWord, $sTemplate) If @error Then Return SetError(2, 0, MsgBox(16, '_Word_DocOpen', '@error: ' & @error) * 0) If Not IsObj($oWordDoc) Then Return SetError(2, 0, MsgBox(16, '_Word_DocOpen', '$oWordDoc is not an Obj') * 0) For $j = 0 To UBound($aTags, 1) - 1 _Word_DocFindReplace($oWordDoc, $aTags[$j][0], $aTags[$j][1], Default, -1) Next consolewrite(@ScriptDir&@CRLF) Local $sFileName = @ScriptDir & "\"&$sSearch_1&"-"&$sSearch_2 &".pdf" _Word_DocExport($oWordDoc, $sFileName, Default, $wdExportCurrentPage) _Word_DocClose($oWordDoc, false) ; speichern nicht vergessen If @error Then Return SetError(3, 0, MsgBox(16, '_Word_DocClose', '@error: ' & @error) * 0) _Word_Quit($oWord) If @error Then Return SetError(4, 0, MsgBox(16, '_Word_Quit', '@error: ' & @error) * 0) Return SetError(0, 0, 1) EndFunc ;==>_Main
Mit SAP hat das nur insofern zu tun, als das die beschriebene Routine über CC aufgerufen wird.
Sie funktioniert aber auch über jede anderen Programmaufruf z.B. aus der Kommandozeile. -
Mir ist aufgefallen, dass Du
- zwar FileOpen aufrufst, dann aber das Handle nicht verwendest und somit bei jedem Lesezugriff die Datei geöffnet und geschlossen wird. Abgesehen davon verlangt FileOpen auch ein FileClose.
- $aTags als 2D array definierst, aus dem Skript aber nicht ersichtlich ist, warum. Genügt nicht ein 1D Array?
- Du $col zwar definierst aber keinen Wert setzt, daher lässt sich damit dann auch ReDim $aTags nicht fehlerfrei ausführen. In der nächsten Zeile steht nur der Buchstabe "W", was auf jeden Fall einen Syntaxfehler bringt
- Keine Fehlerprüfungen in Deinem Skript hast, das macht Debugging natürlich mehr als mühsam
Ich vermute, dass das gepostete Skript nicht der komplette Code ist.
-