我对VBA还是很陌生,但总体而言不是编程。我试图在VBA中创建一个宏,以将电话名称列表的型号名称格式化为可管理的格式。例如。我想要以下名称:
P10,12.9厘米(5.1英寸),4 GB,64 GB,20 MP
要设置为
P10 5.1英寸64 GB
我已经成功使用Split
和Mid
提取了格式化名称的前两个元素。
这是我前两个部分的代码:
'First part of format
firstPart = Trim(Split(modelName, ",")(0))
Debug.Print formattedModelName
'Second part of format
openPos = InStr(modelName, "(")
closePos = InStr(modelName, ")")
secondPart = Mid(modelName, openPos + 1, closePos - openPos - 1)
我的问题是如何提取64 GB
而不是4 GB
。
我尝试遍历所有字符并保存最后5个字符,以查看它们是否与我想要的匹配。但是必须有更好的方法。
我将不胜感激, 非常感谢
编辑
这是输入和输出的另一个示例: 输入:
iPhone iPhone SE,10,2厘米(4“),640 x 1136像素,16 GB,12 MP,iOS 9,排序,Grå
预期输出:
iPhone iPhone SE 4“ 16 GB
答案 0 :(得分:4)
尝试
Option Explicit
Function oneTwoThree(str As String)
Dim vals As Variant
vals = Split(str, ",")
oneTwoThree = Join(Array(vals(0), _
Split(Split(vals(2), "(")(1), ")")(0), _
Trim(vals(4 + (InStr(1, vals(4), "gb", vbTextCompare) = 0)))), " ")
End Function
答案 1 :(得分:4)
如何使用RegEx提取值并使用最后一个值。只需添加对库的引用:“ Microsoft VBScript正则表达式5.5”。然后,您可以执行此操作。
Option Explicit
Public Function xx()
Dim modelName As String
Dim firstPart As String
Dim Pattern As String
Dim GBString As String
Dim regEx As New RegExp
Dim finalName As String
Dim matches As MatchCollection
Let modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
firstPart = Trim(Split(modelName, ",")(0))
With regEx
.Global = True
.IgnoreCase = True
.Pattern = "[0-9]+ GB"
End With
Set matches = regEx.Execute(modelName)
If matches.Count > 0 Then
GBString = matches(matches.Count)
Else
GBString = "<unknown GB>"
End If
finalName = firstPart + GBString
End Function
答案 2 :(得分:2)
尝试下一段代码:
Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ",")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String
firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(2), InStr(data(2), "(") + 1), ")", ""))
thirdPart = Trim(data(4))
MsgBox firstPart & " " & secondPart & " " & thirdPart
您必须非常注意定界符数据子字符串。例如,如果您的主要文本是P10, 12 cm (5.1"), 4 GB, 64 GB, 20 MP
,则该代码将不再起作用。假设您始终在数据元素之间使用逗号和空格,而可以改为:
Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ", ")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String
firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))
thirdPart = Trim(data(3))
MsgBox firstPart & " " & secondPart & " " & thirdPart
它将始终有效。
如果元素4 MB
并不总是存在,请执行以下操作:
Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ", ")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String
firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))
Select Case InStr(modelName, "4 GB")
Case 0
thirdPart = Trim(data(2))
Case Else
thirdPart = Trim(data(3))
End Select
MsgBox firstPart & " " & secondPart & " " & thirdPart
更新:
我想现在我完全明白了你想要的。我用您在问题上给我们的三个示例尝试了下一个代码,该示例成功了(问题是我不知道您想要的是MD
值之前的最后一个数据值。
Dim modelName As String
Dim data() As String
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String
modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
data = Split(modelName, ", ")
firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))
thirdPart = Trim(data(Application.Match("*MP", data, 0) - 2))
MsgBox firstPart & " " & secondPart & " " & thirdPart
您可以尝试
modelName = "P10, 12,9 cm (5.1""), 64 GB, 20 MP"
或搭配
modelName = "iPhone iPhone SE, 10,2 cm (4""), 640 x 1136 pixel, 16 GB, 12 MP, iOS 9, Sort, Grå"
它将始终为您提供答案。
答案 3 :(得分:2)
这是我制作的应该始终有效的功能。
为处理获取正确存储值的问题,它通过用逗号分隔的每个部分并寻找“ GB”,然后在这些部分之一中跟踪最大值,然后该最大值必须是存储值
Public Function FormatName(Inp As String) As String
Dim ArrInp As Variant, i As Integer, Temp As String
ArrInp = Split(Trim(Inp), ",")
FormatName = ArrInp(0) & " " & Mid(Inp, InStr(Inp, "(") + 1, InStr(Inp, ")") - InStr(Inp, "(") - 1)
For i = 1 To UBound(ArrInp)
If InStr(UCase(ArrInp(i)), "GB") <> 0 And Val(ArrInp(i)) > a Then
Temp = ArrInp(i)
End If
Next
FormatName = FormatName & Temp
End Function
希望这会有所帮助。
答案 4 :(得分:2)
我参加聚会不晚!
我通过简单的公式方法进行了快速尝试,并提出了类似的方法,似乎可以使用当前的样本数据集。
如果您的文本在A1单元格中,请尝试使用以下公式提取相关信息,
=LEFT(A1,(FIND(",",A1,1)-1))
=MID(A1,SEARCH("(",A1)+1,SEARCH(")",A1)-SEARCH("(",A1)-1)
=MAX(VALUE(MID(A1,FIND("GB",A1)-3,2)),VALUE(IFERROR(MID(A1,IFERROR(FIND("GB",A1,FIND("GB",A1)+1),0)-3,3),0)))&" GB"
答案 5 :(得分:1)
使用正则表达式:
假设:
"
GB
Replace
方法Option Explicit
Function phone(S As String) As String
Dim RE As Object
Const sPat As String = "^([^,]+).*?(\b[\d.]+"").*(\b\d+\s+GB).*"
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = sPat
.Multiline = True
phone = .Replace(S, "$1 $2 $3")
End With
End Function
^([^,]+).*?(\b[\d.]+").*(\b\d+\s+GB).*
选项:区分大小写; ^ $匹配行间的中断
^
([^,]+)
.*?
(\b[\d.]+")
.*
(\b\d+\s+GB)
.*
$ 1 $ 2 $ 3
$1
$2
$3
由RegexBuddy创建