FileMakerでファイルを作るときにいつも必ず使う小ネタ・小技があります。今回はウインドウサイズの話題です。
このページ内の見出し
最適化すること
昔Macに「ウインドウ最適化ボタン」というスマートかつエレガントなボタンがありました。


最適化ボタンは緑ボタンに引き継がれましたが、その後「最大化」に落ちぶれ、やがてフルスクリーン化という酷い最後を遂げました。
今でも最適化機能はかろうじて残っていて、タイトルバーのダブルクリックがそれです。アプリによりますが下品に最大化されてしまったりエレガントに最適化されたりします。
FileMakerのスクリプトステップに同じ機能あります。「ウインドウの調整」の「収まるようにサイズ変更」がそれです。

レイアウトモードで作成したサイズがデフォルトとして「収まるサイズ」になります。フォーム表示の場合は幅と高さ、リストや表の場合は幅が合致して高さがディスプレイの高さになります。
ウインドウを最適化させたいとき、基本、このスクリプトステップ1行で事足ります。
とはいえ、トリガ(OnLayoutEnter)に仕込んだり、「レイアウト切り替え」を行うスクリプトの中に混ぜ込んだりもしたいので、スクリプトを作っておくのがよろしいですね。そして最適化の1行だけでは不足を感じることもあります。
ウインドウサイズ関連のスクリプトステップにはもうひとつ「ウインドウの移動/サイズ変更」があります。

こちらはウインドウの位置やサイズを計算で調整できます。
ウインドウを最適化させるスクリプトを作る際、これらステップを使ってちょいと工夫を凝らします。
ということで、今回はウインドウサイズを最適化する話ですが、そもそもウインドウサイズを最適化することに興味なければどうでもいい話題でございます。
FileMaker で最適化すること
スクリプトを使ってウインドウサイズを最適化させることに凝り出すと、だんだん深みにはまっていきますが順を追っていきましょう。
LEVEL 1: さくっと最適化
「収まるようにサイズ変更」を使うだけですが、リストや表の表示ではわずかに手間をかけます。
LEVEL 2: 記憶と再現
ウインドウサイズを手動で変更することもあります。記憶させます。
LEVEL 3: こだわりのリスト表示
リスト表示の高さをより詳細に制限します。
ではいきます。
LEVEL 1: さくっと最適化
収まるようにサイズ変更
スクリプトステップ「ウインドウの調整 – 収まるようにサイズ変更」は、表示方法によって最適化の挙動が異なります。
フォーム形式の場合はレイアウト編集で定めたサイズ、リスト形式や表形式では縦が画面いっぱいになります。
リストや表の縦サイズは、画面の小さなノートタイプでは気になりませんが、大きなデスクトップでは縦が長すぎると感じることがあるので、縦サイズを制限したくなります。
ウインドウの移動/サイズ変更
そこで、一度「収まるようにサイズ変更」してから、続けてウインドウサイズを調整します。ウインドウの移動/サイズ変更です。
スクリプトの流れはこうですね。まずは表示方法によって分岐させます。
ウインドウの調整[ 収まるようにサイズ変更 ] if [ Get (レイアウト表示状態) = 0 ] #フォーム表示の場合 else if [ Get (レイアウト表示状態) = 1 ] #リスト表示の場合 else if [ Get (レイアウト表示状態) = 2 ] #表の場合 end if
ここで注意すべきポイントは表示形式で条件分岐してるのに関数が「表示状態」なところです。→ FileMaker ウインドウに関する忘れがちな用語のまとめ – 表示方法・表示形式・表示状態
高さを制限
個人的な感覚にすぎませんが、27インチ以上のディスプレイで縦いっぱいにリストや表が広がるのが鬱陶しいんです。
リストや表では高さ1100pxくらいに収まってくれると見やすいなと思ったりしますので、サイズと位置の高さを指定してみます。
if ( Get ( ウインドウ高さ ) > 1100 ) ウインドウの移動/サイズ変更 [現在のウインドウ ; 1100 ]
こんな感じで制限掛けてます。これを、上記の条件のリストと表にあてがいます。・・・高さいっぱいに広がることに抵抗ある人も少ないと思いますが。
さくっと最適化スクリプトはこんな感じになりました。
この簡単なスクリプトをどのように利用するかというと、まずボタンに仕込むとエレガントな「ウインドウ最適化ボタン」になります。
レイアウトを開いたときに発動するトリガ OnLayoutEnter に仕込むこともあります。
OnLayoutEnter に仕込むといかなる場合にも問答無用で最適化されてしまいますから、別のよく使うスクリプト「レイアウト切り替え・最適化バージョン」に付け加えたりもします。
話それますが、OnLayoutEnter にはむしろ「ウインドウタイトル」を必ずセットしています。
Get ( ファイル名 ) & " - " Get ( レイアウト名 )
話それ続けますが、同じウインドウタイトルが複数発生する場合に備えて WindowNames関数を使って同じウインドウ名を発見したら連番を入れるなどの・・・(話がそれすぎるので以下削除)
LEVEL 2: 記憶と再現
最適化をOnLayoutEnterに仕込むとレイアウトが切り替わる度に問答無用で最適化されてしまいます。
それで挙動は合ってるのですが、ウインドウサイズを手動で広げたり縮めたりすることもよくあります。行って帰ってきたときにはそのサイズを保持してほしい。最適化されたくない。そこで、さらに工夫をします。
ウインドウサイズを動かしたときにそれを保存し、レイアウトを戻ったときに再現するスクリプトを作りましょう。
さてこの項は根本的に矛盾に満ちています。
OnLayoutEnterにセットして最適化させたのに、手動でサイズを変更したらそれに合わせたい。それならOnLayoutEnterに仕込まなければいいのです。それが一番の解決方法です。
レイアウト毎あるいはテーブル毎に調整
でもあえてそれを行いたいときがあります。レイアウト毎あるいはテーブル毎にそれぞれ自動最適化や手動保持をしたい場合です。
基本は自動で最適化を行う。手動でサイズを変更した場合はそれを記憶して再現する。
こんなマニアックな需要があるのかどうか分かりませんが試みたことはあります。
ウインドウサイズを記憶する
手動でウインドウサイズを動かしたとき、それを記録します。スクリプトトリガに OnLayoutSizeChange ありますね。サイズを変えたら発動します。ファイルメーカーさんったら、完璧に想定済みなのでございますね。
OnLayoutSizeChange
OnLayoutSizeChangeにセットするウインドウサイズと位置を記憶するスクリプトを一つ作りましょう。順序よく判りやすく書くとこうです。
1 変数に幅(または内容幅)をゲット。
2 変数に高さ(あるいは内容高さ)をゲット。
3 変数に上位置をゲット。変数に左位置をゲット(必要なら)
4 その他必要と思われる数値をゲット(必要なら)
5 グローバル変数「$$レイアウト名」に上記の値を改行で繋げたものを作る。
最後に変数名「$$レイアウト名」という不穏な言葉が出ましたが、これはグローバル変数の名前を「レイアウト名」とすることで、どのレイアウトの変数なのかを明確にします。$$レイアウト名 & “ウインドウ” みたいに分かりやすい名前にしたほうがいいかもしれません。
えっ。変数の名前にレイアウト名を含めるって? 計算式で変数名を作ることなんて出来るのか?はいできます。
余談:変数名を計算式で作るの巻
・・・と、ここに書き始めましたがまたまた長くなって余談の域を逸脱したのでポストを分けました。変数名を計算で作ることに興味のある方はこちらの投稿を参照ください。
ということでウインドウを手動で変更させたときに、グローバル変数「$$レイアウト名」にサイズが記憶されることになりました。
ウインドウを再現する
OnLayoutEnterトリガーに仕込む最初の条件分岐がありました。
ウインドウの調整[ 収まるようにサイズ変更 ] if [ Get (レイアウト表示状態) = 0 ] #フォーム else if [ Get (レイアウト表示状態) = 1 ] #リスト else if [ Get (レイアウト表示状態) = 2 ] #表 end if
まず1行目の収まるようにサイズ変更を取り払います。すべての場合に最適化するわけに行かなくなりましたから。以下のように一旦変更します。
if [ Get (レイアウト表示状態) = 0 ] #フォーム ウインドウの調整[ 収まるようにサイズ変更 ] else if [ Get (レイアウト表示状態) = 1 ] #リスト ウインドウの調整[ 収まるようにサイズ変更 ] ウインドウの移動/サイズ変更 [高さの制限] else if [ Get (レイアウト表示状態) = 2 ] #表 ウインドウの調整[ 収まるようにサイズ変更 ] ウインドウの移動/サイズ変更 [高さの制限] end if
手動サイズを保持したいのは大抵フォームの場合でしょうから、レイアウト表示状態 = 0(フォーム) の中を弄ります。グローバル変数「$$レイアウト名 & “ウインドウ”」が存在するかどうかの分岐を設けましょう。
こうなります。
#フォーム if [ IsEmpty ( Evaluate ( "$$" & Get ( レイアウト名 ) & "ウインドウ" ) ) ] #ウインドウサイズが保存されていないときは最適化 ウインドウの調整[ 収まるようにサイズ変更 ] else #保存されているときは再現する ウインドウの調整[ 現在のウインドウ ; 高さ: GetValue ( Evaluate ( "$$" & Get ( レイアウト名 ) & "ウインドウ" ) ; 2 ) 横幅: GetValue ( Evaluate ( "$$" & Get ( レイアウト名 ) & "ウインドウ" ) ; 1 ) ] end if
Evaluate ( “$$” & Get ( レイアウト名 ) & “ウインドウ” ) は、グローバル変数を名前で指定しています。ウインドウサイズを手動で調整した場合はこのグローバル変数が作られますから存在の有無で判断できます。
グローバル変数の値は「幅 ¶ 高さ ¶ …」と、改行で作りました。ですから、幅は1行目、高さが2行目にあります。それぞれ取得してセットしています。
フォームのウインドウ調整スクリプト
手動でウインドウサイズを変えていればグローバル変数に保存されていますからそれを再現します。変えた形跡がなければウインドウの最適化を行います。
以上、フォーム形式のウインドウでした。
別ポストの「変数名を計算式で作る」ことを前提としていますが、フォーム部分、こんな感じで収まりました。

