マジックキー (パート1)

以前ご紹介したSelector-ConnectorによるFileMakerデータモデリングで、重要な要素技術となる「マジックキー」という手法について、Kevin Frankさんが2011年に書いたブログ記事をご紹介します。
(元記事に合わせて2回に分けて掲載する予定です。)


FileMaker Hacks logo

Magic Key, part 1

(元記事はこちら)

Kevin Frank
2011/7/31

今回はマジックキーと呼ばれる手法を紹介します。この手法を使えば関連レコードを柔軟に作成してデータを書き込むことができます。マジックキーという名前は、欧州のデベロッパーのUgo Di Lucaの命名によるものです。その詳細についてはこの後説明しますが、その前にまずこの手法の使いどころとなる実際の活用例を見ていきます。今までに、テキストフィールドに入力されたデータをチェックボックスセットとして扱ったシステムを作ったり、引き継いだりしたことはないでしょうか?

このアプローチには長所と短所があるのですが、短所の一つはこの形式で
蓄積されたデータは集計処理にとても手間がかかるという点です。ですがここでマジックキーを使えば、この手間を軽減することができます。今回のデモファイル magic-key-check-box-reportingをダウンロードして操作してみればわかるでしょう。(もちろん、いかなる理由があろうとテキストフィールドをチェックボックスセットとして扱うべきではないという考え方がありますが、その議論については今回は踏み込みません。)

この記事を読んでいる方はご存知だと思いますが、チェックボックスセットを使うと、テキストフィールドに1つ以上の値を挿入できます。複数の値が挿入された場合、それらは改行で区切られます。右の図は、実際のデータがどのようになっているかを示しています。チェックボックスセットには利点もあるものの、一つのフィールドに複数の値を保持することは第1正規形の要件(すべての“列とカラムの交点”は1つの値のみを持つ)を満たしていません。このデータの集計を行なうには、まず別の”tasks”テーブルにコピーする必要があります。

マジックキーがこの課題を解決できる唯一の方法というわけではないですが、おそらくもっとも合理的な方法でしょう。そして現時点(2011年)ではこの手法はどこにも記述されていないということをお伝えしておきます。私は2004年からこの方法に頼ってきたし、今まで問題が発生することもありませんでしたが、一応念のため、自己責任で使用してください

さあ、それではここにVolunteersテーブルがあり、いくつかのテキストフィールドに改行区切りの値が入っています。これらの値を分解してTasksテーブルに入れたいと思います。

そしてこの値を基準にして標準的な小計付きのレポートを作成します。

これでマジックキーを使った手法を試す準備が整いましたが、その前に、標準的な「レコードの作成を許可」したリレーションがどのようにふるまうかを復習しておきましょう。まずは、親テーブルの主キーと子テーブルの外部キーをイコール(=)のリレーションで結びます。

リレーションシップの子側の「レコードの作成を許可」のチェックボックスをオンにします。

Volunteersテーブルのコンテキストから、このリレーションを使って関連の子レコードを作成/更新する方法が2つあります。

方法A:作成/更新するレコードが1つだけでよければ、[フィールド設定]コマンドで子テーブルにいくつかの値を挿入します(例:フィールド設定[Tasks::category ; “Special Events”] )。関連レコードが存在しない場合、新規のレコードが作成され、リレーションを有効にするためにid_volunteerには適切な値が自動的に設定されます。

「レコードの作成を許可」をオンにすることによって、レコードが作成されると同時に自動的に外部キーに値が設定される

リレーション先のレコードに対して2つ目の「フィールド設定」を行うとき(例:フィールド設定[tasks::task ; “Sales for Survivors”])は、FileMakerは新規レコードを作成するのではなく、存在する関連レコードを見て、そのレコードを更新します。

方法Aの大きな特徴は、それが関連レコードが1つの場合のみ正しく動作し、既に複数の関連レコードが存在する場合は、1つ目のレコードしか操作できないということです。標準的な「レコードの作成を許可」するリレーションシップで複数の関連レコードを作成/更新したい場合は…

方法B:VolunteersレイアウトにTasksポータルを配置します。

「レコードの作成を許可」されているポータルの見分け方 — データが入った行の下に空の行が存在する

これで好きな数だけ関連レコードを作成できます。最初の空のポータル行で入力を始めるか「フィールド設定」を実行します。いずれの場合も、関連レコードのフィールドに値を入れると、自動的に新規の関連レコードが作成され、方法Aと同じように外部キーが自動的に設定されます。

標準的な「レコードの作成を許可」するリレーションシップのふるまいを復習できたところで、マジックキーの説明に進みます。お断りしておきますが、この手法はFileMakerの世界の法則に反するように見えるでしょう。リレーションシップグラフで初めてマジックキーのリレーションを見たら、「このデベロッパーは正気か?」と驚くことでしょう。

マジックキーを使用するための準備

1. 親テーブルに、グローバルテキストフ​​ィールドg_magic_keyを定義します。

2. リレーションシップグラフに新規のテーブルオカレンスtasks_createを置きます。

3. volunteersとtasks_createをリレーションで結び、tasks_create側の「レコードの作成を許可」チェックボックスをチェックします。

上のTOは関連レコード作成用。「レコードの作成を許可」はオン / 下のTOは関連レコード表示用。「レコードの作成を許可」はオフ

そう、間違いではありません。g_magic_keyはTasksテーブルの主キーと結合され、「作成を許可」をオンにしました。そして、Tasks::idにはシリアル値の自動入力が設定されています。

マジックキーの解説

この風変わりなリレーションシップをまたいで「フィールド設定」コマンドを発行したときに、一体何が起こっているのでしょうか? フィールドg_magic_keyが空だとすると、

  1. Tasksテーブルに関連レコードが1件作成される
  2. 「フィールド設定」で指定したフィールドに値が設定される
  3. Tasksの主キー(id)に、シリアル値の自動入力によって値が設定される
  4. Tasks::idの値が“マジックのように”g_magic_keyに逆流する

この時点でg_magic_keyはもはや空ではなく、volunteersとtasks_createのリレーションは有効な状態になります。つまり、この後に続く「フィールド設定」ステップは今作成したばかりのレコードを更新し、これを好きなだけ繰り返すことができます。

現在のレコードのフィールドに値を設定しおえたら、g_magic_keyの値をクリアし、再度一からプロセスを繰り返して必要な数の関連レコードを作成します。

マジックキーの活用場面

元々の目的に戻りましょう。どのようにして以下のデータを分解してTasksテーブルにコピーすればいいでしょうか?

今回の手順では、ネストされた3つのループを使用しています。

  1. 内側のループ:指定されたフィールドのすべての値を解析する
  2. 真ん中のループ:特定のレコードのすべての必要なフィールドを渡り歩く
  3. 外側のループ:対象レコード中のすべてのレコードを渡り歩く

ここまで読んだ方なら、おそらくすでに今回のデモファイルをダウンロードしたことでしょう。ファイルを開けば実際に動作するスクリプトを見ることができるので、ここではステップ1の内側のループ(マジックキーが使われている部分)だけを示します。

説明は以上です。この手法は他にも多くの応用先があります。その1つについて次回に検証します。次回の記事は今回よりも短かい予定で、a)上記のスクリプトの機能を「フィールド設定」の1ステップだけで実現するシンプルな改善策を示し、b)2人以上のユーザが干渉しあうことなく同時にレポートを作成できるようにするセーフティ機能を実装します。

Leave a Reply