2016-01-06 44 views
0

我創建了一個VBA宏,它在Word文檔中的<>標記之間查找單詞,並將它們轉換爲合併字段。用合併字段替換給定範圍的文本

這是我想出了

Sub lookForFields() 
    ' 
    ' lookForFields Macro 
    ' 
    Dim para As Paragraph 
    Dim lineText As String 
    Dim regEx As New RegExp 
    Dim strPattern As String: strPattern = "\<(.*?)\>" 
    Dim strInput As String 
    Dim region As Word.Range 
    Dim allmatches As MatchCollection 
    Dim currentWord As String 

    Debug.Print (vbCrLf + "------------------") 
    Dim res As String 
    With regEx 
     .Global = True 
     .MultiLine = False 
     .IgnoreCase = True 
     .Pattern = strPattern 
    End With 
    For Each para In ActiveDocument.Paragraphs 
     txt = para.Range.Text 
     Set allmatches = regEx.Execute(txt) 
     For Each m In allmatches 
      Set rng = ActiveDocument.Range(Start:=m.FirstIndex + para.Range.Start, End:=m.FirstIndex + Len(m.Value) + para.Range.Start) 
      'Set myField = ActiveDocument.Fields.Add(Range:=rng, Type:=wdFieldMergeField, Text:=m.Value) 
      rng.HighlightColorIndex = wdYellow 
     Next m 
    Next para 
End Sub 

第一腳本以下指示正確地強調,我想已經轉換的話:

rng.HighlightColorIndex = wdYellow 

但是,如果我去掉

Set myField = ActiveDocument.Fields.Add(Range:=rng, Type:=wdFieldMergeField, Text:=m.Value) 

合併字段如果段落中有多個,則不會創建。 創建的合併字段也似乎不是「有效的」,因爲右鍵單擊它們來編輯它們的屬性會用「未知開關」錯誤代替它們。 我應該如何去做這件事?

+0

爲什麼你會不使用Word的內置查找能力,使用通配符,這將讓你直接插入合併域到目標範圍內。依靠開始和結束值是非常不可靠的,因爲您已經發現... –

回答

1

如果您使用Alt-F9查看文檔中實際發生的情況,您可能會看到每個段落中的第二個和後續字段被插入到代碼插入的第一個字段中。

這是因爲字段插入會更改文檔範圍內的字符數。沒有任何內容會自動調整MatchCollection的Match對象中記錄的範圍開始和結束值。

處理這類事情的通常方法是向後遍歷文檔,即向後遍歷段落,然後向後遍歷匹配項目。

另一件與此相關的事情是m變量未被聲明。我認爲它可能需要聲明爲正則表達式匹配對象。

所以,你需要的代碼更是這樣的:

Sub lookForFields() 
    ' 
    ' lookForFields Macro 
    ' 
    Dim m As VBScript_RegExp_55.Match 
    Dim theMatch As Long 
    Dim thePara As Long 
    Dim para As Paragraph 
    Dim lineText As String 
    Dim regEx As New RegExp 
    Dim strPattern As String: strPattern = "\<(.*?)\>" 
    Dim strInput As String 
    Dim region As Word.Range 
    Dim allmatches As MatchCollection 
    Dim currentWord As String 

    Debug.Print (vbCrLf + "------------------") 
    Dim res As String 
    With regEx 
     .Global = True 
     .MultiLine = False 
     .IgnoreCase = True 
     .Pattern = strPattern 
    End With 
    For thePara = ActiveDocument.Paragraphs.Count To 1 Step -1 
     Set para = ActiveDocument.Paragraphs(thePara) 
     txt = para.Range.Text 
     Set allmatches = regEx.Execute(txt) 
     For theMatch = allmatches.Count - 1 To 0 Step -1 
      Set m = allmatches(theMatch) 
      Set rng = ActiveDocument.Range(Start:=m.FirstIndex + para.Range.Start, End:=m.FirstIndex + Len(m.Value) + para.Range.Start) 
      Set myField = ActiveDocument.Fields.Add(Range:=rng, Type:=wdFieldMergeField, Text:=m.Value) 
      rng.HighlightColorIndex = wdYellow 
     Next 
    Next 
    Set m = Nothing 
    Set para = Nothing 
End Sub 
+0

您的解決方案完美無缺。非常感謝@ bibadia。 – Polyphil