VBA脚本工作正常,突然出现错误?
VBA脚本工作正常,突然出现错误?
我在Excel表格上有以下代码。我使用VBA来修改特定单元格的内容,以便正确格式化它们以适应我的工作。我们保留有损坏、贝位和车辆识别号码的列表。每一列都有自己特定的格式,其中有两列我已经成功地处理了。你们中的一些人可能会认出这些代码中的一些内容,因为我之前在另一个帖子中就曾提到过如何正确格式化损坏代码。这些列的顺序如下:
贝位 | 车辆识别号码 | 损坏代码
对于车辆识别号码,我们只是将字母转换为大写。简单,完成了。经过一些修改以更好地适应我的需求,损坏代码的函数运行得很完美。如果没有在这里得到的原始帮助,我是无法做到这一点的。现在问题来了,我的老板看到我已经能够处理损坏代码后,要求我让它自动格式化贝位。在我的工作中,贝位有几种可能性,但前面至少有一个字母,例如:
- H-5
- H-125
- HH-50
- 7A-70
- FNCE-13
我想要的是这样的:
输入未经格式化的贝位,比如7a12,将字母转换成大写,按数字进行分割,在两组之间加上一个破折号,完成。我已经实现了这一点,甚至向我的老板展示了。但是当我添加了将车辆识别号码转换为大写的代码后,我开始遇到一个错误,突出显示以下行:
Set allMatches = RE1.Execute(strSource)
RE1.test(strSource)运行得很好,但尝试获取匹配项/子匹配项现在却神秘地抛出了一个错误。我最初使用了来自这个StackOverflow问题的文本来使它正常工作。我得到的错误类似于告诉我对象未设置。我知道代码目前很混乱,我不得不中途离开(认为可能是我的函数出了问题,但事实上,直接从原始子函数运行时仍然会出现相同的错误)。
编辑:错误如下
运行时错误 '91'
对象变量或 With 块变量未设置
而且,它再次突出显示
allMatches = RE.Execute(str)
任何帮助将不胜感激。
Private Sub Worksheet_Change(ByVal Target As Range) Dim KeyCells As Range Dim str As String, result As String Dim RE As Object Dim allMatches As Object ' 变量KeyCells包含将在更改时引发警报的单元格。 Set KeyCells = Application.Union(Range("F3:F100"), Range("C3:C100"), Range("I3:I100")) Set RE = CreateObject("vbscript.regexp") If Not TypeName(Target.Value) = "Variant()" Then If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then ' 当其中一个指定单元格已更改时显示消息。 ' 在这里放置你的代码。 str = ConvertString(Target) If (Not str = Target.Value And Not Target.Value = "") Then Target.Value = str End If End If ' 现在我们要检查贝位以进行自动格式化 Set KeyCells = Application.Union(Range("A3:A100"), Range("D3:D100"), Range("G3:G100")) If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then RE.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})" RE.Global = True If Not Target.Value = "" And Not RE.test(Target.Value) Then str = CStr(Target.Value) RE.IgnoreCase = True allMatches = RE.Execute(str) MsgBox allMatches.Count Target.Value = str End If End If Set KeyCells = Application.Union(Range("B3:B100"), Range("E3:E100"), Range("H3:H100")) If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then RE.Pattern = "[a-z]?" RE.IgnoreCase = False If RE.test(Target.Value) Then Target.Value = UCase(Target.Value) End If End If End If End Sub Function FormatBay(str1 As Range) As String Dim result As String, strSource As String Dim allMatches As Object Dim RE1 As Object Set RE1 = CreateObject("vbscript.regexp") RE1.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})" RE1.Global = True strSource = CStr(str1.Value) Set allMatches = RE1.Execute(strSource) result = "FF-12" If allMatches.Count <> 0 Then result = allMatches.Item(0) End If MsgBox result FormatBay = result End Function Function ConvertString(str1 As Range) As String Dim varStr As Variant Dim strSource As String, strResult As String Dim i As Integer For Each varStr In Split(Trim(str1.Value), " ") strSource = CStr(varStr) If InStr(strSource, ".") = 0 Then strResult = strResult & _ Mid(strSource, 1, 2) & "." & _ Mid(strSource, 3, 2) & "." & _ Mid(strSource, 5, 1) If Len(strSource) > 5 Then strResult = strResult & "(" For i = 6 To Len(strSource) strResult = strResult & Mid(strSource, i, 1) & "," Next i strResult = Left(strResult, Len(strResult) - 1) & ")" End If strResult = strResult & " " Else strResult = strResult & strSource & " " End If Next If strResult = "" Then ConvertString = "" Else ConvertString = Left(strResult, Len(strResult) - 1) End If End Function
编辑:以下是我让它工作的代码,我知道它可能有点冗长,但我只是在学习VBA,当我学到更好的方法时,我会编辑这篇帖子,希望能帮助其他人。
Private Sub Worksheet_Change(ByVal Target As Range) Dim KeyCells As Range Dim str As String, result As String Dim RE As Object Dim allMatches As Object ' 变量KeyCells包含将 ' 在更改时引发警报的单元格。 Set KeyCells = Application.Union(Range("F3:F100"), Range("C3:C100"), Range("I3:I100")) Set RE = CreateObject("vbscript.regexp") If Not TypeName(Target.Value) = "Variant()" Then ' 现在我们要检查贝位以进行自动格式化 Set KeyCells = Application.Union(Range("A3:A100"), Range("D3:D100"), Range("G3:G100")) If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then RE.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})" RE.Global = True If Not Target.Value = "" And Not RE.test(Target.Value) Then str = CStr(Target.Value) str = FormatBay(str) Target.Value = str End If End If Set KeyCells = Application.Union(Range("B3:B100"), Range("E3:E100"), Range("H3:H100")) If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then RE.Pattern = "[a-z]?" RE.IgnoreCase = False If RE.test(Target.Value) Then Target.Value = UCase(Target.Value) End If End If Set KeyCells = Application.Union(Range("C3:C100"), Range("F3:F100"), Range("I3:I100")) If Not Application.Intersect(KeyCells, Range(Target.Address)) _ Is Nothing Then ' 当其中一个指定单元格已更改时显示消息。 ' 在这里放置你的代码。 str = ConvertString(Target) If (Not str = Target.Value And Not Target.Value = "") Then Target.Value = str End If End If End If End Sub Function FormatBay(ByVal text As String) As String Dim result As String, bayLetter As String, bayNumber As String Dim length As Integer, i As Integer Dim allMatches As Object Dim RE As Object Set RE = CreateObject("vbscript.regexp") RE.Pattern = "([0-9]?[a-z]{1,})\-?([0-9]{1,3})" RE.Global = True RE.IgnoreCase = True Set allMatches = RE.Execute(text) If Not allMatches.Count = 0 Then bayLocation = allMatches.Item(0).submatches.Item(0) bayLocation = UCase(bayLocation) bayNumber = allMatches.Item(0).submatches.Item(1) length = Len(bayNumber) For i = 1 To (3 - length) bayNumber = "0" & bayNumber Next result = bayLocation & "-" & bayNumber End If FormatBay = result End Function Function ConvertString(str1 As Range) As String Dim varStr As Variant Dim strSource As String, strResult As String Dim i As Integer For Each varStr In Split(Trim(str1.Value), " ") strSource = CStr(varStr) If InStr(strSource, ".") = 0 And IsNumeric(strSource) Then strResult = strResult & _ Mid(strSource, 1, 2) & "." & _ Mid(strSource, 3, 2) & "." & _ Mid(strSource, 5, 1) If Len(strSource) > 5 Then strResult = strResult & "(" For i = 6 To Len(strSource) strResult = strResult & Mid(strSource, i, 1) & "," Next i strResult = Left(strResult, Len(strResult) - 1) & ")" End If strResult = strResult & " " Else strResult = strResult & strSource & " " End If Next If strResult = "" Then ConvertString = "" Else ConvertString = Left(strResult, Len(strResult) - 1) End If End Function
VBA脚本曾经正常工作,但突然出现错误? 这个问题出现的原因是正则表达式的模式匹配错误。具体来说,正则表达式[a-z]?总是匹配成功。如果目标字符串Target.Value的第一个字符是小写字母,则正则表达式会将其匹配消耗掉。否则,它将在第一个字符之前匹配一个空字符串。虽然您正在测试小写字母的存在,但问号?的作用是使字母变为可选项,从而失去了测试的目的。
但我不明白为什么您需要进行这个测试。您不是要将所有字母都转换为大写吗?那么只需将字符串转换为大写,然后完成即可。或者等到转换完成后再使用UCase函数进行转换。
至于实际的转换,您的代码相当混乱,但我认为您做了很多不必要的工作。如果您单独处理像7a12这样的字符串,以下代码就足够了:
RE.Pattern = "^([0-9]?[A-Z]{1,})-?([0-9]{1,3})$"
RE.IgnoreCase = True
result = UCase(RE.Replace(source, "$1-$2"))
或者我是否遗漏了什么?
不,我只是不了解正则表达式对象的替换函数。我对VBA很新。