< | >

Access:住所に含まれる番地と建物名を一括で分けるVBA
  • (2012-05-17 18:12:57)
何年も手作業でやってきたが、自動化しようとは思いつかなかった。手作業でもそれほど負担ではなく、また例外が多くプログラムに向かないという思い込みからか。しかし、やってみれば、天国(2012/05/18 小平探検隊)。

番地と建物名に間にスペースを入れる仕様のヤマトB2


宅急便伝票打ち出しソフトのヤマトB2では番地と建物名に間にはスペースを入れる仕様になっている。

住所・建物名が短ければ(ある文字数以下)なら分けなくても良いが、だいたい分けることになる。今まで手作業でやってきたが、VBAで一括変換することに。

前提として全角英数字カナを半角にしておく


全角・半角が入り乱れるとおかしな事になるので、strConv関数で半角変換しておく。また半角スペースは全角スペースにしておく。

「住所」フィールドの文字列を順次読み込むという発想


どうやって数字とそれ以外をプログラムで見分けるのか?左端から1文字ずつ読むしかないらしい。

人には間抜けな判定方法に見えるがコンピューターは得意らしい。


For i = 1 To Len(RS![住所1]) - 1
で1文字ずつ最後まで読み込む。人としては許せない作業。
Next i


基本的には数字+文字で分ける


基本的な考え方:「数字の後に数字ではない文字が来たら『番地と建物名』の可能性が高い」

おおむね法則性はあるが、例外も多い。かなりいやらしい。

住所の文字列の左端から2文字読み込み、「数字+数字以外の文字」の組み合せかチェック。


If IsNumeric(Mid(RS![住所1], i, 1)) = True And IsNumeric(Mid(RS![住所1], i + 1, 1)) = False Then


例外が多い


例外はたとえば、「1-2-3」のハイフン、「1丁目2番地3号」や「1条」の漢字、すでに入っている「 」(スペース)など。これらは例外としてスペースを入れない。

Orで例外条件を連ねる。プログラムとしては一応動作するが、かなり汚い。これでいいのか?Andはネスト構造で記述できるが、Orはできないらしい。


If Not (Mid(RS![住所1], i + 1, 1) = "条" Or Mid(RS![住所1], i + 1, 1) = "丁" Or Mid(RS![住所1], i + 1, 1) = "番" Or Mid(RS![住所1], i + 1, 1) & Mid(RS![住所1], i + 2, 1) = "番地" Or Mid(RS![住所1], i + 1, 1) = "号" Or Mid(RS![住所1], i + 1, 1) = " " Or Mid(RS![住所1], i + 1, 1) = "-" Or Mid(RS![住所1], i + 1, 1) = "の" Or Mid(RS![住所1], i + 1, 1) Like "[a-zA-Z]" Or Mid(RS![住所1], i + 1, 1) = "ー") Then


・「丁」「目」「番」「番地」「号」「条」
・「-」
・「 」(全角スペース)
・「の」
・「2A」など数字+アルファベット
・「ー」ハイフンの代わりにこんな文字を入れる人も。これも分けない

合理的なIf ThenとAnd/Orの順番


If Thenの構文に AndやOrの組み合わせが多数必要になる。

If Then文が多くなると効率的な順番を考えないと無駄な計算をさせることになるし、人間がコードを見たとき自然な理解がしにくい。

スペースを入れる場所を見つけても、入れ方がわからない!


Replaceとか考えてみたが、これをやるとおかしくなる。

しかたなく、美しく見えないが、読み込んだ文字列をメモリーに1文字ずつ足し合わせていく、スペースを入れるところにはスペースの文字を足すという方法を採用。


str1 = str1 & Mid(RS![住所1], i, 1)


そして、最後に住所フィールドを入れ替えてupdateする。

RS![住所1] = str1 & Mid(RS![住所1], Len(RS![住所1]), 1)


「& Mid(RS![住所1], Len(RS![住所1]), 1)」の部分は2文字チェックの際、チェックせずstr1に取り込まれていない最後1文字。

結論



Do Until RS.EOF
RS.Edit
str1 = ""
For i = 1 To Len(RS![住所1]) - 1
str1 = str1 & Mid(RS![住所1], i, 1)
If IsNumeric(Mid(RS![住所1], i, 1)) = True And IsNumeric(Mid(RS![住所1], i + 1, 1)) = False Then
If Not (Mid(RS![住所1], i + 1, 1) = "条" Or Mid(RS![住所1], i + 1, 1) = "丁" Or Mid(RS![住所1], i + 1, 1) = "番" Or Mid(RS![住所1], i + 1, 1) & Mid(RS![住所1], i + 2, 1) = "番地" Or Mid(RS![住所1], i + 1, 1) = "号" Or Mid(RS![住所1], i + 1, 1) = " " Or Mid(RS![住所1], i + 1, 1) = "-" Or Mid(RS![住所1], i + 1, 1) = "の" Or Mid(RS![住所1], i + 1, 1) Like "[a-zA-Z]" Or Mid(RS![住所1], i + 1, 1) = "ー") Then
str1 = str1 & " "
End If
End If
Next i
RS![住所1] = str1 & Mid(RS![住所1], Len(RS![住所1]), 1)
str1 = ""
RS.Update
RS.MoveNext
Loop







<< Office互換ソフトの時代・・市場性が失われつつあるOffice< | >Access:住所に含まれる全角カタカナ、全角英数字を一括で半角変換するVBA >>
search
layout
admin

[▲page top]