简体   繁体   English

列的VBA递归循环

[英]VBA Recursive loop for columns

Can anyone explain me if I can recursively loop through a sorted list inside a For loop? 谁能解释我是否可以递归遍历For循环内的排序列表?

I am looping through a column, and once I found an exact match (lets say EALOLES string), then I want to keep on looping until there's no more matches. 我遍历一列,一旦找到完全匹配(让我们说EALOLES字符串),那么我想继续循环直到没有更多匹配为止。 Data example 资料范例

For i = 2 to UsedRange.Rows.Count
  If (Cells(i, 12).Value = "EALOLES") Then
    ' Start an inner loop until EALOLES ends, increment i++
    ' Perform actions appropriate to EALOLES case
    Exit For
  End If
next i

This is all fine with an inner loop, but I was just wondering if this could be achieved also with a recursive function and how that would look like? 有了内部循环,这一切都很好,但是我只是想知道是否也可以通过递归函数来实现,那会是什么样子? From the example I learned about recursion, I would imagine to loop from end of workbook to the beginning. 从我学到的有关递归的示例中,我可以想象从工作簿的末尾开始循环。

Note, I am not stating it would be a better solution, neither an inner loop, but I am just very curious. 请注意,我并不是说这将是一个更好的解决方案,无论是内部循环,还是我很好奇。

Your question is basically is this a candidate for recursion, and the answer is no. 您的问题基本上是这是递归的候选人,答案是否定的。 Iteration with your inner loop is the better solution in this case. 在这种情况下,使用内部循环进行迭代是更好的解决方案。

Read the article: Recursion and Iteration to learn when to use each. 阅读文章: 递归和迭代以了解何时使用它们。

Assuming your data are sorted, you could take advantage of that 假设您的数据已排序,则可以利用它

Dim nOccurrences As Long
Dim cell As Range
With Intersect(ActiveSheet.UsedRange, Columns(12))
    nOccurrences = WorksheetFunction.CountIf(.Cells, "EALOLES")
    If nOccurrences > 0 Then
        For Each cell in .Resize(nOccurrences).Offset(.Find(What:= "EALOLES", LookIn:=xlValues, LookAt:=xlWhole, After:=.Cells(.Rows.Count)).Row-1)
              ‘Do your things
        Next
    End If
End With

This is not an efficient method of returning the start and stop positions of a string in a sorted list but as an intellectual excercise this should do. 这不是返回排序列表中字符串的开始和结束位置的有效方法,但是作为一种知识型练习,应该这样做。

dim i as long, j as long

For i = 2 to UsedRange.Rows.Count
  If (Cells(i, 12).Value = "EALOLES") Then
    for j=i to UsedRange.Rows.Count
      If (Cells(j+1, 12).Value <> "EALOLES") Then
        exit for
      end if
    next j
    Exit For
  End If
next i

debug.print "start: " & i
debug.print "end: " & j

I was musing with a slightly different take on the same theme 我对同一主题的想法略有不同

Define a range to loop over. 定义要循环的范围。 See if the value exists in the range. 查看该值是否在范围内。 If it does, start at the first match and keep looping the loop range until the cell value differs from the specified target string. 如果是这样,则从第一个匹配项开始,并继续循环范围,直到单元格值不同于指定的目标字符串。

Option Explicit

Sub StopAtEnd()

    Dim wb As Workbook
    Dim ws As Worksheet
    Dim endRow As Long

    Set wb = ThisWorkbook
    Set ws = wb.Worksheets("Sheet5")             'change as needed

    endRow = ws.Cells(ws.Rows.Count, "L").End(xlUp).Row

    Dim loopRange As Range

    Set loopRange = ws.Range("L1:L" & endRow) 'Change start row as required

    Dim currentCell As Range
    Dim targetString As String
    Dim startRow As Long

    targetString = "EALOLES"

    On Error GoTo Errhand

    startRow = Application.Match(targetString, loopRange, 0)

    Do Until ws.Range("L" & startRow) <> targetString
        Debug.Print ws.Range("L" & startRow).Address
        startRow = startRow + 1
    Loop

    Exit Sub

Errhand:

    MsgBox "Target string not found"

End Sub

Shout out to @DisplayName who pointed out this could be written instead as: 向@DisplayName大喊大叫,后者指出可以这样写:

Option Explicit

Sub StopAtEnd()

    Dim wb As Workbook
    Dim ws As Worksheet
    Dim endRow As Long

    Set wb = ThisWorkbook
    Set ws = wb.Worksheets("Sheet1")             'change as needed

    endRow = ws.Cells(ws.Rows.Count, "L").End(xlUp).Row

    Dim loopRange As Range

    Set loopRange = ws.Range("L1:L" & endRow) 'Change start row as required

    Dim currentCell As Range
    Dim targetString As String
    Dim startRow As Variant

    targetString = "EALOLES"

    startRow = Application.Match(targetString, loopRange, 0)

    If IsError(startRow) Then

        MsgBox "Target string not found"

    Else

        Do Until ws.Range("L" & startRow) <> targetString

            Debug.Print ws.Range("L" & startRow).Address
            startRow = startRow + 1

        Loop

   End If

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM