我有数千个这种格式的地址:
123 快乐圣堪萨斯城,密苏里州 64521
9812 大街明尼阿波利斯,MN 62154
12 Virgina Ave, Apt 8, 达拉斯, TX 54334
我想提取地址、城市、州,压缩到单个单元格中(如果可能,不使用 VB)。我已经尝试过发布其他方法的几种变体,但我无法获得理想的结果。
我有数千个这种格式的地址:
123 快乐圣堪萨斯城,密苏里州 64521
9812 大街明尼阿波利斯,MN 62154
12 Virgina Ave, Apt 8, 达拉斯, TX 54334
我想提取地址、城市、州,压缩到单个单元格中(如果可能,不使用 VB)。我已经尝试过发布其他方法的几种变体,但我无法获得理想的结果。
分析你的问题!
广告 1):您使用 获取逗号的位置=FIND(",", A1)
,并在 a=LEFT(...)
和 a中使用结果=RIGHT(...)
- 对于后者,您还需要字符串长度 ( =LEN(...)
)
=LEFT(A1;FIND(",";A1)-1)
=RIGHT(A1;LEN(A1)-LEN(B1)-2)
现在是有趣的部分......在你的第三个例子中,我们不能在第一个逗号上拆分,但在第三个逗号上......或者作为更一般的规则,我们总是必须在最后一个逗号上拆分......但是我们如何找到字符串中有多少个逗号,以将其位置作为附加参数提供给=FIND(...)
函数?
快速回答:看看 Stackoverflow(正是这里)......非常聪明......从原始长度中减去所有逗号的字符串长度,然后用其他东西替换最后出现的逗号,因为=SUBSTITUTE(...)
适用于出现, 而=FIND()
仅适用于位置。如果你把这一切结合起来,你将拥有
=LEFT(A1;FIND("@";SUBSTITUTE(A1;",";"@"; LEN(A1)-LEN(SUBSTITUTE(A1;",";""))))-1)
--> 完整地址这里我们使用“@”作为最后一个逗号的中性替换字符串,因为我们假设没有地址使用“@”
广告 2):您再次将上述内容(用空格代替逗号)应用于右侧部分。您可以使用简单的第一个公式版本,因为很明显您想在第一个空白处拆分
=LEFT(C1;FIND(" ";C1)-1)
--> 状态=RIGHT(C1;LEN(C1)-LEN(D1)-1)
--> 邮政编码此 VBA 函数将 Zip、State、City、Street1 和 Street2(Suite、Apt 等)提取到单独的列中。需要稍作修改以删除逗号。
Option Explicit
Function ParseAddress(ByVal varAddress As Variant, ByVal strAddressPart As String) As String
Dim aryAddressTokens() As String
Dim strCity As String
Dim intCtr As Integer
Dim intStreet2Tokens As Integer
Dim strStreet1, strStreet2 As String
If IsMissing(varAddress) Or varAddress = vbNullString Then
ParseAddress = ""
Else
aryAddressTokens = Split(Trim(varAddress), " ")
'
If strAddressPart = "Zip" Then
ParseAddress = aryAddressTokens(UBound(aryAddressTokens))
ElseIf strAddressPart = "State" Then
ParseAddress = UCase(aryAddressTokens(UBound(aryAddressTokens) - 1))
ElseIf strAddressPart = "City" Then
strCity = aryAddressTokens(UBound(aryAddressTokens) - 2)
If Right(strCity, 1) = "," Then strCity = Left(strCity, Len(strCity) - 1)
ParseAddress = strCity
ElseIf strAddressPart = "Street1" Or strAddressPart = "Street2" Then
'Find Street2 if present because Street1 output is dependent on it.
' Assume address never begins with a # or Suite.
intCtr = 1
strStreet2 = ""
intStreet2Tokens = 0
While (intCtr < UBound(aryAddressTokens) - 2) And strStreet2 = ""
If Left(aryAddressTokens(intCtr), 1) = "#" Then
If Len(aryAddressTokens(intCtr)) = 1 Then
strStreet2 = aryAddressTokens(intCtr) & aryAddressTokens(intCtr + 1)
intStreet2Tokens = 2
Else
strStreet2 = aryAddressTokens(intCtr)
intStreet2Tokens = 1
End If
ElseIf Left(aryAddressTokens(intCtr), 5) = "Suite" Then
If Len(aryAddressTokens(intCtr)) = 5 Then
strStreet2 = aryAddressTokens(intCtr) & " " & aryAddressTokens(intCtr + 1)
intStreet2Tokens = 2
Else
strStreet2 = aryAddressTokens(intCtr)
intStreet2Tokens = 1
End If
ElseIf Left(aryAddressTokens(intCtr), 3) = "Apt" Then
strStreet2 = aryAddressTokens(intCtr) & " " & aryAddressTokens(intCtr + 1)
intStreet2Tokens = 2
End If
intCtr = intCtr + 1
Wend
If Not IsEmpty(strStreet2) Then
If Right(strStreet2, 1) = "," Then strStreet2 = Left(strStreet2, Len(strStreet2) - 1)
End If
' Now Street1.
strStreet1 = ""
For intCtr = 0 To UBound(aryAddressTokens) - (3 + intStreet2Tokens)
strStreet1 = strStreet1 & " " & aryAddressTokens(intCtr)
Next
If Right(strStreet1, 1) = "," Then strStreet1 = Left(strStreet1, Len(strStreet1) - 1)
'Assign.
If strAddressPart = "Street1" Then
ParseAddress = Trim(strStreet1)
Else
ParseAddress = Trim(strStreet2)
End If
End If
End If
End Function