在VBA中使用Range.Find只查找前一个值x?

时间:2015-11-09 14:17:46

标签: excel vba excel-vba

我正在尝试使用VBA中的Range.Find方法来找到最接近的前一个行号,该行号具有" true"值。

例如,在第X列中,会出现一个" true"值(第35行),10行," false,"然后"真"再次(第46行)。

当我在循环中进入第46行时,我需要执行range.find并返回第35行。

我使用的代码是:

Worksheets("Data").Cells.Find(True, searchorder:=xlByColumns, searchdirection:=xlNext).Row

正在发生的事情是我只找到了第一个" true"值(在这种情况下,第2行),或最后一个" true"值(第24行,xxx),因为我改变了搜索方向。

我该怎么做才能找到最前面的" true"值?

3 个答案:

答案 0 :(得分:1)

您可以使用After方法中的Find参数和xlPrevious作为SearchDirection,找到上一行为True。我已根据您的评论更新了代码,将其添加到循环中。

由于您发布了代码,我已将我的答案编辑到您的代码中。

Sub Main()

Dim iCurRow As Long
Dim iCounter As Long
Dim iLastRow As Long
Dim iTempRow As Long
Dim iPreviousRow As Long
Dim iChangeCol As Long
Dim ws As Worksheet

Set ws = Worksheets("Data")

With ws

    iChangeCol = .Cells.Find(what:="Change Over?", searchorder:=xlByColumns, searchdirection:=xlNext).Column

    iLastRow = .Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row

    iPreviousRow = 2

    For iCounter = 3 To iLastRow

        If .Cells(iCounter, iChangeCol).Value = True Then

            iTempRow = .Cells.Find(what:=True, After:=.Cells(iCounter, iChangeCol), searchorder:=xlByColumns, searchdirection:=xlPrevious).Row

            iPreviousRow = iTempRow

        End If

    Next iCounter

End With

End Sub

答案 1 :(得分:1)

此简短代码段同时使用Range.Find methodRange.FindNext method循环显示X列中的所有匹配单元格。

Sub rings_true()
    Dim fnd As Range
    With Worksheets("Sheet1")   `<~~ set this worksheet reference properly
        With .Columns(24)
            Set fnd = .Find(What:="TRUE", after:=.Cells(.Rows.Count), _
                             LookIn:=xlValues, LookAt:=xlWhole, _
                             SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
            Do While Not fnd Is Nothing
                If MsgBox("Currently at " & fnd.Address(0, 0) & Chr(10) & "exit now...?", vbYesNo + vbQuestion) = vbYes Then
                    Exit Do
                Else
                    Set fnd = .FindNext(after:=fnd)
                End If
            Loop
        End With
    End With
End Sub

通过MsgBox function报告当前的单元格地址。相同的MsgBox为用户提供了打破循环的机会。

其他错误控制可能包括在进入循环之前确认X列中至少有一个匹配值。

答案 2 :(得分:1)

多个参数放入Find方法,关于你告诉我们的内容,我建议你使用:

  1. After:=.Cells(.Rows.Count, 1)从列的底部开始
  2. LookIn:=xlValues
  3. LookAt:=xlWhole
  4. SearchOrder:=xlByRows逐行查找(而不是逐列)
  5. SearchDirection:=xlPrevious从下到上看“后退”
  6. MatchCase:=False
  7. SearchFormat:=False
  8. 此外,您可以.Find方法用于特定范围,而不是Worksheets("Data").Cells.Find(...,您应该使用Worksheets("Data").Range("X:X").Find(...仅查看第X栏。

    以下是修改后的代码:

    Sub test_ilarson007()
    Dim FirstAddress As String, PreviousMatch As Range, cF As Range
    
    Worksheets("Data").Activate
    With Worksheets("Data").Range("X:X")
        'First, define properly the Find method
        Set cF = .Find(What:=True, _
                    After:=ActiveCell, _
                    LookIn:=xlValues, _
                    LookAt:=xlWhole, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False, _
                    SearchFormat:=False)
    
        'If there is a result,
        If Not cF Is Nothing Then
            FirstAddress = cF.Address
            MsgBox "The row containing the previous 'True' in Column X is : " & cF.Row
            'keep looking with FindNext method : Not usefull for your example
            Do
                Set PreviousMatch = cF
                Set cF = .FindNext(cF)
                '-------------------------------------------------------------
                '----Place instructions to execute on the matched cell/row/...
                'First match (i.e. Row 46 in your example)
                MsgBox PreviousMatch.Row 'Should display 46 (then 35, then ??)
                'Second match (i.e. Row 35 in your example)
                MsgBox cf.Row 'Should display 35 (then ??, then ??)
    
    
                '-------------------------------------------------------------
            'Look until you find again the first result
            Loop While Not cF Is Nothing And cF.Address <> FirstAddress
        End If
    End With
    
    End Sub