OnLayoutEnterに仕込むも良し、別のレイアウト切り替えスクリプトに追加するも良し、面倒なのでこんなの無視するのも良しです。
そうそう、保持した値じゃなく普通の最適化をしたら、 $$レイアウト名&ウインドウ の変数をクリアしておかないといけません。最適化しても OnLayoutSizeChange が作動しますからね。
トグルボタン
さて最適化のボタンに割り当てるという話がありました。
ウインドウサイズを保持するスクリプトが出来上がった以上、このボタンの挙動に少し工夫を入れたいですね。
最適化↔保持サイズ のトグルになっていてほしい。そのためには、最適化サイズなのか保持サイズなのかを見極めてグローバル変数をセットしてそれに応じて分岐させるスクリプトをこのボタンに割り当てます。だんだん面倒になってきましたね。
LEVEL 3: こだわりのリスト表示
セルフポータル機能が付いて以来リスト表示を使うこともめっきり減りましたが、まだまだ使います。無骨でデータ剥き出し上等の表形式と事なり、リスト表示にはリスト表示なりの美しさの追求というものがあります。
高さ再考
高さについて冒頭で述べました。ウインドウいっぱいにまで縦が広がるのを好ましくなく思っているので高さを制限しましたと。
レコード数
リスト表示にもいろいろあって、レコードがたくさんある想定と、すごく少ないレコードの場合があります。考え方が異なります。
レコードが沢山ある場合のリスト表示は「美しい表形式」みたいな感覚です。この場合、大きなディスプレイでは高さを制限したいと考えました。
レコードが少ないってどういうことかというと、ファイルのランチャーだとか、値一覧で使用するような少ないレコードの一覧、ちょっとしたカタログみたいな、あるいは常にフィルタ前提で表示レコード数が10個とかそんなレイアウトの想定です。
レコードが少ない想定のリスト表示
ここでは、レコードが少ない、あるいは、絞り込み結果のレコードが少ないことが想定されるリスト表示について考えます。
例をあげてみようかしら。
全表示だとそれなりに表っぽくて良いんですが、このファイルは通常フィルタして絞り込んで使うようなタイプなので、下の空白が気になります。
もうひとつもっとわかりやすい例、FMランチャー&修復ユーティリティ(笑)なんですが、レコードは極端に少ないです。
キャプションで書いたとおりなんですが、リスト表示でファイルメーカーの用意した最適化を行うと真ん中の画像のように縦がびろーんと伸びてしまいます。
実はFinderというかMacの最適化(タイトルバーのダブルクリック)では理想の形になります。
理想の形に整えたい。
レコード数に応じたウインドウサイズ調整
凝り始めるとキリがないんですが、どうしたいのかわかりました。レコード数とウインドウ高さを連動させたいんです。
フォームのところでGet(ウインドウ幅)とGet(ウインドウ高さ)を得て再現しましたが、リスト表示ではもうちょい複雑になります。
パーツの高さを得る
まず前段階としてFileMakerのパーツの高さを知ります。
ツールバー、ヘッダにフッタ、そしてボディや使用した各パーツの縦サイズをあらかじめ知って(グローバル変数またはグローバルなフィールドに)登録しておきます。このために名前やサイズを調べたのさ。→ FileMaker ウインドウに関する忘れがちな用語のまとめ
何をしているかもうお判りですね。最適化直後のウインドウ高さと、使用可能なスペースの中でレコードボディの高さ×対象レコード数を含むパーツ高さ合計を比較して、大きければ適当に縦サイズを縮めて、小さければボディ高さから見積もった最適サイズまでウインドウを縮めるのです。ツールバーは表示非表示どちらにも対応できるようにしておきます。
まあ、しかしですね、こんなことのためにいろいろゲットしたり変数仕込んだり条件分岐したり、わしあほとちゃいますかねえ。

