Бесконечный цикл Excel VBA

#excel #vba #loops

#excel #vba #циклы

Вопрос:

Я совсем новичок в VBA

Я получаю бесконечный цикл с приведенным ниже кодом, когда я ожидаю, что поиск прекратится при достижении последнего вхождения. (У меня есть 2 ячейки в текущей рабочей области, которые содержат >>>). Кто-нибудь может сказать мне, что происходит не так?

 Set titles = Range("A1:A1")
Dim bEndLoop As Boolean
bEndLoop = False
' lookup part of content in search
mCurLookup = xlPart
With possibleTitles
    Do While Not bEndLoop
        Set titles = .Find(What:=">>>", After:=ActiveCell)
        If Not titles Is Nothing Then
               Application.Goto titles, True
                MsgBox (titles.Address)
                titles.Activate
            Else
                MsgBox "Nothing found"
                bEndLoop = True
            End If
    ' Set t2 = titles(1).CurrentRegion
    Loop
End With
  

Комментарии:

1. Если значение найдено, в вашем коде нет ничего, что указывало бы циклу на остановку. Обычный способ — сохранить адрес первой найденной ячейки, а затем сверить его с будущими найденными значениями.

2. @SJR Я ожидал, что команда titles.activate переместит активную ячейку вниз по листу, и что After:=ActiveCell скажет команде Find искать только после активной ячейки. Тогда я ожидал, что после последней ячейки, содержащей «>>>», поиск ничего не найдет, и цикл завершится.

Ответ №1:

думаю, ответ должен выглядеть так (изhttps://learn.microsoft.com/en-us/office/vba/api/excel.range .findnext ) Мне не нравится поиск из 2 частей, затем FindNext (разве у меня не может быть только одного цикла?), Но тогда, если это официальный способ сделать это, я думаю, лучше придерживаться этого.

 With Worksheets(1).Range("a1:a500")
     Set c = .Find(2, lookin:=xlValues)
     If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            c.Value = 5
            Set c = .FindNext(c)
            If c is Nothing Then Exit Do
        Loop While c.Address <> firstAddress
      End If
End With
  

Комментарии:

1.@Tom нет, ты не можешь. Если c есть Nothing , то c.Address будет выдана ошибка 91. Логические операторы VBA не закорачиваются, и если бы они это сделали, вам все равно пришлось бы сначала проверить Is Nothing .

2. При использовании Find я бы рекомендовал указать дополнительные параметры.

3. FWIW Я внес изменения в этот файл документации в моем форке, здесь . «Официальный способ» написан странно. Я включу эти изменения в более широкий запрос на извлечение как-нибудь на этой неделе.

Ответ №2:

Ниже приведен пример вашего кода с использованием Find FindNext метода. Использование этого метода намного быстрее, чем использование For эквивалента цикла

 Dim titles As Range
Dim possibleTitles As Range
Dim firstAddress As String

Set possibleTitles = ActiveSheet.Range("A:A")

With possibleTitles
    Set titles = .Find(what:=">>>")
    If Not titles Is Nothing Then
        firstAddress = titles.Address

        Do
            MsgBox titles.Address
            Set titles = .FindNext(titles)
        Loop Until firstAddress = titles.Address
    End If
End With
  

Комментарии:

1. Активная таблица. Диапазон («A: A») у меня не работает (в моем случае это был «B: B»). Это сработало только тогда, когда я изменил его на («B1: K100»). У меня есть 2 совпадающих адреса ячеек в столбце B и один в C

2. @Francis — Возможно, вам потребуется изменить его на свой применимый диапазон