我在 Excel 工作表上的以下代码。我正在使用 VBA 更改某些单元格的内容,以便为我的工作正确格式化它们。我们保留了损坏、托架位置和 VIN 的列表。这些列中的每一列都有自己特定的格式,其中 2 列我工作得很好。你们中的一些人可能会从我的另一篇关于正确格式化损坏代码的帖子中认出其中的一些代码。列是这样排序的
Bay Location | VIN | Damage Code(s)
对于 VIN,我们所做的只是大写字母。很简单,搞定了。损坏代码功能在我对其进行了一些更改以更好地满足我的需求后完美运行。如果没有我在这里收到的原始帮助,就无法做到这一点。这就是事情变得奇怪的地方,我的老板,看到我已经让它为损坏代码工作,让我让它自动格式化托架。我工作的海湾位置有几种可能性,但前面总是至少有 1 个字母,例如
- H-5
- H-125
- HH-50
- 7A-70
- FNCE-13
在英语中,我要做的是:输入无格式的bay,例如7a12,大写字母,用数字分割,并在两组之间添加破折号,瞧。
我有这个工作,甚至把它展示给我的老板。但后来我在代码中添加了大写的 VIN 列,我开始收到错误,突出显示该行
Set allMatches = RE1.Execute(strSource)
RE1.test(strSource) 运行良好,但现在尝试获取匹配项/子匹配项会神秘地引发错误。我最初使用This StackOverflow question中的文本来使其正常工作。我得到的错误类似于告诉我对象未设置。我知道代码目前一团糟,我不得不中途离开(我的函数可能有问题,不,直接从原始子函数运行时出现同样的错误)。
编辑:错误如下
运行时错误“91”对象变量或未设置块变量
再次强调
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
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
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
' Display a message when one of the designated cells has been
' changed.
' Place your code here.
str = ConvertString(Target)
If (Not str = Target.Value And Not Target.Value = "") Then
Target.Value = str
End If
End If
' Now we have to check the bays in order to auto format
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
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
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
' Now we have to check the bays in order to auto format
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
' Display a message when one of the designated cells has been
' changed.
' Place your code here.
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