首页 > 解决方案 > 在 VBA excel 中不查看旧数据的最有效程序逻辑是什么?

问题描述

我记得我的一个朋友告诉我,循环遍历整个数据库以满足条件是不好的做法(也是程序员的常见错误),而是引用它们。但是,我知道如何做我想做的唯一方法是使用For-Next循环、If-Then-End If语句和 usingCutPaste宏来删除旧数据点,并使用Filter宏在每次运行代码时只过滤感兴趣的日期。

我需要一种更快的方法,因为我使用 excel VBA 创建了一个全自动工资单程序,该程序将在几年内运行 100,000 或更多行,即使目前只有 6000 行,该程序需要大约 5 分钟才能完成所有的筛选条件和计算。

1.) 使用For-Next循环和If-Then-End If循环

让:

Total_Rows_InSheetTest是工作表中的总行数

ActiveDate_Start是我只想计算的日期

代码逻辑:

For i = 2 To Total_Rows_InSheet
    If Worksheets("Test").Cells(i, 2) >= ActiveDate_Start Then
        'run code'
    End If
Next i

2.) 使用剪切/粘贴宏将数据传输到应归档在另一个工作表中的日期,然后计算的行数将始终为活动行数。

我想将“活动”数据限制在我的工资单应用程序的某个日期范围内,并且我计划删除已经向员工发放工资单的数据行,以免重新计算。这是因为重新运行这些数据是没有意义的,因为它会使程序变得非常慢。

3.) 与 #2 类似,只需使用Filter宏来仅过滤大于或等于ActiveDate_Start

标签: vbaexcel

解决方案


假设我们在 A 列中有一些日期按升序排序(如果未排序,这将不起作用!):

1   2015-01-01
2   2015-01-02
3   2015-01-03
4   2015-01-04
5   2016-12-30
6   2016-12-31
7   2017-01-01
8   2017-01-02
9   2017-01-03
10  2017-01-04
11  2017-01-05
12  2017-01-06
13  2017-01-07
14  2018-01-01
15  2018-01-02
16  2018-01-03
17  2018-01-04
18  2018-01-05

而您的相关数据介于两者之间2017-01-012018-01-01您可以使用

Dim StartRow As Long
StartRow = Application.WorksheetFunction.Match("2017-01-01", Range("A:A").Value, 1)

Dim EndRow As Long
EndRow = Application.WorksheetFunction.Match("2018-01-01", Range("A:A").Value, 1)

Debug.Print StartRow, EndRow

找到循环的第一行和最后一行。

For i = StartRow To EndRow
    If Worksheets("Test").Cells(i, 2) >= ActiveDate_Start Then
        'run code'
    End If
Next i

请注意,您可能需要对Match函数进行一些错误处理,因为它们在找不到任何内容时会抛出错误。

例子:

Dim StartRow As Long
StartRow = 2 'fallback if match throws error
On Error Resume Next 'catch error of match
StartRow = Application.WorksheetFunction.Match("2014-01-01", Range("A:A").Value, 1)
On Error GoTo 0 're-activate error reporting

推荐阅读