使用“ Do Loop While”循环时,FindNext不会更新Range.Address

时间:2019-06-06 14:15:23

标签: excel vba excel-vba

我想做的是在A1到工作簿“摘要”工作表中最后使用的列中的一系列单元格中查找“ DESC”。代码找到搜索值后,它将检查是否为DESC或TERMDESC。

'Gets Column Letter from Column Index
Dim vArr
Dim ColLetter As String
vArr = Split(Cells(1, Lastcolumn).Address(True, False), "$")
ColLetter = vArr(0) ' -->Column NA

'Loop begins
Dim cell As Range
Dim firstCellAddress as string
Dim DescMaxNumber As Integer
Dim TermDescMaxNumber As Integer
Dim ModString as string
Dim ModNumber as integer
DescMaxNumber = 0
TermDescMaxNumber = 0

Set cell = ThisWorkbook.Worksheets("Summary").Range("A1:" & ColLetter & "1").Find("DESC", LookIn:=xlValues)

If cell Is Nothing Then
    MsgBox "Not Found"
    Exit Sub
End If

然后,代码将检查其后两个字母是否具有整数(例如DESCA01,字符串01是整数),以及是否将其存储在DescMaxNumber或TermDescMaxNumber上。

 firstCellAddress = cell.Address

'Find all cells containing DESC including TERMDESC and max numeric value
Do
    SearchString = cell.Value

    'Determines if SearchString is DESC or TermDESC *BEGINNING*
    If InStr(1, SearchString, "DESC") = 1 Then
        ModString = Right(SearchString, 2)

        If IsNumeric(ModString) = True Then
            ModNumber = CInt(ModString)

            If DescMaxNumber < ModNumber Then
                DescMaxNumber = ModNumber
            End If
        End If

    ElseIf InStr(1, SearchString, "TERMDESC") = 1 Then
        ModString = Right(SearchString, 2)

        If IsNumeric(ModString) = True Then
            ModNumber = CInt(ModString)

            If TermDescMaxNumber < ModNumber Then
                TermDescMaxNumber = ModNumber
            End If
        End If
    End If
    Set cell = Range("A1:" & ColLetter & "1").FindNext(cell)
Loop While firstCellAddress <> cell.Address

MsgBox "DESC Max Number = " & DescMaxNumber
MsgBox "TERMDESC Max Number = " & TermDescMaxNumber

此后,它将移动到具有DESC值的下一个单元格。 这是我的问题所在:第一次运行代码时,它将循环遍历包含DESC的所有单元格(D1,E1,F1等),并告诉我DescMaxNumber等于34,而TermDescMaxNumber等于36。

如果我再次运行代码DexcMaxNumber = 0和TermDescMaxNumber = 0,进入代码,我注意到cell.address不会从D1更改为E1,而是停留在D1

谢谢

2 个答案:

答案 0 :(得分:1)

在对Find的初始调用中,指定了我们要搜索的范围是在存储此代码的工作簿中名为Summary的工作表上:

Set cell = ThisWorkbook.Worksheets("Summary").Range("A1:" & ColLetter & "1").Find("DESC", LookIn:=xlValues)

在对FindNext的调用中,未指定任何工作表,因此我们要搜索的范围位于活动工作簿(可能为“摘要”的工作表)中(可能是也可能不是称为“摘要”的工作表)或可能不是存储此代码的工作簿):

Set cell = Range("A1:" & ColLetter & "1").FindNext(cell)

要解决此问题,您只需在对FindNext的调用中指定工作表即可:

Set cell = ThisWorkbook.Worksheets("Summary").Range("A1:" & ColLetter & "1").FindNext(cell)

,但是如果您使用变量存储要搜索的范围,然后仅引用该变量,则它可以减少代码的出错率:

Dim rngToSearch As Range

Set rngToSearch = ThisWorkbook.Worksheets("Summary").Range("A1:" & ColLetter & "1")
Set cell = rngToSearch.Find("DESC", LookIn:=xlValues)

' do stuff with cell

Set cell = rngToSearch.FindNext(cell)

答案 1 :(得分:0)

虽然不是直接回答您自己的问题,但在这种情况下,最好使用通用的FindAll函数,然后处理找到的范围内的单个单元以获取您的值。

我已经使用一些捷径来说明该过程,但是您应该能够使FindAll调用适应您的需求。

Sub ProcessDesc()
    Dim wsSrc As Worksheet: Set wsSrc = ThisWorkbook.Sheets("Sheet1")

    Dim FoundRange As Range, Cell As Range, Val As Integer

    Dim DescMaxNumber As Integer: DescMaxNumber = 0
    Dim TermDescMaxNumber As Integer: TermDescMaxNumber = 0

    Set FoundRange = FindAll("*DESC*", wsSrc.UsedRange)

    For Each Cell In FoundRange
        Val = IIf(IsNumeric(Right(Cell, 2)), CInt(Right(Cell, 2)), 0)
        If InStr(Cell, "TERMDESC") Then
            TermDescMaxNumber = IIf(Val > TermDescMaxNumber, Val, TermDescMaxNumber)
        Else
            DescMaxNumber = IIf(Val > DescMaxNumber, Val, DescMaxNumber)
        End If
    Next Cell
    Debug.Print DescMaxNumber, TermDescMaxNumber

End Sub

Private Function FindAll(What, _
    Optional SearchWhat As Variant, _
    Optional LookIn, _
    Optional LookAt, _
    Optional SearchOrder, _
    Optional SearchDirection As XlSearchDirection = xlNext, _
    Optional MatchCase As Boolean = False, _
    Optional MatchByte, _
    Optional SearchFormat) As Range

    'LookIn can be xlValues or xlFormulas, _
     LookAt can be xlWhole or xlPart, _
     SearchOrder can be xlByRows or xlByColumns, _
     SearchDirection can be xlNext, xlPrevious, _
     MatchCase, MatchByte, and SearchFormat can be True or False. _
     Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
     object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""

    Dim SrcRange As Range
    If IsMissing(SearchWhat) Then
        Set SrcRange = ActiveSheet.UsedRange
    ElseIf TypeOf SearchWhat Is Range Then
        Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
    ElseIf TypeOf SearchWhat Is Worksheet Then
        Set SrcRange = SearchWhat.UsedRange
    Else: SrcRange = ActiveSheet.UsedRange
    End If
    If SrcRange Is Nothing Then Exit Function

    'get the first matching cell in the range first
    With SrcRange.Areas(SrcRange.Areas.Count)
        Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
    End With

    Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
        SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)

    If Not CurrRange Is Nothing Then
        Set FindAll = CurrRange
        Do
            Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
            SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
            If CurrRange Is Nothing Then Exit Do
            If Application.Intersect(FindAll, CurrRange) Is Nothing Then
                Set FindAll = Application.Union(FindAll, CurrRange)
            Else: Exit Do
            End If
        Loop
    End If
End Function