如何在 Word 文档的文本框内查找并替换表格中的文本,使用 Powershell?

huangapple go评论55阅读模式
英文:

How can I find and replace text within a Table inside a Text Box of Word Doc using Powershell?

问题

以下是您要翻译的代码部分:

我正在尝试使用Powershell来查找和替换Word文档.doc中文本框内的表格中的一些文本我可以让它在文本框外的表格页脚和页眉中工作但是如果表格在文本框内则无法工作我认为它失败是因为我没有正确访问文本框的内容

以下是脚本的相关代码

Function findAndReplace($Text, $Find, $ReplaceWith) {
    $matchCase = $true
    $matchWholeWord = $true
    $matchWildcards = $false
    $matchSoundsLike = $false
    $matchAllWordForms = $false
    $forward = $true
    $findWrap = [Microsoft.Office.Interop.Word.WdFindWrap]::wdFindContinue
    $format = $false
    $replace = 2

    $Text.Execute($Find, $matchCase, $matchWholeWord, $matchWildCards, `
        $matchSoundsLike, $matchAllWordForms, $forward, $findWrap, `
        $format, $ReplaceWith, $replace) > $null
}

Function findAndReplaceWholeDoc($Document, $Find, $ReplaceWith) {
    $findReplace = $Document.ActiveWindow.Selection.Find
    findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
    ForEach ($section in $Document.Sections) {
        ForEach ($header in $section.Headers) {
            $findReplace = $header.Range.Find
            findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
            $header.Shapes | ForEach-Object {
                if ($_.Type -eq [Microsoft.Office.Core.msoShapeType]::msoTextBox) {
                    $findReplace = $_.TextFrame.TextRange.Find
                    findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
                }
            }
        }
        ForEach ($footer in $section.Footers) {
            $findReplace = $footer.Range.Find
            findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
        }
    }
}
英文:

I am trying to use Powershell to find and replace some text within a Table that is inside the Text Box of a Word Document (.doc). I am able to get it working for tables, footers and headers outside of the Text box, but not if tables are inside the text box. I think it is failing because I am not correctly accessing the contents of the Text Box.

The relevant code of the script is below:

Function findAndReplace($Text, $Find, $ReplaceWith) {
    $matchCase = $true
    $matchWholeWord = $true
    $matchWildcards = $false
    $matchSoundsLike = $false
    $matchAllWordForms = $false
    $forward = $true
    $findWrap = [Microsoft.Office.Interop.Word.WdFindWrap]::wdFindContinue
    $format = $false
    $replace = 2

    $Text.Execute($Find, $matchCase, $matchWholeWord, $matchWildCards, ` 
	$matchSoundsLike, $matchAllWordForms, $forward, $findWrap, `  
	$format, $ReplaceWith, $replace) > $null
}

Function findAndReplaceWholeDoc($Document, $Find, $ReplaceWith) {
	$findReplace = $Document.ActiveWindow.Selection.Find
	findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
	ForEach ($section in $Document.Sections) {
		ForEach ($header in $section.Headers) {
			$findReplace = $header.Range.Find
			findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
			$header.Shapes | ForEach-Object {
				if ($_.Type -eq [Microsoft.Office.Core.msoShapeType]::msoTextBox) {
					$findReplace = $_.TextFrame.TextRange.Find
					findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
				}
			}
		}
		ForEach ($footer in $section.Footers) {
			$findReplace = $footer.Range.Find
			findAndReplace -Text $findReplace -Find $Find -ReplaceWith $ReplaceWith
		}
	}
}

答案1

得分: 0

Here is the translated code:

$word = New-Object -ComObject Word.Application
$word.Visible = $true
$doc = $word.Documents.Open("C:\path\to\your\document.docx")

$findText = "" # "Text_to_find"
$replaceWith = "" # "Replacement_text"

