用超链接替换Word文件中所有出现的字符串

时间:2018-11-16 19:23:24

标签: vba powershell ms-word

我必须创建一个Powershell脚本,该脚本读取Word文件(.docx),并用超链接替换字符串。到目前为止,基于this script,我可以轻松地用另一个字符串替换所有出现的字符串。使用that script,我可以查找一个字符串并将其替换为超链接。但是,只有第一个匹配项被替换。

到目前为止,这是我对问题的理解:

第一个脚本使用ReplaceWith接口的Replace=wdReplaceAll函数的ExecuteFind参数。问题是ReplaceWith需要一个String而不是一个超链接对象。

第二个脚本未指定这些参数,因此仅使用Find.Execute()函数将Range对象的开头移至找到的字符串,然后在该位置插入链接。

由于我无法一次替换所有匹配项,因此我将尝试遍历所有匹配项以在其位置插入链接。但是Find.Execute()只返回一个布尔值...现在,我正在考虑重新定义范围以排除发现的事件并循环到文档末尾,但这感觉很复杂。

假设我有一个包含此文本的Word文件:

  

换句话说,这里链接的每篇文章都是对   一个主题上有多个列表。一些链接的文章本身   列表列表列表。本文也是列表列表。

这是一个简单的脚本,仅用相对链接替换“列表”的首次出现。我试图将所有出现的“列表”替换为超链接$ linkPath,但找不到方法。帮助吗?

Add-Type -AssemblyName "Microsoft.Office.Interop.Word"
$wdunits = "Microsoft.Office.Interop.Word.wdunits" -as [type]
$objWord = New-Object -ComObject Word.Application  
$objWord.Visible = $false

# Text to find and replace by a link
$findText = "lists"
# Link to file
$linkPath = ".\Untitled.png"
# Source Word (2007+) file
$objDoc = $objWord.Documents.Open([FILE TO READ FROM])
# Resulting file
$saveAs = [FILE TO SAVE TO]
# Set Range to all document content
$range = $objDoc.Content
$range.movestart($wdunits::wdword,$range.start) | Out-Null

# Execute params
$matchCase = $false
$matchWholeWord = $true
$matchWildcards = $false
$matchSoundsLike = $false
$matchAllWordForms = $false
$forward = $true 
$wrap = 1
$format = $False
$wdReplaceNone = 0 
$wdFindContinue = 1
$wdReplaceAll = 2

# $wordFound is true is $findText is found in $range. 
# $range.find.execute modifies the start of the range 
$wordFound = $range.find.execute($findText,$matchCase,`
             $matchWholeWord,$matchWildCards,$matchSoundsLike,`
             $matchAllWordForms,$forward,$wrap)

if($wordFound){
        $objDoc.Hyperlinks.Add($range,$linkPath,$null,$null,$findText) | Out-Null
}
$objDoc.SaveAs($saveAs)
$objDoc.Close()
$objWord.Quit()
$rc = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objWord)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()

参考

1 个答案:

答案 0 :(得分:0)

与任何数据集一样,您必须循环播放才能击中数据集中的所有项目以对数据集中的特定内容采取措施。您没有在代码中执行此操作。在MSWord中,您需要遍历文档。例如,我正在显示要删除的代码,但这也可能是您的替换工作。

示例:仅删除任何超链接的VBA

Sub RemoveHyperlinksInDoc()
    ' You need to delete collection members starting from the end going backwards
    With ActiveDocument
        For i = .Hyperlinks.Count To 1 Step -1
            .Hyperlinks(i).Delete
        Next
    End With
End Sub

用于删除所有超链接的PowerShell示例

Param
(
    [string]$Document = $Word.Documents.Open((Read-Host -Prompt 'Enter the full path to the Word document'))
)

$Word = New-Object -ComObject Word.application
$Hyperlinks = @($Document.Hyperlinks)  
$hyperlinks | ForEach { $_.Delete() }
$document.save()
$document.Close()
$word.quit()

示例:仅用于删除图像超链接的PowerShell

Param
(
    [string]$Document = $Word.Documents.Open((Read-Host -Prompt 'Enter the full path to the Word document'))
)

$Word = New-Object -ComObject Word.application
$Hyperlinks = @($Document.Hyperlinks) 
$Hyperlinks | ForEach {
                         If ($_.Shape) {$_.Delete()}
                         Else {$_.Name;Write-Warning -Message 'Hyperlink is not a graphic and will not be removed'}
                      }
$Document.save()
$Document.Close()
$Word.quit()