by Guantare.com
前回はIMEを利用して郵便番号から住所に変換しましたが、今回はWebの郵便番号検索apiサービスを利用して住所を取得する方法を考えます。とは言え、この手のものはFileMakerオンリーで過ごしてきた私にはとても難しいのでこちらの記事を参考にしました。参考にしたというよりそのまま真似ました。
https://qiita.com/tyuma/items/9a130b2689e8337ff976
https://qiita.com/tyuma/items/72055b3d4184714a456a
郵便番号検索のサイトは
このようなサービスを利用する利点はIME変換に比べてスピーディーに処理できる点にあります。また、数字は英数モードにして入力する習慣がある人にはIMEでの変換にもどかしさを感じるのではないでしょうか?
サンプルファイルの使い方
まずはサンプルファイルをダウンロードして試してください。
起動した画面から「Web活用」ボタンをクリックします。
「サンプル番号」ボタンをクリックすると幾つかのリストが表示されます。右側の件数は日本郵便からダウンロードしたKEN_ALL..CSVで調べた同一番号を持つ住所の件数です。
郵便番号欄に番号を入力します。ハイフンはなくても構いません。全角だとエラーになるのでこのフィールドは「英数モードに固定」にしてあります。
郵便番号のフィールドを抜けるとトリガーでスクリプトが走ります。町域の後ろに番地まで入力した後、間違えて郵便番号欄に入り、抜けた時にもう一度スクリプトが走り番地を消してしまう可能性があるので、カーソルをフィールドに挿入した時と抜けた時の番号が同じだとスクリプトを走らせないようにしてあります。
結果が1件の場合は都道府県、市区町村、町域が設定されます。
結果が複数あるとリストに表示され、選択した住所が設定されます。
前回のIME変換を利用した仕組みでは政令指定都市の区は町域の欄にしていましたが、今回は市区町村の中に入ります。これは日本郵便のデータが市区町村の中にあり、このサービスのデータは日本郵便のデータを利用しているからです。
取得したデータの確認や複数件のリストを作るためのテキストを確認するためにトリガーでは手動でスクリプトを走らせることができます。
「ステップ確認」ボタンをクリックしてレイアウトを変更します。
ステップ1では検索サイトからデータを取得します。
ステップ2では受け取ったデータが1件の場合は都道府県、市区町村、町域のフィールドに値を設定します。複数の場合は選択するためのリストを作成します。
郵便番号欄に番号を入力します。フィールドにトリガーを設定していないので、ステップ1、ステップ2のボタンをクリックします。
このサービスが親切なところは京都市の住所表記です。
「602-8064」は
京都府京都市上京区一町目(上長者町通堀川東入、東堀川通上長者町上る、東堀川通中立売通下る)
の3行分なのですが、
京都府京都市上京区一町目上長者町通堀川東入
京都府京都市上京区一町目東堀川通上長者町上る
京都府京都市上京区一町目東堀川通中立売通下る
京都府京都市上京区一町目
と4件表示されます。通り名を入れる、入れないがユーザーに委ねられています。利便性が高いサービスだと思います。
大まかな仕組み
「URLから挿入」スクリプトステップを使って郵便番号検索サービスに郵便番号とともにリクエストを送ります。JSON形式のテキストデータが返ってきますので、そのテキストから必要な項目を抽出することになります。複数件の場合はバーチャルリストを使って表示し選択できるようになっています。
URLから挿入
「URLから挿入」スクリプトステップでは取得したデータを格納するターゲットをフィールドにするか変数にするか決めます。「URLを指定」に「”http://zipcloud.ibsnet.co.jp/api/search?zipcode=” & “郵便番号”」とサービスのURLと郵便番号を入力します。
ターゲットをフィールドにした場合はスクリプトを実行するレイアウト上にフィールドを配置しておかないとデータを取得できません。「フィールド設定」とは異なり、「挿入」ではレイアウト上に配置しておく必要があります。
SampleDB_12_pstcdではグローバルフィールドを使うパターンとグローバル変数を使う2パターンがあります。
JSON形式
JSON形式とは行の中に幾つかのテキスト列を並べて配置するという形式のようです。私は初めて扱うので詳しくは説明できません。FileMakerではJSON関数が6個ありますが、リファレンスを読んでもさっぱりわかりません。なのでサイトの記事をそのまま真似るしかありませんでした。
それでもJSONについて調べた結果、わかったことは
- 全体が波括弧「{ }」で囲われている。
- この中にkey名と値の数セットがカンマ「,」で区切られて記述される。
- keyとはFileMakerのフィールド名のようなもの。値はフィールドの値と同様。
- key名と値はコロン「:」で区切られる。
- key名はテキストなのでダブルクォーテーション「” “」 で囲む。
- 値がテキストならダブルクォーテーション「” “」 で囲む。
{“key名1″:”値1″,”key名2″:”値2″,”key名3”:数字1}
- この形式で入れ子にできる。
- 波括弧「{ }」で囲まれた部分をオブジェクトと呼ぶ。
- オブジェクトが複数連なる時はカンマ「,」で区切り、配列として角括弧「[ ]」で囲む。
- さらに全体を波括弧「{ }」で囲むということです。
{“key名1″:値,”key名2”:[{“key名a”:値,”key名b”:値,”key名c”:値},{“key名a”:値,”key名b”:値,”key名c”:値},{“key名a”:値,”key名b”:値,”key名c”:値}],”key名3″:値}
さらに半角スペースや改行は無視される。これはFileMakerの計算式と同じですが、全角スペースはエラーになるようです。また、コメントは記述できないようです。
値がない場合、FileMakerでは「IsEmpty」を使ったり「””」を使ったり曖昧なところがありますが、JSONでは「null」を使用します。「null」にはダブルクォーテーション「””」をつけません。
文字コードはUTF-8に限られています。
一番戸惑ったことが名前。オブジェクトとValueです。オブジェクトとはFileMakerのフィールドでもオブジェクトタイプのフィールドのように使われますが、JSONでは
{“address1″:”愛知県”,”address2″:”豊橋市”,”zipcode”:”000000″}
のような形式の文字列のことを指すようです。FileMakerのValueは「行」を表すのですが、JSONでのオブジェクトに相当します。JASONでのValueは値そのものです。
似たようなものの名前もソフトや言語によっても色々です。FileMakerのフィールドと同じようなものをセル、カラムなど異なる名前がついていたりします。
同じ言葉でも意味が違うことも良くあります。「パス」という言葉もグラフィック系ソフトではベクトル系の線を指しますが、他ではフォルダやファイルの階層を表すテキストだったりします。ちょっとした思い込みで深みにハマる原因でもあります。
{
“message”: null,
“results”: [
{
“address1”: “愛知県”,
“address2”: “豊橋市”,
“address3”: “東田町西郷”,
“kana1”: “アイチケン”,
“kana2”: “トヨハシシ”,
“kana3”: “アズマダチョウサイゴウ”,
“prefcode”: “23”,
“zipcode”: “4400062”
},
{
“address1”: “愛知県”,
“address2”: “豊橋市”,
“address3”: “東田町中郷”,
“kana1”: “アイチケン”,
“kana2”: “トヨハシシ”,
“kana3”: “アズマダチョウナカゴウ”,
“prefcode”: “23”,
“zipcode”: “4400062”
},
{
“address1”: “愛知県”,
“address2”: “豊橋市”,
“address3”: “東田町西脇”,
“kana1”: “アイチケン”,
“kana2”: “トヨハシシ”,
“kana3”: “アズマダチョウニシワキ”,
“prefcode”: “23”,
“zipcode”: “4400062”
},
{
“address1”: “愛知県”,
“address2”: “豊橋市”,
“address3”: “東田町”,
“kana1”: “アイチケン”,
“kana2”: “トヨハシシ”,
“kana3”: “アズマダチョウ”,
“prefcode”: “23”,
“zipcode”: “4400062”
}
],
“status”: 200
}
サンプルで使ったサイトではJSON形式で1行で記述すると読みにくくなるのでタブや改行を使って読みやすくしているようです。
messageはエラー内容の記述になっています。
resultsが住所です。
statusはエラーコードで「200」は正常終了のようです。
resultsの中はカンマで区切られた都道府県や市区町村が波括弧「{ }」で囲まれていて、複数の件数があるときはカンマで区切って波括弧「{…. }」を繰り返してあります。
JSON形式を私なりに模式化するとこのような感じでしょうか。
入れ子になると複雑ですが、乱暴な言い方をすれば、オブジェクトと呼ばれる「{ }」で囲まれた中身はフィールド名と値がセットになっているカンマ区切りのCSVの1行のような感じです。さらに「[ ]」で囲まれた中身は複数行のCSVだと思えば理解しやすいかもしれません。
JSON関数
サンプルで使っているFileMakerのJSON関数は2つです。
ValueCount ( JSONListKeys ( $$結果json ; “results” ) )
「$$結果json」は取得されたデータを指しています。
JSONListKeys ( $$結果json ; “results” )はresultsの中身の{}で囲まれたオブジェクトの配列番号を取得し、改行コードで区切ってあります。
ValueCountはFileMakerで使うValueの意味なので、行数を取得します。
resultsの中の「{ }」は1件の住所なので行数が件数ということになります。
注意しなければならないのは配列番号が「0」から始まることです。「0¶1¶2¶3」なら4件ということになります。後ほど使う繰り返しフィールドの繰り返し番号は「1」から始まるので間違わないようにしなければいけません。
JSONGetElement ( $$結果json ; “results[0]address1”)
これはresultsの中の配列番号[0]のaddress1の値”愛知県”を取得することになります。複数の配列がある場合、2番目は[1]、3番目は[2]と指定していくことになります。
最大件数
何度か試してみるうちに、どうも最大20件までしか取得していないような気がしてきて、20件以上の住所がある番号を探し出して住所を取得してみました。いろいろ調べた結果、同一番号の最大件数は66件で愛知県清須市です。やってみると20件までしか取得することができません。
郵便番号検索サイトをよく読むとリクエストパラメーターとして
limit:最大件数:同一の郵便番号で複数件のデータが存在する場合に返される件数の上限値(数字) ※デフォルト:20
とありました。この上限値を増やせばいいのだろうと思いましたが、パラメーターの記述方法がよくわかりません。
またまた、調べまくってどうやらリクエストの郵便番号の後ろに続けて「&limit=80」で良いのではなかろうかと思い、リクエストのテキストを書き換えたところ成功!これで清須市の66件もすべて表示できるようになりました。FileMakerオンリーな私はこんなところで苦労します。
他のサービス
他にフリーで使えるサービスがないか調べてみました。
「zipaddress.net」というサービスがあったので試してみましたが、うまくいきませんでした。JSON形式でデータを取得できるのですが、何が書いてあるかわかりません。言語のパラメータにローマ字があったのでそちらを使うと上手く行きましたが、住所表記がローマ字です(当たり前です)。日本語の場合は文字コードがうまく変換されていない感じで、元はUTF-16のコードのようです。サイト内の記述に「利用は自由ですが、勉強のために作ったものです。」とありました。
本家の日本郵便でもサービスがありました。JSONではなくCSVかXMLでした。CSVなら少し馴染みがあるので試しましたが、完全に文字化け。文字コードがEUCとなっていました。XMLも試しました。文字コードがUTF-8なので無事に日本語で表記されていました。ただ、京都市の通り名など
京都府京都市上京区一町目(上長者町通堀川東入、東堀川通上長者町上る、東堀川通中立売通下る)
と1行に表記されていて、郵便番号から住所を入力するのには不向きです。
「602-8064」はエラーになりました。ハイフンなしにしなければならないようです。ちょっとしたことですが、不親切だなあと感じます。
日本郵便の郵便番号や住所の検索サイトも細やかさがなく、使いづらい印象を持ちます。
Macを使い始めた頃はNEC拡張文字やIBM拡張文字の文字化け、改行コードの違いに泣かされていましたが、最近はほとんど気にすることがありませんでした。久しぶりに文字コードの問題に引っ掛かってしまいました。
バーチャルリスト
取得したJSONデータから住所を取得できたのですが、複数の場合にどのように表示するかを考えなければなりません。
住所を格納するテーブルを作成してもいいのですが、その都度レコードが増えていくことになります。重複のチェックをして同じ番号があれば新規レコードを作らないようにすることもできますが、郵便番号のデータが最新のものとは異なる可能性が出てきます。
住所を入力するまでの一時的なものなのでバーチャルリストにすることにしました。
バーチャルリストとは
FileMakerにバーチャルリストという機能があるわけではありません。一時的なリストを作成するための手法のことです。
バーチャルリスト用のテーブルに予め必要と考えられる最大数のレコードを作成しておきます。表示したい値をグローバル変数などにしてバーチャルリストのフィールドに格納するという仮想的なリストになります。グローバル変数を空にすれば何も表示されなくなります。
スクリプトを変えることによって種類や用途の異なる様々なデータを一つのテーブルを利用して表示できるようになります。
バーチャルリストの作成
バーチャルリストの作り方は幾つかの手法があるようですが、ここでは繰り返しの計算フィールドを利用します。複数のフィールドを使うとその分、計算式を入力しなければなりません。繰り返しフィールドであれば計算式も繰り返し番号を指定すれば1個で済みます。繰り返し数は20にしてあります。ちなみに繰り返しフィールドの繰り返し数は最大32,000と記載されていました。
バーチャルリスト用のテーブルを作り、レコードを200件ほど作成します。IDとして1から200まで数字を入力するようにしておきます。このIDは表示するリストの上限を決めるリレーションキーになるので、必ず数字にしておいてください。
/*グローバル変数を使った場合。非繰り返しフィールドにはExtend (フィールド)が必要、$$変数には不要。*/
Let (
[
/*$$配列VLは整形された住所の配列。1件1行*/
v行 = GetValue ( $$配列VL ; Extend ( ju02_VLID ) );
/*Get ( 計算式繰り返し位置番号 )は最初の繰り返し位置は「1」*/
v繰返し番号 = Get ( 計算式繰り返し位置番号 );
/*区切り文字として「|」を使っている*/
v区切り位置01 = Position ( v行 ; “|” ; 1 ; v繰返し番号 );
v区切り位置02 = Position ( v行 ; “|” ; 1 ; v繰返し番号 + 1 )
] ;
Middle ( v行 ; v区切り位置01 + 1 ; v区切り位置02 – v区切り位置01 – 1)
)
これが繰り返しフィールドの計算式です。
|440-0062|愛知県|豊橋市|東田町西郷|¶
|440-0062|愛知県|豊橋市|東田町中郷|¶
|440-0062|愛知県|豊橋市|東田町西脇|
というように取得したJSONデータからバーチャルリスト用の配列データに整形していきます。JSONデータから必要な値を取得し、値と値を区切り文字で区切ります。ここでは「|」を使っています。区切られた値を繰り返しフィールドの繰り返し位置を指定して表示します。1行が1レコードに割り当てられます。
レイアウトされたフィールドは繰り返し番号を指定することができます。ここでは繰り返し番号[5]を指定しています。[5]は郵便番号、都道府県、市区町村、町域を繋げている5番目の繰り返し位置です。
インスペクタのデータから「繰り返しを表示」で指定できます。
サンプルには住所を表示する繰り返しフィールドが2個あります。1個はトリガーに設定したスクリプト用でグローバル変数を利用します。
もう一つはステップ確認のスクリプト用でグローバルフィールドを利用します。特別な意図がなければグローバル変数の方が良いと思います。
● ● ●
初めてのJSONで悪戦苦闘しましたが、勉強になりましたし、少しは理解できたような気がします。
ガラスに映る向かい合わせのビルがテキスタイルのパターンのようでシャープなビルと対照的。
iPhone 11 Pro 6mm ISO20 1/1000 F2.0 0.0EV P
heif
2020/3 Chiyoda Ward