Цикл VBA в Word для поиска подстановочных строк пропускает первое вхождение - PullRequest
1 голос
/ 01 апреля 2019

У меня есть какой-то VBA для Microsoft Word, который должен находить около пятизначных чисел, используя подстановочные знаки в нескольких файлах, а затем вставляет их и путь / файл в файл 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 не найдено.

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Причина, по которой код в вопросе не находит условия поиска, как ожидалось:

Методы Collapse, а затем Find.Execute находятся в цикле до получения первого результата.Поскольку .Execute также находится в блоке With, предшествующем циклу, Find выполняется дважды, таким образом маскируя первое вхождение поискового термина.

Кроме того:

1) ПредпочтительноДля поиска следует использовать конкретный Range, а не весь документ (objDocx.Range).Это связано с «свертыванием» - оно работает более надежно, когда есть конкретный объект Range.

2) Не не используйте Find.Wrap = wdFindContinue, как предлагается в комментариях.wdFindStop (как в коде в вопросе) правильно при использовании Find в цикле.wdFindContinue часто приводит к «бесконечному циклу», поскольку Word снова запускается в начале документа, и снова ...

3) Возможно (лучше) установить объект Document, когдафайл открывается (или создается), а не полагается на ActiveDocument на втором шаге:

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

Вот часть кода, которая имеет отношение к Find - я пропустилчасти 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
0 голосов
/ 02 апреля 2019

Проблема связана с циклом Do While.Измените его на:

            Do While .Find.Found
                ObjWorksheet.Cells(i, 1) = Left(.Text, 8)
                ObjWorksheet.Cells(i, 2) = objDocx.Name
                i = i + 1
                .Collapse wdCollapseEnd
                .Find.Execute
            Loop

Также вместо:

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

используйте:

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