这是我第一次在这里发帖。我目前正在探索VBA,我想制作一个格式化电话号码并将其转换为标准格式的宏。应删除除数字和字母之外的所有特殊字符。我很抱歉我的英语不太好。这是一个例子。
场景必须如下所示,我选择一个范围,
8009228080
(900) (CAT) BABA
(+1) (900) (289) (9000)
900.900.9000
然后我点击分配宏的按钮然后它就像这样
800-922-8080
900-228-2222
900-289-9000
900-900-9000
输出必须只有### - ### - ####(3个数字' - '3个数字' - '4个数字) 信必须翻译成以下内容 ABC = 2,DEF = 3,GHI = 4,JKL = 5,MNO = 6,PQRS = 7,TUV = 8,WXYZ = 9 我试着查找它,这是我的尝试:
Sub PhoneFormat()
Dim StSel As Range
Dim EndSel As Range
On Error Resume Next
xTitleId = "Format Phone Numbers"
Set EndSel = Application.Selection
Set EndSel = Application.InputBox("Range", xTitleId, EndSel.Address, Type:=8)
我想更改此部分,因为我想首先选择范围,然后单击按钮然后应用宏
For Each StSel In EndSel
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, "+", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, "+1", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, "-", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, ".", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, "(", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, ")", "")
StSel.Value = Application.WorksheetFunction.Substitute(StSel.Value, " ", "")
If (Len(StSel) > 10) Then
StSel = Right(StSel, 10)
End If
StSel = Left(StSel, 3) & "-" & Mid(StSel, 4, 3) & "-" & Right(StSel, 4)
Next
End Sub
我认为这可以优化为更简单的代码,但我不能这样做。此代码也无法将字母替换为数字。在此先感谢,我希望有人能回答这个问题。
答案 0 :(得分:2)
以下是使用正则表达式执行此操作的示例:
Option Explicit
Public Sub test()
Debug.Print FormatWithRegEx("(900) (CAT) BABA")
Debug.Print FormatWithRegEx("(+1) (900) (289) (9000)")
Debug.Print FormatWithRegEx("900.900.9000")
Debug.Print ReplaceCharactersWithRegEx(FormatWithRegEx("(900) (CAT) BABA"))
'or dircetly implement ReplaceCharactersWithRegEx in FormatWithRegEx
End Sub
Public Function FormatWithRegEx(InputString As String) As String
Dim objRegEx As Object
Set objRegEx = CreateObject("vbscript.regexp")
Dim arrPatterns() As Variant
arrPatterns = Array( _
"([A-Z0-9]{10})", _
"\(?([A-Z0-9]{3})\)? \(?([A-Z0-9]{3})\)? \(?([A-Z0-9]{4})\)?", _
"([A-Z0-9]{3})\.([A-Z0-9]{3})\.([A-Z0-9]{4})" _
)
Dim Pattern As Variant
For Each Pattern In arrPatterns
With objRegEx
.Global = True
.IgnoreCase = True
.MultiLine = False
.Pattern = Pattern
Dim objMatches As Object
Set objMatches = .Execute(InputString)
End With
If objMatches.Count = 1 Then
With objMatches(0)
If .SubMatches.Count = 3 Then
FormatWithRegEx= .SubMatches(0) & "-" & .SubMatches(1) & "-" & .SubMatches(2)
End If
End With
End If
If FormatWithRegEx <> vbNullString Then Exit For
Next Pattern
'to implement ReplaceCharactersWithRegEx uncomment …
'FormatWithRegEx = ReplaceCharactersWithRegEx(FormatWithRegEx)
End Function
它识别测试中的3种给定模式。从字符到数字的翻译仍然需要完成。
这是一个纯RegEx替换示例
Public Function ReplaceCharactersWithRegEx(InputString As String) As String
InputString = RegExReplace(InputString, "[ABC]{1}", "2")
InputString = RegExReplace(InputString, "[DEF]{1}", "3")
InputString = RegExReplace(InputString, "[GHI]{1}", "4")
InputString = RegExReplace(InputString, "[JKL]{1}", "5")
InputString = RegExReplace(InputString, "[MNO]{1}", "6")
InputString = RegExReplace(InputString, "[PQRS]{1}", "7")
InputString = RegExReplace(InputString, "[TUV]{1}", "8")
InputString = RegExReplace(InputString, "[WXYZ]{1}", "9")
ReplaceCharactersWithRegEx = InputString
End Function
Private Function RegExReplace(InputString, Pattern, Replace) As String
Dim objRegEx As Object
Set objRegEx = CreateObject("vbscript.regexp")
With objRegEx
.Global = True
.IgnoreCase = True
.MultiLine = False
.Pattern = Pattern
Dim objMatches As Object
Set objMatches = .Execute(InputString)
End With
RegExReplace = objRegEx.Replace(InputString, Replace)
End Function
//编辑
使其对.IgnoreCase = True
// EDIT2
选择循环示例
Dim cl As Range
For Each cl In Selection 'instead of Selection you can also use a defined Range("A1:A50")
Dim FormattedValue As String
FormattedValue = FormatWithRegEx(cl.value)
If FormattedValue <> vbNullString Then 'don't delete if formatting wasn't successful
cl.value = FormatWithRegEx(cl.value)
End If
Next cl
答案 1 :(得分:1)
采取PEH的回答并添加字母转换为数字:
Option Explicit
Public Sub test()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
Dim rng As Range
Dim cell As Range
Set rng = Selection
For Each cell In rng
cell.Value = ConvertLetters(FormatWithRegEx(cell.Value))
Next
End Sub
Public Function ConvertLetters(FormattedString As String) As String
Dim J As Long, Digit As Variant
For J = 1 To Len(FormattedString)
Digit = UCase(Mid(FormattedString, J, 1))
Select Case Digit
Case "A" To "P"
Digit = Chr((Asc(Digit) + 1) \ 3 + 28)
Case "Q"
Digit = "7"
Case "R" To "Y"
Digit = Chr(Asc(Digit) \ 3 + 28)
Case "Z"
Digit = "9"
End Select
Mid(FormattedString, J, 1) = Digit
Next J
ConvertLetters = FormattedString
End Function
Public Function FormatWithRegEx(InputString As String) As String
Dim objRegEx As Object
Set objRegEx = CreateObject("vbscript.regexp")
Dim arrPatterns() As Variant
arrPatterns = Array( _
"\(([a-zA-Z0-9]{3})\) \(([a-zA-Z0-9]{3})\) ([a-zA-Z0-9]{4})", _
"\(([a-zA-Z0-9]{3})\) \(([a-zA-Z0-9]{3})\) \(([a-zA-Z0-9]{4})\)", _
"([a-zA-Z0-9]{3})\.([a-zA-Z0-9]{3})\.([a-zA-Z0-9]{4})" _
)
Dim Pattern As Variant
For Each Pattern In arrPatterns
With objRegEx
.Global = True
.IgnoreCase = True
.MultiLine = False
.Pattern = Pattern
Dim objMatches As Object
Set objMatches = .Execute(InputString)
End With
If objMatches.Count = 1 Then
With objMatches(0)
If .SubMatches.Count = 3 Then
FormatWithRegEx = .SubMatches(0) & "-" & .SubMatches(1) & "-" & .SubMatches(2)
End If
End With
End If
If FormatWithRegEx <> vbNullString Then Exit For
Next Pattern
End Function
<强>更新强>
以下内容将格式化您在评论中表达的电话号码(选择Thom的回答并添加选择):
Sub PhoneFormat()
Dim myLen As Long
Dim i As Long
Dim myNum As String
Dim newNum
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
Dim rng As Range
Dim cell As Range
Set rng = Selection
For Each cell In rng
' Loop through characters, converting values
If Len(cell.Value) > 0 Then
For i = 1 To Len(cell.Value)
Select Case Mid(cell.Value, i, 1)
Case "0"
myNum = "0"
Case "1"
myNum = "1"
Case "2"
myNum = "2"
Case "3"
myNum = "3"
Case "4"
myNum = "4"
Case "5"
myNum = "5"
Case "6"
myNum = "6"
Case "7"
myNum = "7"
Case "8"
myNum = "8"
Case "9"
myNum = "9"
Case "A", "B", "C", "a", "b", "c"
myNum = "2"
Case "D", "E", "F", "d", "e", "f"
myNum = "3"
Case "G", "H", "I", "g", "h", "i"
myNum = "4"
Case "J", "K", "L", "j", "k", "l"
myNum = "5"
Case "M", "N", "O", "m", "n", "o"
myNum = "6"
Case "P", "Q", "R", "S", "p", "q", "r", "s"
myNum = "7"
Case "T", "U", "V", "t", "u", "v"
myNum = "8"
Case "W", "X", "Y", "Z", "w", "x", "y", "z"
myNum = "9"
Case " ", "-", "."
myNum = "-"
Case Else
myNum = ""
End Select
newNum = newNum & myNum
Next i
End If
cell.Value = Right(newNum, 12)
Next
End Sub
答案 2 :(得分:0)
我现在已经修改了脚本以使用选定的范围,它也将转换所有给定的示例。
对于其他可能对某些人有用的目的,阅读和修改很简单,这就是我发布它的原因。
该脚本使用Case Else删除未定义的字符,转换所需的字符。
Sub PhoneFormatRange()
Dim myLen As Long
Dim i As Long
Dim myNum As String
Dim newNum As String
Dim selectedRng As Range
Dim celRng As Range
Dim strLeft As String
Dim strMid As String
Dim strRight As String
' Find the Selected Range and for each cell in the selected range run the cade and repeat.
Set selectedRng = Application.Selection
For Each celRng In selectedRng.Cells
' Convert Cell value to an array
myLen = Len(celRng.Value)
ReDim Carray(Len(celRng.Value))
For i = 0 To myLen
Carray(i) = Mid(celRng.Value, i + 1, 1)
Next
' Loop through array, converting values
If myLen > 0 Then
For i = 0 To myLen
Select Case Carray(i)
Case "0"
myNum = "0"
Case "1"
myNum = "1"
Case "2"
myNum = "2"
Case "3"
myNum = "3"
Case "4"
myNum = "4"
Case "5"
myNum = "5"
Case "6"
myNum = "6"
Case "7"
myNum = "7"
Case "8"
myNum = "8"
Case "9"
myNum = "9"
Case "A", "B", "C", "a", "b", "c"
myNum = "2"
Case "D", "E", "F", "d", "e", "f"
myNum = "3"
Case "G", "H", "I", "g", "h", "i"
myNum = "4"
Case "J", "K", "L", "j", "k", "l"
myNum = "5"
Case "M", "N", "O", "m", "n", "o"
myNum = "6"
Case "P", "Q", "R", "S", "p", "q", "r", "s"
myNum = "7"
Case "T", "U", "V", "t", "u", "v"
myNum = "8"
Case "W", "X", "Y", "Z", "w", "x", "y", "z"
myNum = "9"
Case " ", "-", "."
myNum = "-"
Case Else
myNum = ""
End Select
newNum = newNum & myNum
Next i
End If
' Check the length of the string and if it requals 10 then add the hypens
If Len(newNum) = 10 Then
strLeft = Left(newNum, 3)
strMid = Mid(newNum, 4, 3)
strRight = Right(newNum, 4)
newNum = strLeft & "-" & strMid & "-" & strRight
End If
' Set the cell value within the range to 12 right most characters of the string
celRng.Value = Right(newNum, 12)
' Clear newNum before repeating
newNum = ""
' Go back to celRng and repeat until all the cells within the selection is complete
Next celRng
End Sub
答案 3 :(得分:0)
我也正在写PEH的正则表达式。但我的方法有点不同。只发布它,因为编写这篇文章很有趣,它可能会有所帮助。 我还使用了Xabiers ConvertLetters函数,因为它做得很好而且代码是一个非常好的方法。
我对正则表达式的处理方法是在一个表达式中匹配所有标准。所以我定义的模式找到了你所有定义的可能性。这迫使我做了一些额外的替换,但我稍微扩展了Xabiers代码。
Sub correctNumbers()
Dim i As Long, J As Long
Dim sEXP As String
Dim rng As Range
Dim oRegEx As Object, oMatch As Object
' create object for regular expressions
Set oRegEx = CreateObject("vbscript.regexp")
' supposed you have a sheet called "Sheet1" - change sheetname and range according to your needs
Set rng = ThisWorkbook.Sheets("Sheet1").Range("A2:A4")
' run through every entry in range
For i = 1 To rng.Rows.Count
With oRegEx
.Global = True
.IgnoreCase = False
' define pattern as desribed by you needs
.Pattern = "([\(]?[0-9]{3}[\)]?[\s\.]?[\(]?[A-Z0-9]{3}[\)]?[\s\.]?[\(]?[A-Z0-9]{4}[\)]?)"
Set oMatch = .Execute(rng(i, 1).Value)
If oMatch.Count <> 0 Then
sEXP = oMatch(0)
If Len(sEXP) = 10 Then
sEXP = Left(sEXP, 3) & "-" & Right(Left(sEXP, 6), 3) & "-" & Right(sEXP, 4)
Else
sEXP = ConvertLetters(oMatch(0))
End If
Else
sEXP = ""
End If
End With
' write result in column B
ThisWorkbook.Sheets("Sheet1").Range("B" & i + 1).Value = sEXP
Next i
End Sub
Public Function ConvertLetters(FormattedString As String) As String
Dim J As Long, Digit As Variant
For J = 1 To Len(FormattedString)
Digit = UCase(Mid(FormattedString, J, 1))
Select Case Digit
Case "A" To "P"
Digit = Chr((Asc(Digit) + 1) \ 3 + 28)
Case "Q"
Digit = "7" 'May want to change
Case "R" To "Y"
Digit = Chr(Asc(Digit) \ 3 + 28)
Case "Z"
Digit = "9" 'May want to change
' added as my regular expression finds complete number including dots, spaces and braces
Case ".", " "
Digit = "-"
End Select
Mid(FormattedString, J, 1) = Digit
Next J
' added repalce as my regular expression finds complete number including dots, spaces and braces
ConvertLetters = Replace(Replace(FormattedString, "(", ""), ")", "")
End Function