No.66-1 |
既存データベースの5桁郵便番号を7桁にするには? |
回答者 入川 精二 |
1998年01月 192号 P.21 |
◆ No.66(1997年 11月号)の回答-01(自問自答)
《《はじめに》》
郵便局が出している『新郵便番号CD-ROM』は単に素材を提供しているだけで、そのままではどうにも使い難い形式になっています。
以前(5桁の時に)このCD-ROMからPIPS用の“地名辞書”を作ったことがあって、比較的容易に都道府県別の7桁郵便番号辞書を作ることが出来ました。
辞書があれば、何とかなると思って取り組んだのですが、巨大な辞書を1つ作る(プログラムは簡単だが多分スゴク重くなる)か、都道府県別に辞書を47作ってそれぞれにインデックスを掛ける(インデックスを掛けるのはちょっと大変だし、プログラムも少し複雑になる)か、迷いました。
結局、後者を選択することにしました。インデックスを掛けるのは、「索引一覧表」を作れば全部オートで出来るし、何よりも元のデータが都道府県別になっているので、そのバインダーを利用すればよく、辞書を作るのに楽を出来るのです。
《《地名のJISコードについて》》
都道府県名と市区町村名にはすべてJIS(日本工業規格)コードが設定されています。
JIS X 0401(都道府県)とJIS X 0402(市区町村)です。都道府県コードは2桁、市区町村コードは3桁、都合5桁で全国の市区町村のコード体系が出来ています。
例えば、千葉県は‘12’、松戸市は‘207’。‘12207’で千葉県松戸市が確定します。
このコードが『新郵便番号CD-ROM』のデータに併記されています。PIPSに取り込んで地名のデータベースを作るときに、このJISコードが非常に役に立ちました。郵便局のデータにはいろいろ不備なところがありますが、この点だけは誉めてもよいでしょう。
《《既存の名簿に新郵便番号を付ける》》
通常、郵便番号を振るのは住所を入力するときです。郵便番号を入力して地名を検索するとか、地名コードを入力して地名と郵便番号を検索・入力するなどでしょう。
所が、今回は既に地名が入力されていて、対応する郵便番号を検索するのですからいささか厄介です。新郵便番号を検索するのに何をトッカカリにするか が問題です。
既に入力されているデータの中から、多分入力されているであろう5桁の郵便番号が役に立ちそうです。それと、住所欄から頭の何文字かで「都道府県」名または「市」名が読み取れそうです(全てのデータに都道府県が書かれていれば楽なのですが・・・・)。後は辞書の地名と入力されている住所がマッチするかどうかを見るだけです(話は簡単?)。
県別に辞書を作って、それぞれにインデックスを掛けているので、入力されている住所が何県か が分からないと話になりません。そこで、『県市名一覧』というファイルを作りました。[図1] ここには都道府県名と全国の全ての市名が記載されており、対応する県名(カナ)と県別辞書に掛けたインデックス名があります。「市」が分かれば、どの辞書を探せばよいかが決ります。
《《都道府県別辞書》》
『都道府県別辞書』は『索引名一覧』[図2]のバインダー名の欄にあるように‘○○県地名’という名で登録します。インデックスはやたらと多いので、手操作で掛けるわけに行きません。この表から「索引設定」プログラムを使ってまとめて処理します。
[図2] 索引名一覧
|
[図3]
|
例えば‘大阪府地名’は[図3]のようになっていて、木村会員のお住いのある所は現郵便番号は‘540’新郵便番号は‘540-0033’ということが分かります(住所入力用に使う場合は、郵便番号既知の場合はこれでも使えますが地名コードの欄も必要と思います)。
《《プログラム》》
以上のデータとインデックスを使って既存の住所データベースに7桁郵便番号を書込むプログラム <NT3> が完成しました。
ミソはサブプログラム <県別> 48〜53行目の都道府県を確定する部分でしょう。
都道府県名は3〜4文字、市名になると2〜6文字あります。2文字なら蕨市・柏市・旭市他合わせて10市あります。長い方は「ひたちなか市」というのがあります。
これを住所データの左から2文字⇒3文字⇒4文字・・・と順に該当するものがあるかどうか「県市名一覧」から探すのです。目で探すとしたら記の遠くなるような話ですが、インデックスで探しますから、あっという間です。
今一つのミソは、60〜62行目のワイルドカードで辞書の地名と住所データの地名とがマッチするかどうかチェックするところです。辞書の並び方によっては短い地名でマッチしてしまう可能性もあります。例えば‘東京都中央区日本橋小伝馬町’が‘=東京都中央区日本橋*’と一致してしまいます。こんな事が起こらぬように、辞書は文字数の多い方から順に並べておく必要があります。
《《プログラムを使ってみれば》》
PUCの名簿を対象に、このプログラムを実行してみました。勿論、事前に新郵便番号を書込む8桁の列を挿入しておきます。
実 行 の 結 果、新郵便番号を書込まなかったデータが幾つかありました。次のような例です。
-
辞書の地名と名簿の地名表記が異なる場合:
-
地名の一部が次の列に書かれている。
使用する文字が異なる。「当麻町」と「當麻町」
辞書では「大字」「字」を省略している。
-
市区再編や統合で地名が変更になった場合:
-
木村さんの住所は東区から中央区に変更。
-
名簿で「町」が省略されている場合:
-
名簿では「南篠崎」、辞書では「南篠崎町」
5桁郵便番号をキーにしているので、これが違っていると地名の検索が出来ない。野崎産業の住所に対する郵便番号は辞書では‘103’、名簿に記載されているのは大口事業所の番号‘103-91’。
また、辞書に記載のない宛名、例えば「△△郵便局私書箱」も対応できない。
以上の結果を踏まえて名簿データを多少修正した上で実行した結果が[図4]です。
[図4]
|
問題は実行速度ですが、私の遅いマシン(100メガヘルツ・メモり16MB)で1件1秒強です。インデックスを多用しますので、マシンによりかなり違いが出ると思います。
これが速いか遅いかは見方によって変わるでしょうが、他に方法がなければ、手作業よりはマシということになりますか。
《《このプログラムを使いたい方へ》》
使うプログラムは68行ですが、他にインデックスを設定するために<索引設定>プログラムが必要です。
必要なデータベース(都道府県別地名辞書他)が約500頁あります。
お使いになりたい方があれば喜んで提供させていただきますが、実費+α をご負担頂ければ幸いです(まだ決めていませんが)。
《《プログラム》》
<NT3> ## 既存データベースに7桁郵便番号を書き込む ##
/****************************************************************/
/* V1 処理対象バインダー */
/* V2 処理対象の行の「5桁郵便番号」 */
/* V3 処理対象の行の「住所」 */
/* V12 インデックスで検索した7桁郵便番号 */
/* V13 インデックスで検索した町名 */
/* V23 V13 のコーテーション付きワイルドカード */
/* X1 対象バインダーの頁番号 */
/* X2 「5桁郵便番号」の列番号 */
/* X3 「7桁郵便番号」の列番号 */
/* X4 「住所」の列番号 */
/* X5 処理対象の行番号 */
/****************************************************************/
IUSE ";D/CHIMEI2:CHIMEI";;
IUSE ";D/CHIMEI2:KENSHI";;
$入力1: ACCEPT /P ";対象バインダーは? ";,V1;
IF ERR(0)=55 THEN GOTO $END;
IF V1=";"; THEN GOTO $入力1;
IF NAME(3,V1)=0 THEN GOTO $入力1;
G;%V1/1;
$入力2: ACCEPT /C ";「5桁郵便番号」の列番号は? ",X2;
IF ERR(0)=55 THEN GOTO $END;
IF X2=0 | X2>C THEN GOTO $入力2;
$入力3: ACCEPT /C ";「7桁郵便番号」を書き込む列番号は? ",X3;
IF ERR(0)=55 THEN GOTO $END;
IF X3=0 | X3>C THEN GOTO $入力2;
$入力4: ACCEPT /C ";「住所」の列番号は? ",X4;
IF ERR(0)=55 THEN GOTO $END;
IF X4=0 | X4>C THEN GOTO $入力2;
$#01: FOR X1=1 TO BINDER(V1);
G;%V1/%X1;
FOR X5=H TO T;
LET V2=[X5,X2]; /* 5桁郵便番号を読込む */
IF V2=";"; THEN GOTO $#N2;
LET V3=[X5,X4]; /* 住所を読込む */
IF V3=";"; THEN GOTO $#N2;
$#K0: GOSUB ;
/* 県別辞書を探す */
$#N2: CLEAR V2/3/12/13/23;
NEXT;
P;%V1/%X1;
NEXT;
$END: IEND ";D/CHIMEI2:CHIMEI";;
IEND ";D/CHIMEI2:KENSHI";; STOP;
<県別> ## 都道府県別辞書の検索 ##
$#K00: FOR X11=2 TO 6; /* ここで都道府県を確する */
LET V4=KLEFT$(V3,X11); /* 住所の左からX11文字 */
ISEARCH ";D/CHIMEI2:KENSHI";,V4; /* 県市名一覧から探す */
IF ERR(0)<>0 THEN CONTINUE;
GOTO $#K01; /* 都道府県が確定した */
NEXT;
GOTO $RET2;
$#K01: IREAD ";D/CHIMEI2:KENSHI";,V5=@IDX名 ; /* 県別インデックス名 */
LET V5=";D/CHIMEI2:";+V5;
$#K02: IUSE V5; /* 県別辞書のインデックスを使う */
$#K03: ISEARCH V5,V2; /* 県別辞書から探す */
IF ERR(0)<>0 THEN GOTO $RET1; /* ‘県別’に見つからない */
$#K04: IREAD V5,V12=@新〒 ,V13=@町 ;
LET V23='";=*'+V13+'*";'; /* 町名をワイルドカード化 */
IF V3<>%V23 THEN GOTO $#N1; /* 不符号なら $#N1 へ */
$#K05: LET [X5,X3]=V12; GOTO $RET1; /* 新郵便番号を書込む */
$#N1: INEXT V5; /* 次の候補を探す */
IF ERR(0)<>0 THEN GOTO $RET1;
GOTO $#K04;
$RET1: IEND V5;
$RET2: CLEAR V4,5; RETURN;
|
| |