Performance VBA环路效率

Performance VBA环路效率,performance,excel,for-loop,vba,Performance,Excel,For Loop,Vba,我已经使用了在网站上找到的答案很多次了,但这是我的第一篇帖子 在函数或子函数中执行for循环更有效,还是将循环的增量值作为参数发送到函数或子函数中更有效 我正在将一些文本数据文件导入Excel,解析出各个字段,然后将一些字段拆分为单个字符。我使用的一个文件是医生名单。我有姓名、地址、电话、DEA号码、NPI等 在检查DEA编号时,我有一个sub接收要检查的行号,该行号将DEA拆分为各个数字,一次检查一个数字,然后修改另一个具有该DEA状态的字段。如果状态单元格中不包含“GOOD”一词,则该状态单

我已经使用了在网站上找到的答案很多次了,但这是我的第一篇帖子

在函数或子函数中执行for循环更有效,还是将循环的增量值作为参数发送到函数或子函数中更有效

我正在将一些文本数据文件导入Excel,解析出各个字段,然后将一些字段拆分为单个字符。我使用的一个文件是医生名单。我有姓名、地址、电话、DEA号码、NPI等

在检查DEA编号时,我有一个sub接收要检查的行号,该行号将DEA拆分为各个数字,一次检查一个数字,然后修改另一个具有该DEA状态的字段。如果状态单元格中不包含“GOOD”一词,则该状态单元格将显示为红色。此外,如果适用的话,我正在给坏数字着色

这艘潜艇做了很多工作,我可能会把它分解一点,但在医生档案中没有任何其他地方我正在执行这个确切的步骤,所以我想我应该保持原样

不管怎么说,真正的问题是我是否应该将行号发送到sub,还是我应该直接打电话给sub,让sub计算行号并进行检查。在第一种情况下,我将调用sub的次数等于doctor文件中的行数。在第二种情况下,我将调用sub一次,并且sub包含每行的for循环。这通常更有效

如果我显得多余,我道歉。我训练了一些复杂的软件,这种东西有时会渗透到生活的其他领域

编辑:我试图将此添加到评论中,但没有足够的经验在这里发布。如果我违反了一些规则,我道歉

以下是我当前用于调用sub的代码:

'Use the Doctor Last Name as the number of rows count
Dim numRows As Integer
numRows = Application.CountA(Sheets("DoctorDEA").Range("m:m"))

'lineCtr is the Line Counter used to iterate the FOR loops
Dim lineCtr As Integer
    lineCtr = 1

'Call DEACHecking and DisplayIssues Subs
For lineCtr = 1 To numRows - 1
    DEAChecking (lineCtr)
    DisplayIssues (lineCtr)
Next lineCtr

我的问题是:不带参数调用DEAChecking,让DEAChecking计算行号,然后使用FOR循环,还是让它保持原样更好?

这个问题现在太广泛了,无法有效回答。因此,我只是提供一个小的见解,可能会帮助您构建您的程序


通常,最有效的代码是所有变量都尽可能局部的代码。如果在循环中使用全局变量或调用其他函数,则比使用局部变量执行所有计算要糟糕得多。

如果要测试每个变量并对其计时,可以使用计时器。如果你有一个很大的差距,你将能够抓住它。如果没有,您的答案在处理时间上没有显著差异

  • 您可以使用此选项并从
    TimerTest
    调用sub,也可以在代码开头调用TimerStart,在代码末尾调用TimerStop
  • 用定时器运行一些代码
  • 记录结果
  • 重复和比较
  • HH:MM:SS:00
    格式
计时器代码:

Public strStartTime As String
Public strEndTime As String
Public startTime As Date
Public endTime As Date


Sub timeTest()

    Call TimerStart
        'INSERT CALL TO YOUR SUB HERE
    Call TimerStop   

End Sub

Sub TimerStart()

    startTime = Now

End Sub

Sub TimerStop()

    endTime = Now

'Waited until the timer stopped to perform any additional code, such as formatting the time

    Dim TotalTime As String

    strStartTime = Format(startTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))  
    strEndTime = Format(endTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))
    TotalTime = Format(endTime - startTime, "hh:mm:ss:" & Right(Format(Timer, "#0.00"), 2))

    MsgBox ("      Start: " & strStartTime & vbNewLine & _
            "        End: " & strEndTime & vbNewLine & _
            "Total Time : " & TotalTime)               
End Sub

学分:@Nick Dandoulakis在他的回答中提到了计时器格式:。

如果您使用新标准重复调用sub,sub必须设置环境(例如使用工作表(“mySheet”)…以或set ws=Sheets(“mySheet”)、最后一行=…)来处理该过程。如果循环在sub中,则环境只设置一次。性能不是问题,从磁盘或网络读取文件需要更长的时间。专注于编写逻辑性和可维护性的代码。汉斯,我想这就是我问题的本质。我知道这两种方法都会奏效。我只是不知道我更喜欢哪一个。我甚至没有想过尝试运行某种计时器代码。我来看看这个。谢谢你,谢谢你提出这个问题。我一直想为这个制作一个计时器,但直到今天我才真正开始。在您的特定示例中,这可能不明显,但这可以应用于任何过程,包括比较
工作表函数
与VBA函数,或其他任何操作。它可能在大型数据集上最有用。即使在同一个模块中?在sub的范围之外?这一切都与处理器的一级/二级缓存有关。寄存器的速度是附近内存访问速度的×倍,因此如果程序将内容保持在循环范围内,则速度会快得多,因为编译器将把它转换为注册表访问命令而不是指针内存访问。