我有一个循环遍历一列的宏,该列保存从旧到最近的日期。它找到每个大于
Now
的日期,然后转到其相邻单元格并清除它们。
我相信,如果宏不会针对列(500 行)中的所有值循环,而是在第一个单元格匹配处停止,然后转到其相邻单元格并清除从该行到底部的所有内容,速度会快得多表的内容(即,如果匹配位于第 15 行,则清除从第 15 行一直到 500 的内容),而不检查每一行。
Dim R As Long
For R = 1 To 500
If Cells(R, "A").Value >= Now Then Cells(R, "B").Value = ""
If Cells(R, "A").Value >= Now Then Cells(R, "C").Value = ""
Next
End Sub
使用您的方法,如果您想知道如何在条件匹配后退出循环 - 您可以使用
Exit For
。您还可以同时清除 B 列和 C 列,如下所示:
Dim R As Long
With ActiveWorkbook.Sheets("Sheet1")
For R = 1 To 500
If .Cells(R, "A").Value >= Now Then
.Range("B" & R & ":C500").ClearContents
Exit For
End If
Next
End With
在上面,我还添加了对该表的引用。一旦有不止一张纸可用,这始终是防止可能出现错误的良好做法。
这是一个二分搜索的示例。
Option Explicit
Public Sub ClearByDates(Optional targetDate As Variant = Null)
Dim thisSheet As Worksheet
Dim activeRange As Range
Dim lowerRow As Long, higherRow As Long, thisRow As Long
Dim thisDate As Date
' If no date is provided, assume today is the cutoff
If IsNull(targetDate) Then targetDate = Date
' Assuming that we're putting this code in the worksheet that you want to _
clear. If you decide to put it in a separate module you can either: _
(1) Pass in the worksheet you want to modify as an argument, or _
(2) Explicitly set the worksheet you want to modify using ActiveWorkbook.Worksheets(Name)
Set thisSheet = Me
Set activeRange = thisSheet.UsedRange
With activeRange
' Not only is it cleaner if you use With, you get better performance in VBA _
because it's a hint that the object should be kept loaded and ready.
' Getting the range of rows with values
lowerRow = .Rows(1).Row
higherRow = lowerRow + activeRange.Rows.Count - 1
' Don't start processing until you're in the date range; _
this should handle most common worksheet header situations.
Do Until IsDate(activeRange.Cells(lowerRow, 1))
lowerRow = lowerRow + 1
If lowerRow > higherRow Then Exit Sub
Loop
' Use a binary search to find the first row where the date is _
greater than or equal to the target date.
Do Until lowerRow >= higherRow - 1
thisRow = (higherRow + lowerRow) / 2
thisDate = .Cells(thisRow, 1)
Debug.Print "Row " & Right(" " & thisRow, 7) & ": " & Format(thisDate, "YYYY-MM-DD") & " ";
If thisDate >= targetDate Then
Debug.Print ">= " & Format(targetDate, "YYYY-MM-DD");
higherRow = thisRow
Else
Debug.Print "< " & Format(targetDate, "YYYY-MM-DD");
lowerRow = thisRow
End If
Debug.Print " (lowerRow = " & lowerRow & ", higherRow = " & higherRow & ")"
Loop
' Assuming we just want to clear columns B & C. This can easily be adjusted _
to clear all columns to the right by using .Columns(.Columns.Count) in the _
ending range.
thisSheet.Range("B" & thisRow & ":C" & .Rows(.Rows.Count).Row).ClearContents
End With
End Sub