我有一个很大的Excel文件,其中包含许多手动输入的数据以及许多计算出的列。一组列包含机架号,机架号格式为文本,是三位数字。一个单元可能包含零个或多个机架号。当一个单元中存在多个机架号时,它们用/
分隔。因为我经常用手指指着机架号并错误地输入四位数,所以我设置了一个条件格式设置规则,以将具有不好机架号的单元格颜色设置为红色。
这是我的规则:
=HAS_BAD_RACK_NO(L1834)
应用于范围=$L$1834:$S$1981
。确切的范围每天都在变化,但是大小始终相同。这是驱动它的VBA函数:
Public Function HAS_BAD_RACK_NO(ref As Range) As Boolean
Dim re As New RegExp
Dim cell As Range
Dim found As Boolean
found = False
re.Pattern = "[0-9]{4,}"
For Each cell In ref.Cells
If re.Test(cell.value) Then
HAS_BAD_RACK_NO = True
found = True
Exit For
End If
Next cell
If Not found Then
HAS_BAD_RACK_NO = False
End If
End Function
问题在于,每当我在其覆盖的单元格之一中输入数据时,此条件格式设置规则就会大大降低Excel的速度。我估计离开单元格后,Excel会在1到10秒之间重新开始响应并接受键盘输入。我不知道为什么它这么慢,因为它从未检查多个单元格。只有一个单元格范围。
诚然,这是一个复杂的电子表格,具有多个自定义功能,相当多的条件格式设置规则以及大量图表。但是,通过测试,我确定只有在我编辑此特定条件格式设置规则范围内的单元格时,才会出现这种减速。如果我编辑范围以排除正在编辑的单元格,则性能问题将消失。
此功能非常简单;为什么这么慢?
答案 0 :(得分:3)
在我的测试中,此函数的执行速度提高了大约30倍-使用静态正则表达式,而不是每次运行都创建一个新的正则表达式:
Public Function HAS_BAD_RACK_NO(ref As Range) As Boolean
Static re As RegExp '<< use a static object
'only create if needed
If re is nothing then
Set re = New RegExp
re.Pattern = "[0-9]{4,}"
end if
if ref.countlarge > 1 then
HAS_BAD_RACK_NO = True 'don't allow multiple-cell inputs
else
HAS_BAD_RACK_NO = re.Test(ref.value)
end if
End Function
测试子:
Sub Driver()
Dim t
t = Timer
'L34:S181 contains the data which the UDF processes
With ActiveSheet.Range("L34:S181")
.Value = .Value
End With
Debug.Print Timer - t
End Sub
原始版本约为1.3秒,而使用静态正则表达式则约为0.04秒。