VBA - 针对工作代码中的特定错误抛出异常,IsNumeric 问题?
VBA - throwing exceptions for specific errors in working code, IsNumeric issue?
如果标题含糊不清,我深表歉意。我不知道如何引用这个问题。
我有代码强制任何 TL 值的长度为 "TL-" 之后的 6 个数字的长度,并且对 CT 值执行相同的长度为 "CT-" 之后的 4 个数字的长度。如果太短,则在"TL-"后加0;如果太长,则在 "TL-".
之后删除 0
TL- 0012 -> TL-000012
TL-0008981 -> TL-008981
TL - 008 -> TL-000008
代码在找到字符串 "TL" 后获取 6 个数字,将 "TL-" 放入单元格,然后将六个数字放入。我 运行 遇到了一些我没有成功解决的问题。
主要问题:
如果存在更多数字,它将获取所有这些数字。
出现的其他故障排除问题之一是,如果有另一个 TL 值,它会抓取所有数字并将其相加。现在,它将看到字符串 "TL" 第二次出现,并删除它和它后面的任何内容。我希望对其他问题应用相同类型的修复。
示例输出:
Start: Output:
TL-000487 #3 5/7" Cutter TL-487357
TL-000037(N123t3-01) TL-37123301
TL-000094 CTAT15123 TL-9415123
TL-000187 TL-00017 TL-000678 TL-000187
TL-000205 TL-000189 TL-000205
TL-000996:.096 REAMER TL-996096
TL-002313-(MF-4965) TL-23134965
期望输出:
Start: Output:
TL-000487 #3 5/7" Cutter TL-000487
TL-000037(N123t3-01) TL-000037
TL-000094 CTAT15123 TL-000094
TL-000187 TL-00017 TL-000678 TL-000187
TL-000205 TL-000189 TL-000205
TL-000996:.096 REAMER TL-000996
TL-002313-(MF-4965) TL-002313
如果有人可以帮助我解决这些问题,我会发现它提供的信息最丰富,也最有帮助。
代码:
'force length of TL/CT to be 6/4 numbers long, eliminate spaces
Dim str As String, ret As String, tmp As String, j As Integer, k As Integer
For k = 2 To StartSht.Range("C2").End(xlDown).Row
ret = ""
str = StartSht.Range("C" & k).Value
'for TL numbers
If InStr(str, "TL") > 0 Then
'if more than one TL value, delete everything after the first TL number
If InStr(3, str, "TL") > 0 Then str = Mid(str, 1, InStr(3, str, "TL") - 2)
For j = 1 To Len(str)
tmp = Mid(str, j, 1)
If IsNumeric(tmp) Then ret = ret + tmp
Next j
'force to 6 numbers if too short; add 0s immediately after "TL-"
For j = Len(ret) + 1 To 6
ret = "0" & ret
Next j
'force to 6 numbers if too long; eliminate 0s immediately after "TL-"
If Len(ret) > 6 Then
Debug.Print Len(ret)
For j = Len(ret) To 7 Step -1
If Mid(ret, 1, 1) = "0" Then
ret = Right(ret, j - 1)
End If
Next j
End If
'eliminate superfluous spaces around "TL-"
ret = "TL-" & ret
StartSht.Range("C" & k).Value = ret
'for CT numbers
ElseIf InStr(str, "CT") > 0 Then
For j = 1 To Len(str)
tmp = Mid(str, j, 1)
If IsNumeric(tmp) Then ret = ret + tmp
Next j
'force to 4 numbers if too short; add 0s immediately after "CT-"
For j = Len(ret) + 1 To 4
ret = "0" & ret
Next j
'force to 4 numbers if too long; eliminate 0s immediately after "CT-"
If Len(ret) > 4 Then
Debug.Print Len(ret)
For j = Len(ret) To 5 Step -1
If Mid(ret, 1, 1) = "0" Then
ret = Right(ret, j - 1)
End If
Next j
End If
'eliminate superfluous spaces around "CT-"
ret = "CT-" & ret
StartSht.Range("C" & k).Value = ret
End If
Next k
编辑:
CT 问题
现在
Start: Output:
CT-0087 (TC-7988) CT-0087
CT-0067-02 CT-0067
CT-0076-REV01 CT-0076
CT-0098-1 A CT-0098
我希望它是
Start: Desired Output:
CT-0087 (TC-7988) CT-0087
CT-0067-02 CT-0067-02
CT-0076-REV01 CT-0076-01
CT-0098-1 A CT-0098-1
所以应该总是有一个“-”和最多 2 个数字可以抓取,但我只希望它在破折号紧随其后时抓取它(CT-0087 (TC-7988) 不应该CT-0087-79),我不知道如何针对该特定问题抛出异常。想法?
如果 TL-###### 始终是您可以使用的前九个字符。
如果破折号不是第 3 个字符,我已对其进行了一些更改。
Dim iIndex As Integer
'If there is a space between TL and - "TL -" let's get rid of it.
iIndex = InStr(str, " ")
If iIndex = 3 Then
str = Replace(str, " ", "", 1, 1)
End If
If Left(str, 2) = "TL" Then
TL = Left(str, 9)
TL = padZeros(TL, 6)
StartSht.Range("C" & k).Value = TL
ElseIf Left(str, 2) = "CT" Then
CT = Left(str, 7)
CT = padZeros(CT, 4)
StartSht.Range("C" & k).Value = CT
Else
MessageBox.Show ("We got a string we didn't expect.")
End If
为您的短号码添加一个函数,例如
Function padZeros(szinput As String, lenght As Integer) As String
Dim temp As String
temp = Trim(Right(szinput, 6))
temp = Replace(temp, "-", "")
temp = Replace(temp, " ", "")
szinput = Left(szinput, 3)
Do While lenght > Len(temp)
temp = "0" & temp
Loop
padZeros = szinput & temp
End Function
有几件事我会采取不同的做法。
- 我会将
Instr
函数的结果存储在一个变量中
- 当您找到第一个 "TL" 条目时,您会将这些字符保留为答案的一部分。但这意味着您需要担心文本和数字之间的空格和连字符。我会寻找第一个 "TL" 然后从那个位置看连续的字符寻找第一个数字。这是您号码的开头。该字符之前的任何内容都应删除。
- 要用前导零格式化数字,您可以使用
Format$
函数。要删除前导零,您可以使用 CLng
. 将字符串转换为长整数
- 看起来您稍后在查找 "CT" 时可能需要类似的代码,所以我建议创建一个 returns 数字的函数。
函数如下:
Public Function ExtractNumberWithLeadingZeroes(ByRef theWholeText As String, ByRef idText As String, ByRef numCharsRequired As Integer) As String
' Finds the first entry of idText in theWholeText
' Returns the first number found after idText formatted
' with leading zeroes
Dim i As Integer
Dim j As Integer
Dim thisChar As String
Dim returnValue As String
Dim tmpText As String
Dim firstPosn As Integer
Dim secondPosn As Integer
returnValue = ""
firstPosn = InStr(1, theWholeText, idText)
If firstPosn > 0 Then
' remove any text before first idText, also remove the first idText
tmpText = Mid(theWholeText, firstPosn + Len(idText))
'if more than one idText value, delete everything after (and including) the second idText
secondPosn = InStr(1, tmpText, idText)
If secondPosn > 0 Then
tmpText = Mid(tmpText, 1, secondPosn)
End If
' Find first number
For j = 1 To Len(tmpText)
If IsNumeric(Mid(tmpText, j, 1)) Then
tmpText = Mid(tmpText, j)
Exit For
End If
Next j
' Find where the numbers end
returnValue = tmpText
For j = 1 To Len(returnValue)
thisChar = Mid(returnValue, j, 1)
If Not IsNumeric(thisChar) Then
returnValue = Mid(returnValue, 1, j - 1)
Exit For
End If
Next j
'force to numCharsRequired numbers if too short; add 0s immediately after idText
'force to numCharsRequired numbers if too long; eliminate 0s immediately after idText
' The CLng gets rid of leading zeroes and the Format$ adds any required up to numCharsRequired chars
returnValue = Format$(CLng(returnValue), String(numCharsRequired, "0"))
End If
ExtractNumberWithLeadingZeroes = returnValue
End Function
你可以这样调用这个函数:
ret = ExtractNumberWithLeadingZeroes(str, "TL", 6)
你会得到类似“000487”的信息。
您的原始代码块变为:
'force length of TL/CT to be 6/4 numbers long, eliminate spaces
Dim str As String, ret As String, k As Integer
For k = 2 To StartSht.Range("C2").End(xlDown).Row
ret = ""
str = StartSht.Range("C" & k).Value
ret = ExtractNumberWithLeadingZeroes(str, "TL", 6)
If ret <> "" Then
StartSht.Range("C" & k).Value = "TL-" & ret
Else
'for CT numbers
ret = ExtractNumberWithLeadingZeroes(str, "CT", 4)
If ret <> "" Then
StartSht.Range("C" & k).Value = "CT-" & ret
End If
End If
Next k
编辑:OP 澄清了他的立场,所以我重写了 ExtractNumberWithLeadingZeroes
函数并在下面包含了新版本:
Public Function ExtractNumberWithLeadingZeroes(ByRef theWholeText As String, ByRef idText As String, ByRef numCharsRequired As Integer) As String
' Finds the first entry of idText in theWholeText
' Returns the first number found after idText formatted
' with leading zeroes
Dim returnValue As String
Dim extraValue As String
Dim tmpText As String
Dim firstPosn As Integer
Dim secondPosn As Integer
Dim ctNumberPosn As Integer
returnValue = ""
firstPosn = InStr(1, theWholeText, idText)
If firstPosn > 0 Then
' remove any text before first idText, also remove the first idText
tmpText = Mid(theWholeText, firstPosn + Len(idText))
'if more than one idText value, delete everything after (and including) the second idText
secondPosn = InStr(1, tmpText, idText)
If secondPosn > 0 Then
tmpText = Mid(tmpText, 1, secondPosn)
End If
returnValue = ExtractTheFirstNumericValues(tmpText, 1)
If idText = "CT" Then
ctNumberPosn = InStr(1, tmpText, returnValue)
' Is the next char a dash? If so, must include more numbers
If Mid(tmpText, ctNumberPosn + Len(returnValue), 1) = "-" Then
' There are some more numbers, after the dash, to extract
extraValue = ExtractTheFirstNumericValues(tmpText, ctNumberPosn + Len(returnValue))
End If
End If
'force to numCharsRequired numbers if too short; add 0s immediately after idText
'force to numCharsRequired numbers if too long; eliminate 0s immediately after idText
' The CLng gets rid of leading zeroes and the Format$ adds any required up to numCharsRequired chars
If returnValue <> "" Then
returnValue = Format$(CLng(returnValue), String(numCharsRequired, "0"))
If extraValue <> "" Then
returnValue = returnValue & "-" & extraValue
End If
End If
End If
ExtractNumberWithLeadingZeroes = returnValue
End Function
Private Function ExtractTheFirstNumericValues(ByRef theText As String, ByRef theStartingPosition As Integer) As String
Dim i As Integer
Dim j As Integer
Dim tmpText As String
Dim thisChar As String
' Find first number
For i = theStartingPosition To Len(theText)
If IsNumeric(Mid(theText, i, 1)) Then
tmpText = Mid(theText, i)
Exit For
End If
Next i
' Find where the numbers end
For j = 1 To Len(tmpText)
thisChar = Mid(tmpText, j, 1)
If Not IsNumeric(thisChar) Then
tmpText = Mid(tmpText, 1, j - 1)
Exit For
End If
Next j
ExtractTheFirstNumericValues = tmpText
End Function
如果标题含糊不清,我深表歉意。我不知道如何引用这个问题。
我有代码强制任何 TL 值的长度为 "TL-" 之后的 6 个数字的长度,并且对 CT 值执行相同的长度为 "CT-" 之后的 4 个数字的长度。如果太短,则在"TL-"后加0;如果太长,则在 "TL-".
之后删除 0TL- 0012 -> TL-000012
TL-0008981 -> TL-008981
TL - 008 -> TL-000008
代码在找到字符串 "TL" 后获取 6 个数字,将 "TL-" 放入单元格,然后将六个数字放入。我 运行 遇到了一些我没有成功解决的问题。
主要问题: 如果存在更多数字,它将获取所有这些数字。
出现的其他故障排除问题之一是,如果有另一个 TL 值,它会抓取所有数字并将其相加。现在,它将看到字符串 "TL" 第二次出现,并删除它和它后面的任何内容。我希望对其他问题应用相同类型的修复。
示例输出:
Start: Output:
TL-000487 #3 5/7" Cutter TL-487357
TL-000037(N123t3-01) TL-37123301
TL-000094 CTAT15123 TL-9415123
TL-000187 TL-00017 TL-000678 TL-000187
TL-000205 TL-000189 TL-000205
TL-000996:.096 REAMER TL-996096
TL-002313-(MF-4965) TL-23134965
期望输出:
Start: Output:
TL-000487 #3 5/7" Cutter TL-000487
TL-000037(N123t3-01) TL-000037
TL-000094 CTAT15123 TL-000094
TL-000187 TL-00017 TL-000678 TL-000187
TL-000205 TL-000189 TL-000205
TL-000996:.096 REAMER TL-000996
TL-002313-(MF-4965) TL-002313
如果有人可以帮助我解决这些问题,我会发现它提供的信息最丰富,也最有帮助。
代码:
'force length of TL/CT to be 6/4 numbers long, eliminate spaces
Dim str As String, ret As String, tmp As String, j As Integer, k As Integer
For k = 2 To StartSht.Range("C2").End(xlDown).Row
ret = ""
str = StartSht.Range("C" & k).Value
'for TL numbers
If InStr(str, "TL") > 0 Then
'if more than one TL value, delete everything after the first TL number
If InStr(3, str, "TL") > 0 Then str = Mid(str, 1, InStr(3, str, "TL") - 2)
For j = 1 To Len(str)
tmp = Mid(str, j, 1)
If IsNumeric(tmp) Then ret = ret + tmp
Next j
'force to 6 numbers if too short; add 0s immediately after "TL-"
For j = Len(ret) + 1 To 6
ret = "0" & ret
Next j
'force to 6 numbers if too long; eliminate 0s immediately after "TL-"
If Len(ret) > 6 Then
Debug.Print Len(ret)
For j = Len(ret) To 7 Step -1
If Mid(ret, 1, 1) = "0" Then
ret = Right(ret, j - 1)
End If
Next j
End If
'eliminate superfluous spaces around "TL-"
ret = "TL-" & ret
StartSht.Range("C" & k).Value = ret
'for CT numbers
ElseIf InStr(str, "CT") > 0 Then
For j = 1 To Len(str)
tmp = Mid(str, j, 1)
If IsNumeric(tmp) Then ret = ret + tmp
Next j
'force to 4 numbers if too short; add 0s immediately after "CT-"
For j = Len(ret) + 1 To 4
ret = "0" & ret
Next j
'force to 4 numbers if too long; eliminate 0s immediately after "CT-"
If Len(ret) > 4 Then
Debug.Print Len(ret)
For j = Len(ret) To 5 Step -1
If Mid(ret, 1, 1) = "0" Then
ret = Right(ret, j - 1)
End If
Next j
End If
'eliminate superfluous spaces around "CT-"
ret = "CT-" & ret
StartSht.Range("C" & k).Value = ret
End If
Next k
编辑: CT 问题
现在
Start: Output:
CT-0087 (TC-7988) CT-0087
CT-0067-02 CT-0067
CT-0076-REV01 CT-0076
CT-0098-1 A CT-0098
我希望它是
Start: Desired Output:
CT-0087 (TC-7988) CT-0087
CT-0067-02 CT-0067-02
CT-0076-REV01 CT-0076-01
CT-0098-1 A CT-0098-1
所以应该总是有一个“-”和最多 2 个数字可以抓取,但我只希望它在破折号紧随其后时抓取它(CT-0087 (TC-7988) 不应该CT-0087-79),我不知道如何针对该特定问题抛出异常。想法?
如果 TL-###### 始终是您可以使用的前九个字符。
如果破折号不是第 3 个字符,我已对其进行了一些更改。
Dim iIndex As Integer
'If there is a space between TL and - "TL -" let's get rid of it.
iIndex = InStr(str, " ")
If iIndex = 3 Then
str = Replace(str, " ", "", 1, 1)
End If
If Left(str, 2) = "TL" Then
TL = Left(str, 9)
TL = padZeros(TL, 6)
StartSht.Range("C" & k).Value = TL
ElseIf Left(str, 2) = "CT" Then
CT = Left(str, 7)
CT = padZeros(CT, 4)
StartSht.Range("C" & k).Value = CT
Else
MessageBox.Show ("We got a string we didn't expect.")
End If
为您的短号码添加一个函数,例如
Function padZeros(szinput As String, lenght As Integer) As String
Dim temp As String
temp = Trim(Right(szinput, 6))
temp = Replace(temp, "-", "")
temp = Replace(temp, " ", "")
szinput = Left(szinput, 3)
Do While lenght > Len(temp)
temp = "0" & temp
Loop
padZeros = szinput & temp
End Function
有几件事我会采取不同的做法。
- 我会将
Instr
函数的结果存储在一个变量中 - 当您找到第一个 "TL" 条目时,您会将这些字符保留为答案的一部分。但这意味着您需要担心文本和数字之间的空格和连字符。我会寻找第一个 "TL" 然后从那个位置看连续的字符寻找第一个数字。这是您号码的开头。该字符之前的任何内容都应删除。
- 要用前导零格式化数字,您可以使用
Format$
函数。要删除前导零,您可以使用CLng
. 将字符串转换为长整数
- 看起来您稍后在查找 "CT" 时可能需要类似的代码,所以我建议创建一个 returns 数字的函数。
函数如下:
Public Function ExtractNumberWithLeadingZeroes(ByRef theWholeText As String, ByRef idText As String, ByRef numCharsRequired As Integer) As String
' Finds the first entry of idText in theWholeText
' Returns the first number found after idText formatted
' with leading zeroes
Dim i As Integer
Dim j As Integer
Dim thisChar As String
Dim returnValue As String
Dim tmpText As String
Dim firstPosn As Integer
Dim secondPosn As Integer
returnValue = ""
firstPosn = InStr(1, theWholeText, idText)
If firstPosn > 0 Then
' remove any text before first idText, also remove the first idText
tmpText = Mid(theWholeText, firstPosn + Len(idText))
'if more than one idText value, delete everything after (and including) the second idText
secondPosn = InStr(1, tmpText, idText)
If secondPosn > 0 Then
tmpText = Mid(tmpText, 1, secondPosn)
End If
' Find first number
For j = 1 To Len(tmpText)
If IsNumeric(Mid(tmpText, j, 1)) Then
tmpText = Mid(tmpText, j)
Exit For
End If
Next j
' Find where the numbers end
returnValue = tmpText
For j = 1 To Len(returnValue)
thisChar = Mid(returnValue, j, 1)
If Not IsNumeric(thisChar) Then
returnValue = Mid(returnValue, 1, j - 1)
Exit For
End If
Next j
'force to numCharsRequired numbers if too short; add 0s immediately after idText
'force to numCharsRequired numbers if too long; eliminate 0s immediately after idText
' The CLng gets rid of leading zeroes and the Format$ adds any required up to numCharsRequired chars
returnValue = Format$(CLng(returnValue), String(numCharsRequired, "0"))
End If
ExtractNumberWithLeadingZeroes = returnValue
End Function
你可以这样调用这个函数:
ret = ExtractNumberWithLeadingZeroes(str, "TL", 6)
你会得到类似“000487”的信息。
您的原始代码块变为:
'force length of TL/CT to be 6/4 numbers long, eliminate spaces
Dim str As String, ret As String, k As Integer
For k = 2 To StartSht.Range("C2").End(xlDown).Row
ret = ""
str = StartSht.Range("C" & k).Value
ret = ExtractNumberWithLeadingZeroes(str, "TL", 6)
If ret <> "" Then
StartSht.Range("C" & k).Value = "TL-" & ret
Else
'for CT numbers
ret = ExtractNumberWithLeadingZeroes(str, "CT", 4)
If ret <> "" Then
StartSht.Range("C" & k).Value = "CT-" & ret
End If
End If
Next k
编辑:OP 澄清了他的立场,所以我重写了 ExtractNumberWithLeadingZeroes
函数并在下面包含了新版本:
Public Function ExtractNumberWithLeadingZeroes(ByRef theWholeText As String, ByRef idText As String, ByRef numCharsRequired As Integer) As String
' Finds the first entry of idText in theWholeText
' Returns the first number found after idText formatted
' with leading zeroes
Dim returnValue As String
Dim extraValue As String
Dim tmpText As String
Dim firstPosn As Integer
Dim secondPosn As Integer
Dim ctNumberPosn As Integer
returnValue = ""
firstPosn = InStr(1, theWholeText, idText)
If firstPosn > 0 Then
' remove any text before first idText, also remove the first idText
tmpText = Mid(theWholeText, firstPosn + Len(idText))
'if more than one idText value, delete everything after (and including) the second idText
secondPosn = InStr(1, tmpText, idText)
If secondPosn > 0 Then
tmpText = Mid(tmpText, 1, secondPosn)
End If
returnValue = ExtractTheFirstNumericValues(tmpText, 1)
If idText = "CT" Then
ctNumberPosn = InStr(1, tmpText, returnValue)
' Is the next char a dash? If so, must include more numbers
If Mid(tmpText, ctNumberPosn + Len(returnValue), 1) = "-" Then
' There are some more numbers, after the dash, to extract
extraValue = ExtractTheFirstNumericValues(tmpText, ctNumberPosn + Len(returnValue))
End If
End If
'force to numCharsRequired numbers if too short; add 0s immediately after idText
'force to numCharsRequired numbers if too long; eliminate 0s immediately after idText
' The CLng gets rid of leading zeroes and the Format$ adds any required up to numCharsRequired chars
If returnValue <> "" Then
returnValue = Format$(CLng(returnValue), String(numCharsRequired, "0"))
If extraValue <> "" Then
returnValue = returnValue & "-" & extraValue
End If
End If
End If
ExtractNumberWithLeadingZeroes = returnValue
End Function
Private Function ExtractTheFirstNumericValues(ByRef theText As String, ByRef theStartingPosition As Integer) As String
Dim i As Integer
Dim j As Integer
Dim tmpText As String
Dim thisChar As String
' Find first number
For i = theStartingPosition To Len(theText)
If IsNumeric(Mid(theText, i, 1)) Then
tmpText = Mid(theText, i)
Exit For
End If
Next i
' Find where the numbers end
For j = 1 To Len(tmpText)
thisChar = Mid(tmpText, j, 1)
If Not IsNumeric(thisChar) Then
tmpText = Mid(tmpText, 1, j - 1)
Exit For
End If
Next j
ExtractTheFirstNumericValues = tmpText
End Function