FileMaker - 任意のレコードを選択して絞り込む

今回は行頭のチェックボックスにチェックを付け、対象行を絞り込む方法をご紹介します。
今回の実装方法はFileMaker Pro13から追加された集計の「一覧」を使用しているため、Ver.13以上以上であることが条件になります。
> サンプルファイルに一部不具合があり、修正して差し替えました。(2015.10.06 16:42頃)

#概要
最初に実際の動作を簡単に説明しておきます。
下の画像のように、チェックを付けた行だけに絞ります。

![選択絞り込み.png](https://qiita-image-store.s3.amazonaws.com/0/68589/a5e796c5-791b-da6e-a1b4-82b8c2ce41f8.png "選択絞り込み.png")

その他に対象の全レコードにチェックを付けたり外したりする機能も含めてみました。

まあ良くある機能なのですがファイルメーカーで単純に各レコードにチェック用フィールドを作って実装すると、全レコードのチェックを初期化するときなどに動作が重くなってしまいます。（経験談 (^0^;) ）
そこで、もっと仕組みが単純でパフォーマンスの良い方法を考えてみた結果が今回の実装方法です。

それでは順番に説明していきたいと思います。

#詳細説明
##テーブルの定義
今回は顧客テーブルをサンプルとしますが、ユニークなキーフィード（今回は"ID"）があれば同様に実装可能です。

今回の実装に関係するフィールドについてのみ説明します。
追加するフィールドは3つです。

![フィールド定義.png](https://qiita-image-store.s3.amazonaws.com/0/68589/080d810e-697b-e8bd-494c-55c3c254d0f0.png "フィールド定義.png")



1. 選択された行のID値をリストで保持するグローバルフィールド(gSelectedIDs)
	このフィールドはテキストのグローバルフィールドとして定義しているだけです。
	
2. 現在の行が選択されているかを示す計算フィールド(cIsSelected)
	このフィールドの計算式は以下のように設定しています。
	> **PatternCount ( "¶" & gSelectedIDs & "¶"; "¶" & ID & "¶" )**
	
	要は選択値の中に現在の行のIDが含まれていると1。含まれない場合は0が設定されるように設定しています。
	リストの前後に改行マークを付加することで、各行全体と比較するようにしています。
	**(ID=1に対して、11とか12とかがカウントされない）**
	
	
3. 全レコードにチェックをつけたり、判定するための集計「一覧」フィールド(sIDs)
	このフィールドは集計の「一覧」として定義しているだけです。

##リレーション定義
レコードの絞込用にリレーションを1つだけ定義します。
![リレーション定義.png](https://qiita-image-store.s3.amazonaws.com/0/68589/1186fbf7-50d2-a52c-6804-928616f95dbe.png "リレーション定義.png")


##スクリプトの定義
今回スクリプトは4つ作成しています。順番に説明していきます。
スクリプトの名称はイケてないのでご自由に変更して下さい。

###「Startup」スクリプト
選択行をクリアして初期レイアウトを表示しています。
また、絞り込みを解除しています。

```FMScript:スクリプト名「Startup」
1 フィールド設定 [ 一覧選択::gSelectedIDs ; "" ] 
2 レイアウト切り替え [ 「顧客一覧」 (一覧選択) ]
3 全レコードを表示
```

###「選択行のみ表示」スクリプト
選択された行だけに絞り込むためのスクリプトです。
前述したリレーションを元に、関連レコードへ移動スクリプトステップを使用して絞り込みを行います。

```FMScript:スクリプト名「選択行のみ表示」
1 レイアウト切り替え [ 「顧客一覧_絞込用」 (一覧選択_絞り込み用) ]
2 関連レコードへ移動 [ 関連レコードのみを表示 ; テーブル: 「一覧選択」 ; 使用するレイアウト: 「顧客一覧」 (一覧選択) ] 
```

###「一行対象」スクリプト
各レコードの先頭にあるチェックボックスをクリックした時に実行されるスクリプトです。
チェックされていない場合は、gSelectedIDsフィールドに自身のIDを追加。
チェックされていた場合は、削除します。

```FMScript:スクリプト名「一行対象」
1 # 選択されていない場合は追加
2 # 選択されている場合、対象がリストの最後のIDの時だけは、直前の改行文字を削除。それ以外は後ろの改行文字を削除する
3 フィールド設定 [ 一覧選択::gSelectedIDs ; 
  If( 一覧選択::cIsSelected;
    Let (
      [
        ~excludedValues = Substitute( ¶ & 一覧選択::gSelectedIDs & ¶ ; [ ¶ & 一覧選択::ID & ¶ ; ¶ ] )
      ]; 
      Middle ( ~excludedValues ; 2 ; Length ( ~excludedValues ) - 2 )
    );
    List ( 一覧選択::gSelectedIDs; 一覧選択::ID )
  )
]
```

###「全行対象」スクリプト
全行を対象にチェックを付けたり、外したりします。
全行チェックの確認には、集計フィールド"sIDs"を利用しています。

```FMScript:スクリプト名「全行対象」
1 # 全行を対象に、すでに全行が選択されている場合は選択を解除し、そうで無い場合は選択状態にする
2 If [ Exact ( 一覧選択::sIDs & ¶ ; FilterValues ( 一覧選択::sIDs ; 一覧選択::gSelectedIDs  ) ) ] 
3 	# 全行選択されている場合は全行解除
4 	フィールド設定 [ 一覧選択::gSelectedIDs ; "" ] 
5 Else
6 	# 全行選択されていない場合は全行選択
7 	フィールド設定 [ 一覧選択::gSelectedIDs ; 一覧選択::sIDs ] 
8 End If
```

##レイアウトの定義
ボタンとチェックボックスに関する定義だけが今回の対象です。

###「選択行のみ表示」ボタン
前述したスクリプト「選択行のみ表示」を実行するように定義します。
![選択行のみ表示ボタン.png](https://qiita-image-store.s3.amazonaws.com/0/68589/72642f9f-49dd-2c4a-05b2-bf3a5217842b.png "選択行のみ表示ボタン.png")


###「全行表示」ボタン
こちらは単一ステップで、「全レコードを表示」を実行するように定義します。
![全行表示ボタン.png](https://qiita-image-store.s3.amazonaws.com/0/68589/411d5f9e-4700-620e-fad8-d5a348b4f995.png "全行表示ボタン.png")

###各行のチェック表示
今回のチェックボックスは、ファイルメーカーのチェックボックスを使用していません。四角の枠は図形の四角形を使用し、テキストのチェックマーク「✓」の表示・非表示を切り替えることで実現しています。
表示・非表示の判定にフィールド「cIsSelected」を使用しています。

![チェックの表示判定.png](https://qiita-image-store.s3.amazonaws.com/0/68589/899a71af-2c3f-eb6e-a91f-7f13fd175e30.png "チェックの表示判定.png")

###各行の選択状態変更
各行のチェックボックス用に配置した四角形をボタンとして定義し、前述したスクリプト「一行対象」を実行するように定義します。
![各行状態変更ボタン.png](https://qiita-image-store.s3.amazonaws.com/0/68589/b8d8bd40-f406-6622-daf6-2d8072b0da6e.png "各行状態変更ボタン.png")

###全体のチェック表示
このチェックマークも先ほどと同じでテキストを表示・非表示切替しているだけですが、判定は対象行の一覧と選択行の一覧が一致しているかで判定しています。
![全行チェックの判定.png](https://qiita-image-store.s3.amazonaws.com/0/68589/5035215b-aad4-8074-283c-8fe8cb5eedf5.png "全行チェックの判定.png")


###全体の選択状態変更
全体のチェックス用に配置した四角形をボタンとして定義し、前述したスクリプト「全行対象」を実行するように定義します。

###選択行の色づけ
これは、条件付き書式が使用できるボタンオブジェクトを行の最背面に配置することで実現しています。


説明は以上です。
これらの設定をすることで任意行の選択絞り込みが出来るようになりますので、是非応用して活用してみて下さい。

今回のサンプルは以下の場所に置きましたので、詳しくはファイルを参照して下さい。
記述ミスやバグなど見つけましたら是非お知らせ下さい。
[サンプルファイル](http://it-komons.jp/filemaker/samples/ListSelected.zip)