Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
WinDev Forum
Beiträge im Thema:
8
Erster Beitrag:
vor 10 Jahren
Letzter Beitrag:
vor 10 Jahren
Beteiligte Autoren:
Al, Piet van Zanten, Bosher

[WD12] MS Word automation

Startbeitrag von Al am 13.08.2008 08:25

Hello All

I have to do a find and replace in a word document and can't seem to get started with the automation process. Can anyone help with a code example please.

As an alternative, a friend of mine has written a small vb script for me which does the job but I am having trouble running it from within Windev because I have to pass three parameters to it as strings and I am stuck there also.

The parameters I need to pass to exerun() as strings are
The filepath and name
The word to be replaced
The new word

Something like:
exerun("vbscript.vbs "DocumentPathAndName" "WordToReplace" "ReplacementWord")



Regards
Al

This is the VB script

'Pramas: (1) Filename with full path (2) Find Text (3) Replace Text.
'
'Example of use C:\Project.Al\ReplaceStr "C:\Project.Al\Form 01 Daily Log.doc" "XXX" "ABC"
'
'Notes: In the above example any errors will be logged to "C:\Project.Al\ReplaceStr.log", if this dir does not exist they will be logged to
' c:\ReplaceStr.log
'


'Check there are 3 Parma's
'
If Wscript.Arguments.Count 3 Then
pWriteLogFile "[ERROR]: 3 params are required. (1) Filename with full path (2) Find what (3) Replace with"
Wscript.Echo "[ERROR]: 3 params are required. (1) Filename with full path (2) Find what (3) Replace with"
Wscript.Quit
End If


'Store Pramas
'
strFilePath = Wscript.Arguments(0) 'Filename with path
strFind = Wscript.Arguments(1) 'Find this
strReplaceWith = Wscript.Arguments(2) 'Replace with This.
'strProcessDir = Wscript.Arguments(3) 'Verions 2: Process all files in dir. If 1 replace all files in dir else just replace single file.



'Write Log File extry.
'
'pWriteLogFile "Start"


'Check Imput File exists.
'
Set objFSO = CreateObject("Scripting.FileSystemObject")
sLogFilePathName = objFSO.GetParentFolderName(strFilePath) 'Set LogFile path as current input path

'Check LogFile Path Exists if Not set to c:\
If objFSO.FolderExists(sLogFilePathName) = False Then
sLogFilePathName = "c:\"
End If

If right(sLogFilePathName,1) "\" Then
sLogFilePathName = sLogFilePathName & "\"
End If
sLogFilePathName = sLogFilePathName & "ReplaceStr.log" 'Path to Log file

'Wscript.Echo sLogFilePathName

If objFSO.FileExists(strFilePath) Then

'Call pReplaceText Proc.
'
pReplaceText strFind, strReplaceWith
Else
pWriteLogFile "[ERROR]: Input file does not exist - " & strFilePath
Wscript.Echo "[ERROR]: Input file does not exist - " & strFilePath
End If

'Close File objects
'
Set objFSO = Nothing



'Proc: pReplaceText
'
Sub pReplaceText(strFind, strReplaceWith)
Const wdFindContinue = 1
Const wdReplaceAll = 2
intStrFound =0

'Create Word Object
'
On Error Resume Next
' Create new instance of Word
Set objWord = CreateObject("Word.Application")

If Err = 429 Then 'ERR_APP_NOTFOUND
pWriteLogFile "[ERROR]:Word is not installed on this computer."
WScript.Echo "[ERROR]:Word is not installed on this computer. "
WScript.Quit
End If
objWord.Visible = True


'Open Word Doc.
'
Set objDoc = objWord.Documents.Open(strFilePath)
Set objSelection = objWord.Selection


'Replace Body
'
With objSelection.Find 'or With objRange.Find
.Text = strFind
.Replacement.Text = strReplaceWith
'.Forward = False
.Wrap = 1
.Format = False
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.Execute ,,,,,,,,,,wdReplaceAll

If objSelection.Find.Found Then
intStrFound =1
End If
End With


'Replace Header Text
'
With objDoc.Sections(1).Headers(1).Range.Find
.Replacement.ClearFormatting
.ClearFormatting
.Text = strFind
.MatchWholeWord = True
.Wrap = wdFindContinue
.Format = False
.Replacement.Text = strReplaceWith
.Execute ,,,,,,,,,,wdReplaceAll

If objSelection.Find.Found Then
intStrFound =1
End If
End With


'Replace Footer Text
'
With objDoc.Sections(1).Footers(1).Range.Find
.Replacement.ClearFormatting
.ClearFormatting
.Text = strFind
.MatchWholeWord = True
.Wrap = wdFindContinue
.Format = False
.Replacement.Text = strReplaceWith
.Execute ,,,,,,,,,,wdReplaceAll

If objSelection.Find.Found Then
intStrFound =1
End If
End With


'Save Status
'
If intStrFound = 0 Then
pWriteLogFile "[NOT FOUND]:" & strFind & " not found in " & strFilePath
'Wscript.Echo "[NOT FOUND]:" & strFind & " not found in " & strFilePath
End If


'Save Changes and Quit Word
'
objWord.Application.Quit -1 'wdSaveChanges
Set objWord = Nothing

End Sub



'Write string to file
'
Sub pWriteLogFile(sFileContents)
Const ForWriting = 8 '2 Overwrite

If sLogFilePathName = "" Then
sLogFilePathName = "c:\ReplaceStr.log"
End If

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFSFile = oFS.OpenTextFile(sLogFilePathName,ForWriting,True)

oFSFile.WriteLine(date & " " & time & ": " & sFileContents)
oFSFile.Close

Set oFSFile = Nothing
Set oFS = Nothing
End Sub

Antworten:

Hi Al,

Try something like this...

oWord is an object Automation "Word.Application.11"
oDoc is object Automation dynamic


You can use all the COM methods for word like

oRange = oDoc>>Range

OF course you will need to open or create a doc using COM methods first!!

You might also find DSOFramer ocx useful (Try a google search)

Tip: I don't use the merge methods. I put text placeholders I.e. [[Name]] and use COM replace text methods. Works better..

Cheers

Bob

von Bosher - am 13.08.2008 17:53
Hello Bob

Thanks for the ideas. I will give them a go.


Regards
Al

von Al - am 14.08.2008 14:11
Hi Al,

I have some code samples if it turn out that you need them.

Cheers

Bob



von Bosher - am 14.08.2008 14:25
Hi Al,

This is an example of search and replace:


WHEN EXCEPTION
Error("An error has occuurred ","",...
"Erro number: "+ExceptionInfo(errCode),...
"Message:"+ExceptionInfo(errSummary),...
"Info:"+ExceptionInfo(errInfo),...
"During:"+ExceptionInfo(errDuring),...
"Procedure:"+ExceptionInfo(errProcess),...
"Object:"+ExceptionInfo(errElement),...
"Line:"+ExceptionInfo(errLine))

MyWord>>Documents>>Close(OLEFalse)
MyWord>>Quit()
delete MyWord
RESULT False
END

bVisible is boolean =False

//-------BEGIN Loading and initializing Word
MyWord=GetActiveObject("Word.Application")
IF MyWord=Null THEN
// there was no Word already opened , we allocate one
MyWord = new object OLE "Word.Application"//"Word.Basic"
ELSE
IF YesNo("All active documents in Word must be closed first.","Do you want to close them?") THEN
MyWord>>ActiveDocument>>Close(OLEFalse)
ELSE
RESULT False
END
END

MyWord>>Visible=bVisible
MyWord>>Application>>Visible=bVisible
MyWord>>Documents>>Open(DocumentName,OLEFalse,OLEFalse)
MyWord>>Selection>>WholeStory()
MyWord>>Selection>>Find>>Execute(sSearchString,OLEFalse,OLETrue,OLEFalse,OLEFalse,OLEFalse,OLETrue,1,OLEFalse,sSubstString,2)
MyWord>>Visible = OLETrue
MyWord>>Quit()
delete MyWord



sSearchString and sSubstString are the string to search and replace. It's advisable to render Word invisible, so the user cannot interfere with any keystrokes.
To learn how to do something in Word (or Excel) I always record a Macro, (menu extra) then look at the Macro (extra, macros, edit) and "translate" it using the Windev syntax.

Documents.Open FileName:="""Mydoc.doc"""

Becomes in Windev:

MyWord>>Documents>>Open("Mydoc.doc")

HTH, Best regards,
Piet


von Piet van Zanten - am 14.08.2008 15:49
Hello Piet

Thank you very much, your code works and gives me encouragement that automation can be mastered.

I have one remaining favour to ask. I also need to find and replace in the headers and footers and from the macro I understand that I need to activate them but the conversion of the macro defeats me. I have tried all sorts of permutations without success and the error messages from WIndev are no help at all.
I am unclear how to reference the "wdPanelNone" and other "wd..." named automation items.


Macro
If ActiveWindow.View.SplitSpecial wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "ReplacementText "
.Replacement.Text = "SearchText"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll


The crazy thing to me is that the macro parameters are different from those you recommend and which work. The Macro indicates that the find and replace strings are the first two parameters but your code has them as the first and the last parameters, yet it works fine.

Anyway, can you help with a translation of the header macro into Windev code.
The footer will be the same with a name change to "CurrentPageFooter"
I presume the macro code activates the header pane and then does a find and replace.

Regards
Al


von Al - am 15.08.2008 12:21
Hi Al,

I'm not in the office right now, but I can give you some hints already.
The code I gave you is a code that I used in WD5, I'm still using it in WD12. That's probably why the current version of Word would produce other macro's for the same task.
wdPanelNone is a constant. So are the other wdXXX's. You can to find out their value's if you open the Visual Basic editor in Word and create a userform with a textbox and a button. In the button click code type TextBox1=wdPanelNone
If you run the userform and click the button the textbox will display the numerical value of the constant. (btw: wdPanelNone is zero, so the textbox remains blank)
I should have a small list of the ones I use already. Perhaps there's a list on the web somewhere too.

I'll get back to you on this. Meantime keep me posted if you made any progress.

Best regards,
Piet

von Piet van Zanten - am 15.08.2008 13:54
Hello Piet

Thanks, that was the missing piece of the puzzle.

It now works ok on the header, body and footer

I found the constant values on the web as you suggested

The code I am now using is as follows


//define these constants in the project init
CONSTANT
wdPaneNone = 0
wdOutlineView = 2
wdNormalView = 1
wdPrintView = 3
wdSeekCurrentPageHeader = 9
wdSeekCurrentPageFooter = 10
END

LFindString is string = ""
LReplaceString is string = ""
MyWord is object OLE dynamic
IF MyWord Null THEN
MyWord>>Visible = OLETrue
MyWord>>Quit()
END
bVisible is boolean =False
MyWord=GetActiveObject("Word.Application")
MyWord>>Visible=bVisible
MyWord>>Application>>Visible=bVisible

//find and replace in the body of the document
MyWord>>Documents>>Open(LJobDirDoc,OLEFalse,OLEFalse)
MyWord>>Selection>>WholeStory()
MyWord>>Selection>>Find>>ClearFormatting
MyWord>>Selection>>Find>>Replacement>>ClearFormatting
MyWord>>Selection>>Find>>Execute(LFindString,OLEFalse,OLETrue,OLEFalse,OLEFalse,OLEFalse,OLETrue,1,OLEFalse,LReplaceString,2)

//find and replace in the header of the document
MyWord>>ActiveWindow>>ActivePane>>View>>SeekView = wdSeekCurrentPageHeader
MyWord>>Selection>>Find>>ClearFormatting
MyWord>>Selection>>Find>>Replacement>>ClearFormatting
MyWord>>Selection>>Find>>Execute(LFindString,OLEFalse,OLETrue,OLEFalse,OLEFalse,OLEFalse,OLETrue,1,OLEFalse,LReplaceString,2)

//find and replace in the footer of the document
MyWord>>ActiveWindow>>ActivePane>>View>>SeekView = wdSeekCurrentPageFooter
MyWord>>Selection>>Find>>ClearFormatting
MyWord>>Selection>>Find>>Replacement>>ClearFormatting
MyWord>>Selection>>Find>>Execute(LFindString,OLEFalse,OLETrue,OLEFalse,OLEFalse,OLEFalse,OLETrue,1,OLEFalse,LReplaceString,2)

MyWord>>Quit(-1)
delete MyWord



At this point I was just concerned with getting it working so I have left out all the tests that were in the macro code. I will play with them later. I still don't have a real understanding of what I am doing with this, I have just followed your lead, but I have something to build on now.

It seems quite straightforward once you know the basics and I am astounded that PCSoft do not include examples of how to translate a office macros into Windev

Thanks again for your generous help.

Regards
Al












von Al - am 15.08.2008 15:51
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.