FileMakerでタグ的なフィールド

FileMakerでよく使う定番の小ネタがあります。タグ的なフィールドの仕組みもその一つ。キーワードとかタグとか言われているメタデータ的なアレです。レコードにタグ付けを行い、素早くフィルターして絞り込めるようになります。

タグ的なるもの

ここで取り扱うタグ的なものは、専用テーブルで展開するような立派なデータではなくて、フィールド内のテキストだけで済ませるシンプルなものです。

タグ的フィールド
カンマで区切られたテキスト

表示と入力

表示はカンマ区切りになります。入力はカンマ区切りでも改行区切りでもどっちでもOK。

テキスト入力で登録しますが、登録済みのリストからポップアップやチェックボックスで追加や削除を行いたいところ。

ポップアップでは、タグ欄に入力済みの言葉を選べば取り除き、入力されていない言葉を選べば入力される仕組みです。

ポップアップによる入力
入力と取り除きがトグルで行えるポップアップ

チェックボックスではチェックを付けたり外したりするだけ。

チェックボックスでの入力
チェックボックスでの入力

簡易フィルタ

タグやキーワードはフィルタしてなんぼです。簡易フィルタ機能を備えましょう。ポップアップまたはチェックボックスでフィルタします。後ほど。

仕組み

二つのフィールドと一つの値一覧

まず二つのフィールドで成り立ちます。tagsフィールドとtagsDispフィールドです。tagsフィールドは計算式フィールド、tagsDipsはテキストフィールドですが計算式が含まれます。名前はどうでもいいのですが話がし辛いのでこれで行きます。他にkeywords と keywordsDisp なんてのもありです。

レイアウトに表示するのは tagsDisp で、入力と表示を司ります。tags は、tagsDips から計算によって作り出され、データ登録の要となります。

tagsDisp

tagsDispは表示と入力に使います。入力の際のルールは、タグの区切りをカンマまたは改行とします。テキストフィールドですが計算式を仕込みます。それは Self の形を整えます。

計算式では、Substitute で置換してから少し整形します。

  • “,”(カンマ)があれば、”, “(カンマ+スペース)に置換
  • “,  “(カンマ+スペース2個)があれば、(カンマ+スペース)に置換
  • “¶”(改行)があれば、 “, “(カンマ+スペース)に置換
  • 次に、テキストの最後2文字が “, “(カンマ+スペース)なら、その2文字を取り除く

カンマ、カンマ+スペース、改行、いずれの方法で入力しても、結果はカンマ+スペースで区切られたテキストになります。

Let ( [
 tagsD = Self ;
 tagsD = Substitute ( tagsD ; [ "," ; ", " ]; [ ", " ; ", " ]; [ ¶ ; ", "] );
 tagsD = If ( Right ( tagsD ; 2 ) = ", " ; Left ( tagsD ; Length ( tagsD )-2 ) ; tagsD )
 ]; tagsD )

野蛮な計算式ですがこうしています。

tags

tagsは計算式フィールドで、レイアウト上に表示する必要はありません。ただし後で述べるフィルタ(検索)のためにレイアウトの外に配置しておくのが望ましいです。tags は tagsDisp の内容から計算して生成されます。

tagsDisp の “, “(カンマ+スペース)を ¶(改行)に変換します。ただそれだけです。これにより、tagsフィールドは、改行テキストつまりリストになります。リストにすることで、値一覧に登録することができます。

値一覧 tags

値一覧をひとつ作成し、対象フィールドを tags に指定します。tagsフィールドは改行テキストのリストですので、値一覧には入力済みのタグが内部的に登録されるという案配です。

値一覧作成画面
値一覧tagsを作成する – tagsフィールドを指定するだけ

(FileMakerでは以前からときどきボタンが潰れたり文字が読めなくなることがあります。原因は知っていますが作りの雑さはもう諦めてます)

入力補助のスクリプト

ポップアップによる入力

まず入力用のグローバルフィールド「入力用グローバル」を一つこしらえて、フィールドの隣に配置、スタイルをポップアップメニューにして値一覧 tags を表示させ、スクリプトトリガをセットします。

スクリプトトリガはこんな感じ。

スクリプトトリガ

OnObjectEnter に「ウインドウ再表示」を割り当てています。このスクリプトは「ウインドウ内容の再表示」ステップだけが記されています。触った途端に更新されるようにそうしています。グローバルフィールドを使い回すので。それだけの理由です。

OnObjectExit には、ウインドウへ移動(行き先指定なし)と再表示の2ステップのスクリプトをセット。ポップアップのフィールドがいつまでもアクティブになっているのが不細工ですからこうしています。

肝心なのは OnObjectModify にセットした「値一覧からpopup入力」スクリプトです。

値一覧からpopup入力

このスクリプトを生かすために、事前準備としてスクリプト引数に対象フィールド名を指定します。対象フィールドは入力・表示用の tagsDisp フィールドです。“TagLike::tagsDisp” のように、テーブルも含めた正確なフィールド名を “” で囲んで書いておきます。わざわざスクリプト引数に対象フィールド名を入れるのは、スクリプトに汎用性を持たせるためです。

スクリプトの流れは次の通り。まず変数を用意します。

  • 変数 $fld に Get(スクリプト引数) – 対象のフィールド名
  • 変数 $item に Get(アクティブフィールド内容) – 選んだアイテム
  • 変数 $itemC に、Get(アクティブフィールド内容)  &  “, ” – カンマ付きのアイテム

tagsDispは区切り表示がありますから、区切りを含めない $item と 含める $itemC をそれぞれ保存しておくのです。