foreach ($shape in $doc.Shapes) {
    if ($shape.Type -eq [Microsoft.Office.Core.MsoShapeType]::msoTextBox) {
        $textBox = $shape.TextFrame.TextRange
        if ($textBox.Tables.Count -gt 0) {
            foreach ($table in $textBox.Tables) {
                $findRange = $table.Range
                $find = $findRange.Find
                $find.Text = $findText
                $find.Replacement.Text = $replaceWith
                $find.Wrap = 0   # wdFindStop
                $replace = 2   # wdReplaceAll
                # $find.Execute($False, $False, $False, $False, $False, $False, $True, $find.Wrap, $False, $findText, $replaceWith, $replace, $False, $False, $False)
				$find.Execute($findText, $null, $null, $null, $null, $null, $True, $find.Wrap, $null, $replaceWith, $replace, $null, $null, $null)

            }
        }
    }
}

# $word.Quit()

Let me know if you need any further assistance!

英文:

> I think it is failing because I am not correctly accessing the contents of the Text Box.

Yes. The point is this.

Sub How_can_I_find_and_replace_text_within_a_Table_inside_a_Text_Box_of_Word_Doc_using_Powershell()
    
    Dim d As Word.Document, tbox As Shape, sp As Shape, tb As Word.Table
    Dim Text As Word.Find, Find As String, ReplaceWith As String
    
    Set d = ActiveDocument
    For Each sp In d.Shapes
        If sp.Type = msoTextBox Then
            Set tbox = sp
            If tbox.TextFrame.TextRange.Tables.Count > 0 Then
                
                For Each tb In tbox.TextFrame.TextRange.Tables
                
                    Set Text = tb.Range.Find
                    Text.Execute FindText:=Find, ReplaceWith:=ReplaceWith, _
                        Wrap:=wdFindStop, Replace:=wdReplaceAll
                        'use wdFindStop : only in the table, or all the text in Textbox will be replace
                Next tb
                
            End If
        End If
    Next sp
    
End Sub

I don't understand and have not tried powershell, only VBA, VB, C#, and a little C++. I think your code is probably similar in principle, but the command symbols and keywords used are different.
So I think you need to be able to "enter" the text box before you can get the content, but it can be a table or whatever, as long as it is in the text box. You probably just don't know what object or method to use to access it. so I provide you with the worked VBA code, and then you can try to convert it to powershell, which you can use.
However, I read your code, Shape, TextFrame, TextRange these objects you have used, should be aware of, then I do not know what is the reason. You should carefully compare my code with yours to see what the key differences are.

The translation probably looks like this:(I've actually tested it with Windows PowerShell and it works! This is also my first time using Windows PowerShell. Thank you!)

  • You can directly apply. All you need is to assign the value of $findText, $replaceWith, and the argument of $word.Documents.Open() to run it. Good luck.
$word = New-Object -ComObject Word.Application
$word.Visible = $true
$doc = $word.Documents.Open("C:\path\to\your\document.docx")

$findText = "" # "Text_to_find"
$replaceWith = "" # "Replacement_text"

foreach ($shape in $doc.Shapes) {
    if ($shape.Type -eq [Microsoft.Office.Core.MsoShapeType]::msoTextBox) {
        $textBox = $shape.TextFrame.TextRange
        if ($textBox.Tables.Count -gt 0) {
            foreach ($table in $textBox.Tables) {
                $findRange = $table.Range
                $find = $findRange.Find
                $find.Text = $findText
                $find.Replacement.Text = $replaceWith
                $find.Wrap = 0   # wdFindStop
                $replace = 2   # wdReplaceAll
                # $find.Execute($False, $False, $False, $False, $False, $False, $True, $find.Wrap, $False, $findText, $replaceWith, $replace, $False, $False, $False)
				$find.Execute($findText, $null, $null, $null, $null, $null, $True, $find.Wrap, $null, $replaceWith, $replace, $null, $null, $null)

            }
        }
    }
}

# $word.Quit()

huangapple
  • 本文由 发表于 2023年5月20日 22:46:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76295800.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定