【问题标题】:Excel vba reverse for loop stepping beyond end valueExcel vba反向循环超出结束值
【发布时间】:2015-07-23 11:46:53
【问题描述】:

我正在调试下面的代码。当我遍历它时,我注意到 row_j 的值为 1,尽管 For row_j = LastRow_date_new To 2 Step -1

我希望row_j 的最小值为 2,因为第 1 行中没有数据。SearchCol 中的值是格式为 20/01/2015 09:15:00 的日期,没有间隙或空值。

row_j 用于设置End_row,它被传递给Copy_to_b 并在那里传播错误。

谁能看出我的问题出在哪里?

另外,您能否推荐一种方法来在满足与Date_end 匹配的所需值时退出循环

谢谢

Sub select_date_range(LastCol As Long, LastRow_date_new As Long, DateMax As Date, Date_end As Date)
Dim SearchCol As Integer
Dim row_i As Integer
Dim row_j As Integer
Dim Start_row As Integer
Dim End_row As Integer

With Worksheets("a")
    For SearchCol = 1 To LastCol Step 3
        LastRow_date_new = Application.CountA(.Range((.Cells(1, SearchCol)), (.Cells(65536, SearchCol))))
        For row_i = 2 To LastRow_date_new
            If Sheets("a").Cells(row_i, SearchCol).Value = DateMax Then Start_row = row_i
        Next row_i
        For row_j = LastRow_date_new To 2 Step -1
            If Sheets("a").Cells(row_j, SearchCol).Value = Date_end Then End_row = row_j
        Next row_j
        ''''''' use range col1, row i to col2, row j to copy into new sheet
        Call copy_to_b(Start_row, SearchCol, End_row)
    Next SearchCol
End With

End Sub

【问题讨论】:

    标签: vba excel for-loop


    【解决方案1】:

    使用For row_j = LastRow_date_new To 2 Step -1,并且在每个For 之后,您的变量将等于最后一个值+ 步骤,这就是For-loop 自身退出的方式。

    因此,如果您不想将该变量设置为 1,则必须在 For-loop 之后将其设置为正确的值,如下所示:

        For row_i = 2 To LastRow_date_new
            If Sheets("a").Cells(row_i, SearchCol).Value = DateMax Then Start_row = row_i
        Next row_i
        row_i=2
        For row_j = LastRow_date_new To 2 Step -1
            If Sheets("a").Cells(row_j, SearchCol).Value = Date_end Then End_row = row_j
        Next row_j
        row_j=2
    

    要在您的条件匹配时退出循环,您可以使用Exit For,有些人会说它不优雅但确实有效(以及代码审查下面的另一种方式)

    Sub select_date_range(LastCol As Long, LastRow_date_new As Long, DateMax As Date, Date_end As Date)
    Dim SearchCol As Integer
    Dim row_i As Integer
    Dim row_j As Integer
    Dim Start_row As Integer
    Dim End_row As Integer
    
    With Worksheets("a")
        For SearchCol = 1 To LastCol Step 3
            LastRow_date_new = Application.CountA(.Range((.Cells(1, SearchCol)), (.Cells(65536, SearchCol))))
    
            For row_i = 2 To LastRow_date_new
                If CDate(.Cells(row_i, SearchCol).Value) <> CDate(DateMax) Then
                Else
                    Start_row = row_i
                    Exit For
                End If
            Next row_i
    
            For row_j = LastRow_date_new To 2 Step -1
                If CDate(.Cells(row_j, SearchCol).Value) <> CDate(Date_end) Then
                Else
                    End_row = row_j
                    Exit For
                End If
            Next row_j
    
    
            ''''''' use range col1, row i to col2, row j to copy into new sheet
            Call copy_to_b(Start_row, SearchCol, End_row)
        Next SearchCol
    End With
    
    End Sub
    

    要替换您的For,您可以使用Do WhileDo Until

    row_j = LastRow_date_new
    Do While row_j >= 2 And .Cells(row_j, SearchCol).Value <> Date_end
        row_j = row_j - 1
    Loop
    End_row = row_j
    

    【讨论】:

    • 感谢@R3uK。我在原始问题中犯了一个错误(现已编辑)。我传递了基于row_j 设置的变量end_row。干杯
    • 是的,我看到后来打字忘了更正,完成! ;) 代码工作正常吗?
    • End_row 的值仍然为 0,所以还没有
    • 使用Exit For 方法??当您比较日期时,可能在比较的两个部分都使用CDate() 函数,请参阅编辑
    • 啊,似乎早期的函数正在重置 Date_max 值,这可能是造成问题的原因。 Exit for 方法现在似乎(主要)有效。我会做更多的调试......
    【解决方案2】:

    我认为您的问题可能是由于您查看的列中缺少任何值或只有一个值。此外,如果您在此列中有空值,您可能会错过值,如果是这种情况,我会改变我的答案。你应该改变

    With Worksheets("a")
        For SearchCol = 1 To LastCol Step 3
            LastRow_date_new = Application.CountA(.Range((.Cells(1, SearchCol)), (.Cells(65536, SearchCol))))
            For row_i = 2 To LastRow_date_new
                If Sheets("a").Cells(row_i, SearchCol).Value = DateMax Then Start_row = row_i
            Next row_i
            For row_j = LastRow_date_new To 2 Step -1
                If Sheets("a").Cells(row_j, SearchCol).Value = Date_end Then End_row = row_j
            Next row_j
            ''''''' use range col1, row i to col2, row j to copy into new sheet
            Call copy_to_b(Start_row, SearchCol, End_row)
        Next SearchCol
    End With
    

    到这里

    Dim xlws As Excel.Worksheet
    Dim lngrow as Long
    Set xlws = Thisworkbook.Sheets("a")
    For SearchCol = 1 to LastCol Step 3
        While xlws.Range.Cells(lngrow,SearchCol).Value <> ""
              If xlws.Cells(lngrow,SearchCol).Value = DateMax Then
                 Start_row = lngrow
              Elseif xlws.Cells(lngrow,SearchCol).Value = Date_end Then
                 End_row = lngrow
              End If
              lngrow = lngrow + 1
         Loop
         Call copy_to_b(Start_row, SearchCol, End_row)
     Next SearchCol
    

    【讨论】:

    • 感谢@cronos2546 的输入。我应该提到我搜索的列中没有空白或空值。编辑问题以反映这一点。干杯
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2012-03-13
    • 1970-01-01
    • 2017-05-26
    • 2023-03-29
    相关资源
    最近更新 更多