首页 > 解决方案 > Word中的VBA循环查找通配符字符串第一次出现

问题描述

我有一些用于 Microsoft Word 的 VBA,它应该在多个文件中使用通配符找到一些五位数字,然后将它们和路径/文件粘贴到一个 excel 文件中。不幸的是,它总是错过第一次出现的通配符字符串。我无法确定为什么!

我已经尝试重新排序以确保不会错过它,但是,我无法让它正常工作。当我自己手动运行通配符搜索时,它会找到第一个出现的位置。但是,它不会在 VBA 中执行此操作。

Public Sub TestFindNumbers()

    Dim i As Long
    i = 2 ' Row in Excel to start

    Dim ObjExcel As Object, ObjWorkBook As Object, ObjWorksheet As Object

    Set ObjExcel = CreateObject("EXCEL.APPLICATION")

    Set ObjWorkBook = ObjExcel.Workbooks.Add
    Set ObjWorksheet = ObjWorkBook.Worksheets("Sheet1")


    Set dlgFile = Application.FileDialog(msoFileDialogFilePicker)

    With dlgFile
        dlgFile.AllowMultiSelect = True
        If .Show = -1 Then
            For nDocx = 1 To dlgFile.SelectedItems.Count


                Documents.Open dlgFile.SelectedItems(nDocx)
                Set objDocx = ActiveDocument

                With objDocx.Range
                    With .Find
                        .ClearFormatting
                        .Replacement.ClearFormatting
                        .Text = "[0-9]{5}"
                        .Replacement.Text = ""
                        .Forward = True
                        .Wrap = wdFindStop
                        .Format = False
                        .MatchWildcards = True
                        .Execute
                    End With

                    Do While .Find.Found
                        .Collapse wdCollapseEnd

                        .Find.Execute

                        If .Text <> "" Then
                            ObjWorksheet.Cells(i, 1) = Left(.Text, 8)
                            ObjWorksheet.Cells(i, 2) = dlgFile.SelectedItems(nDocx)
                        Else
                            i = i - 1
                        End If
                            i = i + 1



                    Loop
                End With


                objDocx.Close SaveChanges:=wdDoNotSaveChanges
            Next nDocx
        Else
            MsgBox ("You need to select documents first!")
            Exit Sub
        End If
    End With

    ObjWorksheet.Cells(1, 1) = "Number"
    ObjWorksheet.Cells(1, 2) = "Path & Filename"



    ObjExcel.Visible = 1



    Set objDocx = Nothing
    Set ObjExcel = Nothing
    Set ObjWorkBook = Nothing
    Set ObjWorksheet = Nothing

End Sub

我创建了一个包含以下内容的测试文件:

1234 Shouldn’t be selected
12345 Select this one. First occurrence.
98765 Another good one
568 Nope
This one is 55555 in the middle
End

当我运行我的 VBA 代码时,我得到 98765 和 55555 作为命中。不幸的是,没有找到 12345。

标签: vbaloopsms-wordfind

解决方案


问题中的代码未按预期找到搜索词的原因:

, CollapsethenFind.Execute方法在第一个结果被拾取之前就在循环中。由于.Execute也在With循环之前的块中Find,因此运行两次,从而掩盖了搜索词的第一次出现。

此外:

1) 最好使用一个特定Range的来进行搜索,而不是整个文档 ( objDocx.Range)。这是由于“折叠” - 当有特定Range对象时它更可靠地工作。

2)不要按照评论中的建议使用Find.Wrap = wdFindContinue。(如问题中的代码)在循环中wdFindStop使用时是正确的。通常会导致“无限循环”,因为 Word 将再次从文档的开头开始,一次又一次......FindwdFindContinue

3)可以(更好)在打开(或创建)文件时设置对象,而不是在第二步中Document依赖:ActiveDocument

 Set objDocx =  Documents.Open dlgFile.SelectedItems(nDocx)

这是与查找有关的代码部分 - 我省略了 Excel 部分以使其更易于阅读

Dim objDocx As Word.Document
Dim rngFind As Word.Range

Set objDocx = Documents.Open dlgFile.SelectedItems(nDocx)
Set rngFind = objDocx.content

With rngFind
    With .Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = "[0-9]{5}"
        .Replacement.Text = ""
        .Forward = True
        .wrap = wdFindStop
        .Format = False
        .MatchWildcards = True
        .Execute
    End With

    Do While .Find.Found
         If .Text <> "" Then
             ObjWorksheet.Cells(i, 1) = Left(.Text, 8)
             ObjWorksheet.Cells(i, 2) = dlgFile.SelectedItems(nDocx)
         Else
             i = i - 1
         End If
         i = i + 1

        .Collapse wdCollapseEnd
        .Find.Execute
    Loop
End With

推荐阅读