#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 — Возможно, вам потребуется изменить его на свой применимый диапазон