FindNext - проверка кода VBA верна, но в Excel не работает [дубликат]

[D3] Список & л; Строка & GT; items = ui.getQueryParameters (). get ("item");

где ui объявлен как член в остальном ресурсе, например:

  @Context UriInfo ui;   

Недостатком является то, что он вообще не появляется в аргументах методов.

5
задан Elysian Fields 28 March 2013 в 19:28
поделиться

2 ответа

Причина, по которой она дает только первое совпадение, связана с ошибкой. См. Ссылку (РАЗДЕЛ 5) внизу.

Я уже давно подал ее как ошибку. Если вы прочитали вышеприведенную ссылку, я также предложил альтернативный код.

Извлеките эту ссылку в случае, если ссылка когда-либо замирает (что ей не нужно)

.FindNext doesn работайте в пользовательской функции, как ожидалось. Вы можете использовать его в нормальной функции.

Позволяет сказать, что у нас есть эти данные в Sheet1:

A1 → Colt
A2 → Holt
A3 → Dolt
A4 → Hello

и в

B1 → olt

Теперь, если мы вставьте приведенный ниже код в модуль и запустите его, тогда мы получим ожидаемый результат как $A$1:$A$3

Sub Test()
    Sample Sheets("Sheet1").Range("B1"), Sheets("Sheet1").Range("A1:A4")
End Sub

Sub Sample(FirstRange As Range, ListRange As Range)
    Dim aCell As Range, bCell As Range, oRange As Range
    Dim ExitLoop As Boolean
    Set oRange = ListRange.Find(what:=FirstRange.Value, LookIn:=xlValues, _
    lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False)
    ExitLoop = False
    If Not oRange Is Nothing Then
        Set bCell = oRange: Set aCell = oRange

        Do While ExitLoop = False
            Set oRange = ListRange.FindNext(After:=oRange)

            If Not oRange Is Nothing Then
                If oRange.Address = bCell.Address Then Exit Do
                Set aCell = Union(aCell, oRange)
            Else
                ExitLoop = True
            End If
        Loop
        MsgBox aCell.Address
    Else
        MsgBox "Not Found"
    End If
End Sub

Однако он не будет работать так, как ожидалось, если вы вставляете эту функцию в модуль и вызываете ее из рабочий лист как (Say in Cell C1) =FindRange(A1,A1:A5)

Код даст вам только 1-й экземпляр найденного значения и игнорирует остальные

. И, следовательно, результат, который вы будете get $ A $ 2 !!!

Function FindRange(FirstRange As Range, ListRange As Range) As String
    Dim aCell As Range, bCell As Range, oRange As Range
    Dim ExitLoop As Boolean
    Set oRange = ListRange.Find(what:=FirstRange.Value, LookIn:=xlValues, _
    lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False)
    ExitLoop = False
    If Not oRange Is Nothing Then
        Set bCell = oRange: Set aCell = oRange

        Do While ExitLoop = False
            Set oRange = ListRange.FindNext(After:=oRange)

            If Not oRange Is Nothing Then
                If oRange.Address = bCell.Address Then Exit Do
                Set aCell = Union(aCell, oRange)
            Else
                ExitLoop = True
            End If
        Loop
        FindRange = aCell.Address
    Else
        FindRange = "Not Found"
    End If
End Function

Нам нужно подходить к этому под другим углом.

Вместо использования .FindNext мы используем .Find снова, пока не получим желаемый результат ($ A $ 1: $ A $ 3). См. Код ниже, который работает:

Function FindRange(FirstRange As Range, ListRange As Range) As String
    Dim aCell As Range, bCell As Range, oRange As Range
    Dim ExitLoop As Boolean
    Set oRange = ListRange.Find(what:=FirstRange.Value, LookIn:=xlValues, _
    lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False)
    ExitLoop = False
    If Not oRange Is Nothing Then
        Set bCell = oRange: Set aCell = oRange

        Do While ExitLoop = False
            Set oRange = ListRange.Find(what:=FirstRange.Value, After:=oRange, LookIn:=xlValues, _
            lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
            MatchCase:=False, SearchFormat:=False)
            If Not oRange Is Nothing Then
                If oRange.Address = bCell.Address Then Exit Do
                Set aCell = Union(aCell, oRange)
            Else
                ExitLoop = True
            End If
        Loop
        FindRange = aCell.Address
    Else
        FindRange = "Not Found"
    End If
End Function
2
ответ дан Siddharth Rout 17 August 2018 в 10:54
поделиться
  • 1
    Я могу жить с этим, будучи ошибкой. Раздражает, но, хорошо знать. – Elysian Fields 28 March 2013 в 22:40

Пожалуйста, не так, как для логики, но вот решение, которое дает мне те же результаты. Измените .Find строку на:

Set c = .Find(what:=lookupRange.Value2, after:=.Cells(1), LookIn:=xlValues, LookAt:=xlWhole)

и дополнительно измените .FindNext на:

Set c = .Find(what:=lookupRange.Value2, after:=c, LookIn:=xlValues, LookAt:=xlWhole)

. Обратите внимание, что диапазон tableRange должен иметь названия столбцов. Если нет, то порядок результатов не будет ожидаться с первого взгляда.

Дополнительное (EDITED) объяснение для последнего предложения. Если у вас есть таблица этого типа:

    |  A  |  B  |  C  |  D  |
  --+-----+-----+-----+-----+
  1 | ABC    1     2     A
  2 | ABC    3     4     B
  3 | ABC    5     6     C

при поиске ABC в range("A1:D3") для получения данных из столбца D вы получите результат: BCD. Чтобы получить ABC, в первой строке должны быть заголовки столбцов.

2
ответ дан Kazimierz Jawor 17 August 2018 в 10:54
поделиться
  • 1
    Кажется, что это хорошо работает - есть ли у вас предложения, если у tableRange нет заголовков? – Elysian Fields 28 March 2013 в 21:10
  • 2
    Кроме того, что это делает эту работу (и мое использование .Find не работает)? Возможно .FindNext не может быть вызван из UDF – Elysian Fields 28 March 2013 в 21:11
Другие вопросы по тегам:

Похожие вопросы: