How do I replace all occurrences of string in Word

2019-04-09 18:30发布

I've managed to find& edit per one word file. With this code:

$objWord = New-Object -comobject Word.Application  
$objWord.Visible = $false

$objDoc = $objWord.Documents.Open("C:\users\stefan\test\New Microsoft Word Document.docx") 
$objSelection = $objWord.Selection 

$FindText = "that" 
$MatchCase = $False 
$MatchWholeWord = $true
$MatchWildcards = $False 
$MatchSoundsLike = $False 
$MatchAllWordForms = $False 
$Forward = $True 
$Wrap = $wdFindContinue 
$Format = $False 
$wdReplaceNone = 0 
$ReplaceWith = "this" 
$wdFindContinue = 1 

$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ` 
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,` 
$Wrap,$Format,$ReplaceWith) 
$objDoc.Save()
$objWord.Quit()

But I want to do it for whole folder. I've tried to insert something like this:

$objWord = New-Object -comobject Word.Application  
$objWord.Visible = $false

 $list = Get-ChildItem "c:\users\stefan\test\*.*" -Include *.doc*
 foreach($item in $list){
 $objDoc = $objWord.Documents.Open($list.FullName,$true)

 $objSelection = $objWord.Selection 

$FindText = "Sara" 
$MatchCase = $False 
$MatchWholeWord = $true
$MatchWildcards = $False 
$MatchSoundsLike = $False 
$MatchAllWordForms = $False 
$Forward = $True 
$Wrap = $wdFindContinue 
$Format = $False 
$wdReplaceNone = 0 
$ReplaceWith = "AJMOO" 
$wdFindContinue = 1 

$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ` 
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,` 
$Wrap,$Format,$ReplaceWith) 
$objDoc.Save()
$objWord.Quit()
}

Also, it changes only one item that is found, but I want all items in the file. Thanks.

2条回答
淡お忘
2楼-- · 2019-04-09 19:15

Thankfully to @Matt I've solved my code.

Here is a correct version which works:

$objWord = New-Object -comobject Word.Application  
$objWord.Visible = $false

$list = Get-ChildItem "c:\users\stefan\test\*.*" -Include *.doc*
foreach($item in $list){
$objDoc = $objWord.Documents.Open($item.FullName,$true)

$objSelection = $objWord.Selection 
$wdFindContinue = 1
$FindText = "Sara" 
$MatchCase = $False 
$MatchWholeWord = $true
$MatchWildcards = $False 
$MatchSoundsLike = $False 
$MatchAllWordForms = $False 
$Forward = $True 
$Wrap = $wdFindContinue 
$Format = $False 
$wdReplaceNone = 0 
$ReplaceWith = "AJMOO" 
$wdFindContinue = 1 
$ReplaceAll = 2

$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ` 
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,` 
$Wrap,$Format,$ReplaceWith,$ReplaceAll) 
$objDoc.Save()
$objDoc.Close()
}
$objWord.Quit()
查看更多
Bombasti
3楼-- · 2019-04-09 19:26

Multiple Replacements

Also, it changes only one item that is found, but I want all items in the file

This is because you have not set the scope of the replacement to be all items. The is from the next argument you did not specify in your Execute method call. Set a variable called $wdReplaceAll and set it to 2. Then you adjust your call to add that variable.

$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ` 
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,` 
$Wrap,$Format,$ReplaceWith,$wdReplaceAll) 

That fixes that issue when run against one file.

Multiple Files

But I want to do it for whole folder

The partial issue with that is your are not properly querying the folder for files. -Include is finicky and work when partnered with -Recurse however you are treating it like a -Filter anyway so adjust as such.

$list = Get-ChildItem "c:\users\stefan\test\" -filter "*.doc*"

Next, when you are looping you are not using the current iteration but the whole collection when calling .open()

$objDoc = $objWord.Documents.Open($list.FullName,$true)

Should instead be

$objDoc = $objWord.Documents.Open($item.FullName,$true)

as per your loop definition.

Now you need to be sure you close each document before you quit the application. Right now you are quitting word inside the loop.

foreach($item in $list){
    #.... Stuff and things happens here.
    $objDoc.Save()
    $objDoc.Close()
}

$objWord.Quit()

Variable declaration and calls

Right now you set $wrap to the value of the variable $wdFindContinue. When that is first called $wdFindContinue is null as it is not set to a few lines later in the code.

$Wrap = $wdFindContinue 
#...
$wdFindContinue = 1 

Switch the order of these lines or just set $wrap directly to 1. I am unsure of the implications of this being incorrect.

查看更多
登录 后发表回答