加速用户定义的函数
Posted
技术标签:
【中文标题】加速用户定义的函数【英文标题】:Speeding Up a User Defined Function 【发布时间】:2018-03-31 03:07:36 【问题描述】:我有与其他 2 个用户定义函数相关联的用户定义函数,当我更新单元格时,它可能需要几分钟 (5-10),因为该文件有多达 400k 个单元格,并且它正在运行另外 2 个自定义函数来创建我们在工作中使用的日期格式。它似乎在循环它们并且需要很长时间。
以下是自定义函数:
Function FL_YR_PDxWK(MY_DATE)
FL_YR_PDxWK = FL_YEAR(MY_DATE) & "_" & Right("00" & FL_PERIOD(MY_DATE),
2) & "x" & FL_WEEK(MY_DATE)
End Function
看这2个:
Function FL_PERIOD(MY_DATE)
If DatePart("yyyy", MY_DATE + (7 - Weekday(MY_DATE))) = DatePart("yyyy",
MY_DATE) Then
If Application.WorksheetFunction.Ceiling((DatePart("ww", MY_DATE) /
4), 1) = 14 Then
FL_PERIOD =
Application.WorksheetFunction.Ceiling((DatePart("ww", MY_DATE) / 4), 1) - 1
Else
FL_PERIOD =
Application.WorksheetFunction.Ceiling((DatePart("ww", MY_DATE) / 4), 1)
End If
Else
FL_PERIOD = 1
End If
End Function
与
Function FL_WEEK(MY_DATE)
If DatePart("yyyy", MY_DATE + (7 - Weekday(MY_DATE))) = DatePart("yyyy",
MY_DATE) Then
If DatePart("ww", MY_DATE) Mod 4 = 0 Then
FL_WEEK = 4
Else
If DatePart("ww", MY_DATE) = 53 Then
FL_WEEK = 5
Else
FL_WEEK = DatePart("ww", MY_DATE) Mod 4
End If
End If
Else
FL_WEEK = 1
End If
End Function
【问题讨论】:
能否请您稍微解释一下每个功能的目的是什么? 你回答了你自己的问题:it is is running through 2 other custom functions
... 通过压缩为一个来提高效率,并确保任何给定的值只需要计算一次(如果需要重复,请使用变量或数组而不是函数。)
...而且,正如@JosephSerido 所说,您的函数需要 cmets 和其他解释,并且一些示例数据也会有所帮助关于您正在尝试做的事情的一些背景知识。 (否则就像说,“我的房子倒了,这锤子怎么了?”)见minimal reproducible example。
另外,我强烈建议在您的模块中指定Option Explicit
,指定您的函数是public
还是private
,始终说明您打算使用ByRef
还是ByVal
,以及明确指定函数返回的类型public MyFunc(ByRef myString) As Boolean
使用函数的结果值而不是函数本身。并使用变体数组来获取结果。
【参考方案1】:
您在 FL_PERIOD 中使用相同的参数调用 .Ceiling(...
两次,并进行两次相同的计算。替换
If Application.WorksheetFunction.Ceiling((DatePart("ww", MY_DATE) / 4), 1) = 14 Then
与
Dim iWeek as Long
Dim iRetVal as Long
iWeek = If Application.WorksheetFunction.Ceiling((DatePart("ww", MY_DATE) / 4), 1)
If iWeek = 14 Then
iRetVal = iWeek - 1
...
FL_PERIOD = iRetVal
您可以在 FL_WEEK 上应用相同的概念,在此您调用两次 If DatePart("ww", MY_DATE)
。
加快代码速度的另一个选项是使用正确且特定的类型。当前版本执行许多类型转换,因为Function FL_YR_PDxWK(MY_DATE)
生成字符串,而其他函数生成整数。实际发生的是 VBA 使用 Variants
并尝试将它们转换为所需的形式。你应该做的是像这样正确指定类型:
Function FL_PERIOD(MY_DATE as Date) as String ' will return string
...
作为奖励,您可以在函数中进行格式化以返回所需的 2 位格式,如下所示:
FL_PERIOD = Format (iRetVal, "00")
End Function
因此您可以省略FL_YR_PDxWK
中的Right
函数调用。
考虑到大量的计算,我推荐另一个技巧,通过减少系统调用的次数来节省额外的秒数:因为你可以确定 iRetVal 在 1 到 53 之间,你可以使用它来代替 Format
If iRetval < 10 Then
FL_PERIOD = "0" & CStr(iRetVal)
Else
FL_PERIOD = CStr(iRetVal)
Endif
【讨论】:
以上是关于加速用户定义的函数的主要内容,如果未能解决你的问题,请参考以下文章