そして、if を使って順に処理します。

  1. $fld に $itemCがあれば $itemC を削除
  2. $fld に $itemがあれば $item を削除
  3. $fld に $item がなければ…
    1. $fld内容が空なら→ $item を追加
    2. $fld内容が空でなければ→ 改行と $item を追加

やや野蛮なスクリプトですが、ポップアップから選んで追加したり消したりできるようになりました。

チェックボックスによる入力

キーワードやタグって、ポップアップよりチェックボックスでの入力が望ましいと思えるかもしれません。

ポップアップと同じく、グローバルフィールド「入力用グローバル」に表示させましょう。表示するのは、改行テキスト即ちリストであるところの tags フィールドです。「そのレコードのtags」です。

チェックボックスのレイアウト
チェックボックスのレイアウト
チェックボックスのレイアウト - ポップオーバー使用
ポップオーバーを使用したレイアウト

チェックボックスはアイテムを見渡せるし操作が簡単ですが、その分レイアウトの場所を取ります。また、アイテムが増えたときにスクロールできない欠点もあります。ポップオーバーでは多少緩和されますが、アイテムが大量に作られるような想定だと、やはり専用テーブルを用いた方法が良いかもしれません。

チェックボックスのためのスクリプトは2つ必要で、一つ目はグローバルフィールドにそのレコードの現在のtagsを表示させます。二つ目はチェックを tagsDisp に反映させます。

チェックボックス表示のスクリプト

グローバルフィールドにtagsフィールドを表示さます。何かと汎用性にこだわる筆者は、ここでもスクリプト引数を使います。スクリプト引数に対象のフィールド名をフルで書いておくことで、同じ目的のフィールドが増えても引数を変更するだけで対応できます。ここでは “TagLike::tags” と括って書きます。それから、ウインドウ内容の再表示を必ず追加します。

tags をグローバルフィールドに転記させるスクリプト
tags をグローバルフィールドに転記させるスクリプト

チェックボックス内容を表示させるこのステップは、もしレイアウト上に直接置くなら(上図の上) OnRecordLoad に、ポップオーバーで一手間かけるなら(上図の下)ポップオーバーのウインドウの OnObjectEnter に仕込みます。

チェックボックスのスクリプト

グローバルフィールドの OnObjectModify にセットするチェックボックス反映のスクリプトです。

まずその前に例によってスクリプト引数には、入力用であるDispのフィールドを指定しておきますね。“TagLike::tagsDisp” です。汎用性のためです。

変数 $item に Get(アクティブフィールド内容) を指定します。見た目はチェックボックスですが、実際の内容はチェックを付けたアイテムの改行テキスト即ちリストです。

次にフィールド設定です。スクリプト引数に指定したフィールド名、ここではtagsDisp ですが、その内容をすべて $item で置き換えます。

チェックしたもの外したもの、それらを一個ずつ判断するのではなく、フィールド全部を置き換えるわけです。単純な話です。

チェックボックス反映スクリプト
チェックボックス反映スクリプト

フィルター

タグやキーワードを付けるのはフィルタするためですね。簡易なフィルタを実施しましょう。グローバルフィールドを一つこしらえてフィルター用に使います。

基本、検索するだけです。検索対象となるフィールドは改行テキストの tags フィールドです。レイアウト上に表示する必要はないけど、レイアウトの外にフィールドを置いておきましょう。検索するとき、検索モードで「フィールドを名前で設定」スクリプトステップを使うからです。フィールドがないと検索できません。

ポップアップによるフィルタ

ポップアップによる検索
ポップアップによる検索

ポップアップメニューで選んだタグを検索します。検索するだけのシンプルな仕組みですが、検索語の書き方に一工夫いります。

というのも、例えば「タグ」「タグ1」「タグ2」というタグがあったとして「タグ」で検索すると全部ヒットしてしまいます。また、検索モードで「==タグ」としても駄目ですね、複数行のタグあればイコールにならないのでヒットしません。「”タグ”」と囲っても上手くいきませんでした。「タグ」と同じ結果になってしまいます。これは困ったな。

検索って難しいですね。「 *”タグ”」これで何とかなりました。「”タグ”*」これでも何とかなりました。どうも腑に落ちず納得できないんですが、現時点で最良と思えますので採用しています。もっと良い書き方をご存じの方は教えてください。

というわけでスクリプトはこんなのですが、これをトリガ OnObjectModify にセットしています(例によって、対象フィールド名をスクリプト引数としています)

チェックボックス絞り込みのスクリプト
チェックボックス絞り込みのスクリプト

チェックボックスによるフィルタ

チェックボックスによるフィルタ
チェックボックスによるフィルタ

チェックボックスでのフィルタでは、もうちょっと複雑なことを目指す必要があります。複数のチェックをした場合に「絞り込み」にしたいんです。

or 検索なら簡単ですが、and 検索にしたい場合にどうしましょ。「絞り込み」を使います。スクリプトは次のようにしました。

  • チェックされたアイテムが1個なら普通に検索
  • チェックが二つ以上なら、最初のアイテムで検索した後、次のアイテム以降は絞り込み検索を繰り返す

最初にチェックアイテムをリスト化して行数を測ります。

チェックボックス絞り込みのスクリプト
チェックボックス絞り込みのスクリプト

検索の指定って難しいですね。


以上、タグ的なフィールドについてざっくりかつ詳細に書きました。実は以前同じ内容の投稿をしていました(書いたことを忘れていたらしい)→FM メディア管理 – キーワード

ほとんど同じことを書いていますが、異なるところもあります。こっちの投稿が新しいので、ちょっとは洗練されたし、読みやすい構成になったかな。どうかな。

尚、ここで使用したファイルをダウンロードできます。ワンイシューファイルなので判りやすいと思います。

Download TagLike.fmp12.zip

 

このエントリーをはてなブックマークに追加

コメント

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください