我的宏遇到了问题。 我试图在字符串中找到以FP 608或TM 608开头的元素。
我尝试提取的字符串始终以FP或TM开头。后面的元素是数字,3或4个数字(100或1000)。它们也可以有2位小数(100.10或1000.10)。
例如,它应该提取:
这似乎有效,但效率低下:
Function GetRealCost(MyRange As Variant)
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayStatusBar = False
Dim regEx As Object
Set regEx = CreateObject("vbscript.regexp")
Dim strPattern As String
Dim strInput As String
Dim strOutput As Object
strPattern = "\b(TM )([0-9]{3,4})(,[0-9]{1,2}\b)"
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
strInput = MyRange
If regEx.test(strInput) Then
regEx.Pattern = "(\b[0-9]{3,4})(,[0-9]{1,2}\b)"
Set strOutput = regEx.Execute(MyRange)
GetRealCost = regEx.Execute(strInput)(0)
Else
strPattern = "\b(TM )([0-9]{3,4}\b)"
regEx.Pattern = strPattern
If regEx.test(strInput) Then
regEx.Pattern = "(\b[0-9]{3,4}\b)"
Set strOutput = regEx.Execute(MyRange)
GetRealCost = regEx.Execute(strInput)(0)
Else
strPattern = "\b(FP )([0-9]{3,4})(,[0-9]{1,2}\b)"
regEx.Pattern = strPattern
If regEx.test(strInput) Then
regEx.Pattern = "(\b[0-9]{3,4})(,[0-9]{1,2}\b)"
Set strOutput = regEx.Execute(MyRange)
GetRealCost = regEx.Execute(strInput)(0)
Else
strPattern = "\b(FP )([0-9]{3,4}\b)"
regEx.Pattern = strPattern
If regEx.test(strInput) Then
regEx.Pattern = "(\b[0-9]{3,4}\b)"
Set strOutput = regEx.Execute(MyRange)
GetRealCost = regEx.Execute(strInput)(0)
Else
GetRealCost = ""
End If
End If
End If
End If
Application.ScreenUpdating = True
End Function
谢谢!
答案 0 :(得分:0)
效率低下主要是由于应用和测试了许多正则表达式,所有正则表达式都可以合并为一个。此外,通过仅创建和设置RegExp
个对象一次可以提高代码速度,因为使用公式为每个单元格创建和设置它可能会变得非常无效。
最后,我不相信在 UDF 中禁用/启用屏幕更新和其他内容是一个好主意,因为这将对每个单独计算的单元格应用一次,这是违反直觉的,它实际上没有任何效果,因为除了计算结果之外,不允许UDF更改应用程序的状态。
您可以尝试使用此UDF:
Function GetRealCost(strInput As String) As String
Static reg As Object
If reg Is Nothing Then
Set reg = CreateObject("vbscript.RegExp")
reg.Global = True
reg.MultiLine = True
reg.IgnoreCase = False
reg.Pattern = "\b((FP )|(TM ))\d{3,4}(,\d{1,2})?\b"
End If
Dim matches As Object: Set matches = reg.Execute(strInput)
If matches.count <> 0 Then GetRealCost = Mid(matches(0), 4)
End Function