カスタム関数、一歩及ばず

FileMaker Pro 7 以降で実装されたカスタム関数、便利ですよね。
すべてのロジックを計算式に書くと、ごちゃごちゃになるような時には、汎用部分を切り出して、カスタム関数化! ちょっとしたデータの加工などには最適です。

Developer/Advanced 版のみでしか、作成、編集、削除できないので、FileMaker Pro しか持っていないエンドユーザの現場ではいじられる心配のない点も Good!(笑)。でも、自社でデータベースのメンテをするのに、Advanced 版を持たないというのは、もったいない気もしますが。

Web 上の情報を徘徊しても、カスタム関数は人気の高い機能のようです。特に、再帰呼び出しができることで繰り返しの計算が可能になったことはインパクトがあったようですね。

使い勝手の面で、ちょっとした物足りなさは、ファイル間のコピーやインポートができない点でしょうかね。でも、ファイルをまたいで利用する関数が大量でなければ(7以降はファイル数はそんなに使いませんよね?)、大した手間ではありませんし、汎用の開発テンプレートに共有する関数を仕込んでおくという手もあります。

「一歩及ばず」の理由は、移植の問題ではありません。
人気の理由でもある再帰呼び出しの限界が問題なのです。

カスタム関数の再帰限界:合計 50,000 回まで。コールスタックの制限によって、呼び出しの深さが 10,000 までに制限されます。この制限を超えた場合、カスタム関数は「?」を返します。末端再帰は、適切に最適化されるため、末端再帰によってコールスタックのサイズが大きくなることはありません。
FileMaker Pro 10 および FileMaker Pro 10 Advanced の技術仕様

カスタム関数の作者がこの点を理解していれば、オッケー。あるいは、対象データからして、絶対に10,000回も再帰的に呼ばれることはないケースでも、まあオッケー。

カスタム関数と GetNthRecord 関数と組み合わせると、対象レコードや関連レコードを走査して値を取得できますが、単純に「引数には Get ( 対象レコード数 ) や Count ( 関連TO::関連フィールド ) を指定してね」的な使い方だと、再帰限界を超えてしまうケースはめずらしくないでしょう。

単なる動作サンプルなら問題ないですが、実際のソリューションではお客さんに「? が出てますが〜」と言われるようではいけません。そうしたリスクがある場合は、処理に時間がかかっても、レコード移動をループしながら値をかき集めるスクリプトだって、考えなければならないかもしれません(クリップボードを使う方法はもう止めましょう)。

カスタム関数が再帰呼び出しから抜けるためには、判断ができる引数が必要なので、上限以上の値が渡される可能性がある場合は引数をチェックするなり、ユーザにわかりやすいエラーを返すなりの対策を講じることも必要ですね。

ちなみに、値の連結や加算の出力を繰り返すような処理は、コールスタックの制限にひっかかるので、10,000回の再帰呼び出しが限界。10,000件の対象レコードや関連レコード、あるいは10,000文字のテキストなどでアウトですから、誰でも遭遇しておかしくない制限です。

末端再帰するようにしておけば、限界は50,000回にアップ。端折って説明すると、再帰呼び出しする時に、計算結果を次の再帰に丸ごと渡すようにする。すると、FileMaker が前の計算結果を保持するためのメモリを消費しないで済むので、再帰回数がより多くなってもオッケーというわけ。末端再帰については、サンプルを書くのが面倒なので、参考ページをば。
FileMaker 9's Custom Function Primer

50,000回の制限は、無限ループを防ぐ趣旨なのだろうが、対象レコードのキーをかき集めて一時的なリレーション越しに動的な集合に対して統計関数を使ったり、ポータル上から関連レコードを開いて擬似的なトランザクション処理を行うことも可能なので、もっと上に上限を設定してほしかった。実に惜しい。今後に期待したい。