この例ではリスト表示がひとつしかないので少ない行数で収まっていますが、ちょっと非効率です。リスト表示のレイアウトが複数ある場合なんかだと対応が変わります。
レイアウト管理テーブル
深みにはまるとこうなるという例です。レイアウトを管理するテーブルを作ります。

レイアウト管理テーブルでボディ、ヘッダ、フッタ、ステータスエリア(グローバル)を記しておき、スタートアップ時にすべてのリストレイアウトのサイズをグローバル変数に記録しておきます。この準備により、リストレイアウトのOnLayoutEnterでは高さを調整するスクリプトを発動させ、美しい最適化を実現させます。
レイアウトは日々追加したり削除したり名前を変更したりします。レイアウトリストをテーブルに作成することそのものをスクリプトで自動化させます。
レイアウト名リスト作成スクリプト
まず「レイアウトリスト」というグローバルフィールドを作っておきレイアウトリストを記入します。関数 LayoutNames() を使います。
リストをレコード化するスクリプト
次に、レイアウト名リストをループで分解してレコード化します ・・・詳細は割愛します。リストテキストのレコード化ってほんとよく使います。
フィールドデータを取得するスクリプト
レイアウト名リストのテーブルには、レイアウト番号、表示タイプ(フォームやリスト)それから各パーツのサイズ、グローバルなツールバーサイズなどのフィールドを用意しています。これらを自動計算一部手動で記入します。フィールドの計算式や、取得するスクリプトを使います・・・詳細は割愛しますが。
不要レコードを削除するスクリプト
さらに既存レコードをチェックして削除されたレイアウト名(リストにないもの)を削除します。これもループでチェックしています。
これらをまとめたスクリプトをボタンに割り当てたりレイアウト一覧レイアウトのトリガに仕込んだりして、レイアウト情報を最新に保ちます。
いったい何のためにここまで手間をかけるのか。それは不問にしてください。
以上、リスト表示のウインドウサイズ最適化でした。
さて次は表形式について。と言いたいところですが、これはどうでもいいです。表は無骨さが売りのデータ中心主義で作られます。見た目の変な工夫をしないほうがスッキリします。
ということでウインドウサイズの調整についてでした。こんなのはまあ、どうでもいいと言えばどうでもいい話ですが、いや、どうでもよくない。ところでトップで寝そべっているのはとめ22歳、盲目で鼻炎。