後輩の hirata に指摘をもらったので、コード部分を書き換えました(12/10 14:04)
カスタム関数を作ってみた
ピティナでは、noguchi によるFileMakerの研修が月2回で開催されているのですが、
FileMaker初心者の私も参加しています。
今回、お題として「出退勤を管理するシステム」をFileMakerで作ってみることになりました。
その中で、労働時間を計算するのに、後ろ倒し、前倒しをする時刻計算が必要になったので、カスタム関数を使ってみました。
関数の概要
たとえば、
- 09:01 ~ 09:30 に出勤したら、09:30 として扱う。(出勤は後倒し)
- 19:00 ~ 19:29 に退勤したら、19:00 として扱う。(退勤は前倒し)
みたいな処理です。
イメージ図:後倒し時刻_時(_time; _unit; _i)
コード:後倒し時刻_時(_time; _unit; _i)
Let ([
m = Minute ( _time );
h = Hour ( _time );
threshold = _i * _unit
];
Case (
threshold ≥ 60; h+1;
Case (
m = 0; h;
m ≤ threshold ; h;
後倒し時刻_時 ( _time; _unit; _i+1 )
)
)
)
コード:後倒し時刻_時(_time; _unit; _i) 改修しました!!
後輩の hirata から「n時を取るだけなら、Loopする必要ないよ」と指摘をもらいました。
たしかに!!ということで、下記コードに書き直しました。
Let ([
m = Minute ( _time );
h = Hour ( _time );
threshold = 60 - _unit
];
Case (
m > threshold ; h+1;
h
)
)
閾値 = 60 - unit ですね。恥ずかしや。
関数の解説
引数解説
後倒し時刻_時 ( 19:01:00; 15; 0 )
- _time :時刻部分は、タイムスタンプ型のフィールドを指定するイメージです。
- _unit :ピティナでは 15分単位計算の人、30分単位計算の人がいるので単位を指定できるようにしました。
- _i :ちょっとダサいのですが、、、初期値 0を投入します。。。げふん。
処理解説
まず、初めのLet関数で、、
- 引数で受け取った時刻の 分数部分 を取得
- 引数で受け取った時刻の 時刻部分 を取得
- 閾値(分)として、単位分 * ループ回数(i) を設定
次にCase文で、
- 閾値(分)が60分を超えていたら、チェック対象時刻(時) + 1を結果として返却。
- チェック対象時刻(分)が、ちょうど 0分なら、チェック対象時刻(時)を結果として返却。
- チェック対象時刻(分)が、閾値(分)未満なら、チェック対象時刻(時)を結果として返却。
- いずれとも判断がつかなければ、_i をインクリメントして、もう一度判定し直し。
という感じになります。
最後に
なぜに再帰処理にしたのか
実は、FileMakerの関数では、Loop処理ができません。For とか、While がありません。
なので関数内でLoop処理をしたい場合、どうしても再帰処理で解決するしかないのです。
あるいは
(関数ではなく)スクリプトを作成する、という方法があります。
ただし、処理結果を取得したい場合には、
- スクリプトの実行
- Get ( スクリプト結果 )
と、2段階にする必要があります。
また、スクリプトワークスペース(FM13では、「スクリプトの管理」)に当然ながら出てきてしまうので、
一覧性を気にする方は、フォルダ分けをするか、Lib的なファイルに作成するようにすると良いと思います。
参考になれば幸いです。