在Excel中将1个单元格中的地址元素分开

时间:2013-07-29 02:09:02

标签: excel parsing excel-formula extract

我有以这种格式的数千个地址:

123 Happy St. Kansas City,MO 64521

9812 Main Street Minneapolis,MN 62154

12 Virgina Ave,Apt 8,Dallas,TX 54334

我想将地址,城市,州,邮政编码提取到单个单元格中(如果可能,不使用VB)。我已经尝试了其他方法的几种变体,但我无法获得理想的结果。

2 个答案:

答案 0 :(得分:2)

分析你的问题!

  1. 您想以逗号分隔您的地址字符串
  2. 然后你想要从第一个空白处的(1)分割出正确的片段
  3. ad 1):您使用=FIND(",", A1)得到逗号的位置,并使用=LEFT(...)=RIGHT(...)中的结果 - 对于后者,您还需要字符串长度( =LEN(...)

    • B1:=LEFT(A1;FIND(",";A1)-1)
    • C1:=RIGHT(A1;LEN(A1)-LEN(B1)-2)

    现在来了有趣的部分......在你的第三个例子中,我们不能拆分第一个逗号,而是放在第三个逗号上......或者作为更一般的规则,我们总是必须拆分最后一个逗号。 ..但是我们如何找到字符串中有多少逗号,将其作为附加参数的位置提供给=FIND(...)函数?

    快速回答:查看Stackoverflow(确切地说here)...非常聪明...从原始长度中删除所有逗号后减去字符串的长度,然后用逗号替换逗号的最后一次出现其他因素,因为=SUBSTITUTE(...)适用于出现,而=FIND()仅适用于位置。如果你把这一切都包含在内,你就会有

    • B1:=LEFT(A1;FIND("@";SUBSTITUTE(A1;",";"@"; LEN(A1)-LEN(SUBSTITUTE(A1;",";""))))-1) - >完整地址
    • C1:(与上述相同)

    这里我们使用“@”作为最终逗号的中性替换字符串,因为我们认为没有地址使用“@”

    ad 2):您再次将上述内容(空白而不是逗号)应用于右侧部分。您可以使用公式的简单第一版,因为很明显您要在第一个空白处拆分

    • D1:=LEFT(C1;FIND(" ";C1)-1) - >状态
    • E1:=RIGHT(C1;LEN(C1)-LEN(D1)-1) - >邮政编码

答案 1 :(得分:0)

此VBA函数将Zip,州,城市,Street1和Street2(套房,公寓等)提取到单独的列中。需要稍作修改以删除逗号。

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