くまおやぢの雑記帳

人生は、やろうと思った瞬間がスタートライン。Excel・Access・ガジェット・スマホ関係のネタを綴っています。あなたの「できる」を応援します。

エクセルVBA|住所の文字列を分割する方法

今日は住所について文字列分割していきます。また例のごとくパートのおねえさんからの要望です。

通常、文字列分割は特定の文字で区切るのが多いですが、住所の場合は区切る位置が都道府県から始まり、市区町村があるのでエクセルの区切り位置の機能は使えません。

また、文字数が同じであれば、right関数やmid関数、left関数でも片づけられそうですが、文字数もバラバラなのでこれも不可。ということでVBAでちゃちゃっとやることにしました。

    Sub 住所分割()
    Dim ws As Worksheet
    Set ws = ActiveSheet
    
    Dim lastRow As Long
    lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
    
    ' ▼ 政令指定都市リスト(必要に応じて追加/削除)
    '   ここに含まれている都市は「市+区」を市区欄にまとめて格納
    Dim seiReiCities As Variant
    seiReiCities = Array( _
        "札幌市", "仙台市", "さいたま市", "千葉市", "川崎市", "横浜市", _
        "新潟市", "静岡市", "浜松市", "名古屋市", "京都市", "大阪市", _
        "堺市", "神戸市", "岡山市", "広島市", "北九州市", "福岡市", "熊本市" _
    )
    
    Dim i As Long
    For i = 2 To lastRow ' 2行目から最終行まで処理
        Dim address As String
        address = ws.Cells(i, 1).Value
        
        Dim ken As String, shi As String, machi As String
        Dim kenEnd As Long, shiEnd As Long
        
        '========================================
        '【1】都道府県の取得
        '========================================
        If Left(address, 3) = "北海道" Then
            ' 北海道は3文字
            ken = "北海道"
            kenEnd = 3
        ElseIf Left(address, 3) = "京都府" Then
            ken = "京都府"
            kenEnd = 3
        ElseIf Left(address, 3) = "大阪府" Then
            ken = "大阪府"
            kenEnd = 3
        Else
            ' 「都」「道」「府」「県」のいずれかを検索
            kenEnd = InStr(address, "都")
            If kenEnd = 0 Then kenEnd = InStr(address, "道")
            If kenEnd = 0 Then kenEnd = InStr(address, "府")
            If kenEnd = 0 Then kenEnd = InStr(address, "県")
            
            If kenEnd > 0 Then
                ken = Left(address, kenEnd)
            End If
        End If
        
        '========================================
        '【2】市区の取得
        '========================================
        
        ' --- 2-1. 東京の場合(東京23区を「市区」欄に) ---
        If ken = "東京都" Then
            ' 「区」を探す(例: 新宿区、中央区 など)
            shiEnd = InStr(kenEnd + 1, address, "区")
            If shiEnd > 0 Then
                ' 例: 「東京都新宿区◯◯」の場合
                ' kenEnd=3, shiEnd=6 (それぞれ「都」「区」の位置)
                ' → Mid(...,4,6-4+1)=「新宿区」
                shi = Mid(address, kenEnd + 1, shiEnd - (kenEnd + 1) + 1)
            End If
        
        ' --- 2-2. その他の都道府県の場合 ---
        Else
            ' まず政令指定都市かどうかを確認
            Dim city As Variant
            Dim cityPos As Long, wardPos As Long
            Dim foundCity As Boolean
            foundCity = False
            
            For Each city In seiReiCities
                ' 例: 「福岡市」「札幌市」「横浜市」など
                cityPos = InStr(kenEnd + 1, address, city)
                If cityPos > 0 Then
                    ' 政令指定都市を見つけたら、そのあとに「区」があるか探す
                    wardPos = InStr(cityPos + Len(city) - 1, address, "区")
                    ' 例: 「福岡市博多区」の場合
                    ' cityPos=「福岡市」の先頭位置、そこからさらに「区」を検索
                    If wardPos > 0 Then
                        ' 「市+区」全体を市区欄にまとめる
                        shi = Mid(address, kenEnd + 1, wardPos - (kenEnd + 1) + 1)
                        shiEnd = wardPos
                    Else
                        ' 「区」が見つからない場合は「市」までで市区欄とする
                        Dim cityEnd As Long
                        cityEnd = cityPos + Len(city) - 1
                        shi = Mid(address, kenEnd + 1, cityEnd - (kenEnd + 1) + 1)
                        shiEnd = cityEnd
                    End If
                    foundCity = True
                    Exit For
                End If
            Next city
            
            If Not foundCity Then
                ' 通常の市・区・町・村を探す(政令指定都市以外の場合)
                shiEnd = InStr(kenEnd + 1, address, "市")
                If shiEnd = 0 Then shiEnd = InStr(kenEnd + 1, address, "区")
                If shiEnd = 0 Then shiEnd = InStr(kenEnd + 1, address, "町")
                If shiEnd = 0 Then shiEnd = InStr(kenEnd + 1, address, "村")
                
                If shiEnd > 0 Then
                    shi = Mid(address, kenEnd + 1, shiEnd - (kenEnd + 1) + 1)
                End If
            End If
        End If
        
        '========================================
        '【3】町域の取得
        '========================================
        If shiEnd > 0 Then
            ' shiEnd の次から最後までを町域とする
            machi = Mid(address, shiEnd + 1)
        Else
            ' shiEnd が0 (「市区」を見つけられなかった) 場合は
            ' 都道府県の次から最後までを町域とする
            machi = Mid(address, kenEnd + 1)
        End If
        
        '========================================
        '【4】結果を出力
        '========================================
        ws.Cells(i, 2).Value = ken    ' B列: 都道府県
        ws.Cells(i, 3).Value = shi    ' C列: 市区
        ws.Cells(i, 4).Value = machi  ' D列: 町域
    Next i
    
End Sub

実行するとこんな感じです。

これで長さのまちまちな住所もワンクリックで分割できます。

ただ、ひとつ問題があって、下の4行

石川県野々市市

三重県四日市市

広島県廿日市市

佐賀県大町町

この4市町は市と町が2文字続いているためうまく区切れていません。本来なら

石川県|野々市市

三重県|四日市市

広島県|廿日市市

佐賀県|大町町 となるはずが、

石川県|野々市|市

三重県|四日市|市

広島県|廿日市|市

佐賀県|大町|町 となってしまっています。

この住所が出てくることはほとんどないので今回はこの不具合はスルーします。もし万が一この市町が出てきた場合は手計算とします。