在 VBA(Word) 上,通过 运行 宏编辑另一个文档或忽略数组中的空行?

On VBA(Word), edit a document by running a macro on another document OR ignore the empty lines in an array?

我正在尝试改进从制表符分隔的 docx 文件中提取数据的宏。在文档 I 运行 宏中,它找到左侧的单词(来自制表符分隔的文件),并用右侧的单词替换它们。我是编程的初学者,但设法组合了满足我需要的东西,我花了很多时间尝试调试和改进它。

然而,还有一件小事听起来不太难,但我完全无法理解。如果在引用列表的末尾有一个空行,我的宏会给出“运行-time Error 9, subscript out of 运行ge”。当然这可以通过删除那个空行来解决,但我想让宏更好地工作并以某种方式忽略它。

我实际上有 2 个不同的修复方法,但不知道如何实施它们。即使您不查看整个问题而只是帮助我学习如何实施以下修复,它也会对我有所帮助。

  1. 当我 运行 我的宏在我的主文档上时,尝试删除空的 参考列表中的行。但我不知道如何编辑 带有宏的文档在另一个文档上 运行。
  2. 以某种方式修改循环,而不是“UBound - 1 到 0”和“0 到 Unbound - 1",他们检测带有字符的行或者他们忽略 空行。

有人能帮助我实施修复或提供其他修复吗?

Macro:
Sub BulkFindReplace()
Application.ScreenUpdating = False
Dim FRDoc As Document, FRList, j As Long

 'Load the strings from the reference doc into a text string to be used as an array.
Set FRDoc = Documents.Open("C:\Users\USERNAME\Desktop\refList.docx", ReadOnly:=True, Addtorecentfiles:=False, Visible:=False)
FRList = FRDoc.Range.FormattedText
FRDoc.Close False
Set FRDoc = Nothing
    
    If Split(Split(FRList, vbCr)(0), vbTab)(0) > Split(Split(FRList, vbCr)(0), vbTab)(1) Then
        With ActiveDocument.Range.Find
          .ClearFormatting
          .Replacement.ClearFormatting
          .MatchWholeWord = True
          .MatchCase = True
           'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
           'Find text <Tab> Replace text
          For j = 0 To UBound(Split(FRList, vbCr)) - 1
            .Text = Split(Split(FRList, vbCr)(j), vbTab)(0)
            .Replacement.Text = Split(Split(FRList, vbCr)(j), vbTab)(1)
            .Execute Replace:=wdReplaceAll
          Next
        End With
    Else
        With ActiveDocument.Range.Find
          .ClearFormatting
          .Replacement.ClearFormatting
          .MatchWholeWord = True
          .MatchCase = True
           'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
           'Find text <Tab> Replace text
          For j = UBound(Split(FRList, vbCr)) - 1 To 0 Step -1
            .Text = Split(Split(FRList, vbCr)(j), vbTab)(0)
            .Replacement.Text = Split(Split(FRList, vbCr)(j), vbTab)(1)
            .Execute Replace:=wdReplaceAll
          Next
        End With
    End If
Application.ScreenUpdating = True
End Sub

编辑:试图在下面说得更清楚

示例:

待处理的Word文件:

1
2
3
4
5

列表宏引用(宏将左边的数字替换为右边的数字)

1    2
2    3
3    4
4    5
5    6

问题: 如果像这样list在最后有一个空行(复制东西时经常发生,我想万无一失),宏会报错:

1    2
2    3
3    4
4    5
5    6
‏‏‎ ‎‏‏‎ ‎‎

我考虑过的可能修复方法:

  1. 编辑宏中的列表以去除任何空行。我知道如何删除空行,但我不知道如何对另一个文档(列表)执行此操作,而我 运行 从主文档中调用宏。

如果像您假设的那样,空行是由于 reflist.docx 末尾的空段落造成的,您的第一道防线是确保您永远不会在该文件的结尾。

您的第二道防线是确保检查您正在构建的范围 FRList 末尾没有空段落,这很容易做到。

鉴于您已将 FRList 声明为变体(您省略了数据类型,因此它会自动分配默认的变体)您还可以通过分配数组使代码更清晰、更易于阅读由 Split 输出到 FRList,正如我在下面所做的那样。

Sub BulkFindReplace()
    Application.ScreenUpdating = False
    Dim FRDoc As Document, FRRng As Range, FRList As Variant, j As Long

    'Load the strings from the reference doc into a text string to be used as an array.
    Set FRDoc = Documents.Open("C:\Users\USERNAME\Desktop\refList.docx", ReadOnly:=True, Addtorecentfiles:=False, Visible:=False)
    FRRng = FRDoc.Range.FormattedText
    If Len(FRRng.Paragraphs.Last.Range.Text) = 1 Then FRRng.MoveEnd wdCharacter, -1
    FRList = Split(FRRng, vbCr)
    FRDoc.Close False
    Set FRDoc = Nothing
    If Split(FRList, vbTab)(0) > Split(FRList, vbTab)(1) Then
        With ActiveDocument.Range.Find
            .ClearFormatting
            .Replacement.ClearFormatting
            .MatchWholeWord = True
            .MatchCase = True
            'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
            'Find text <Tab> Replace text
            For j = 0 To UBound(FRList) - 1
                .Text = Split(FRList(j), vbTab)(0)
                .Replacement.Text = Split(FRList(j), vbTab)(1)
                .Execute Replace:=wdReplaceAll
            Next
        End With
    Else
        With ActiveDocument.Range.Find
            .ClearFormatting
            .Replacement.ClearFormatting
            .MatchWholeWord = True
            .MatchCase = True
            'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
            'Find text <Tab> Replace text
            For j = UBound(FRList) - 1 To 0 Step -1
                .Text = Split(FRList(j), vbTab)(0)
                .Replacement.Text = Split(FRList(j), vbTab)(1)
                .Execute Replace:=wdReplaceAll
            Next
        End With
    End If
    Application.ScreenUpdating = True
End Sub