エクセル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文字続いているためうまく区切れていません。本来なら

石川県|野々市市

三重県|四日市市

広島県|廿日市市

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

石川県|野々市|市

三重県|四日市|市

広島県|廿日市|市

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

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

コメント

タイトルとURLをコピーしました