こんにちはジョージです、先日まで博多の「FileMaker Training 基礎コース」で講師を務めさせて頂きました。ご参加頂いた皆様、大変お疲れ様でした!オンサイトのトレーニングではガイドブックの内容以外にも時間の許す限り、実際の現場で利用されているテクニックも一部紹介させて頂いてますが、本日は特に好評だったテクニック「かっこいい関連レコードを含めたレコードの複製」を紹介します。
トレーニングではまずディスカッション形式で、基礎編で習った範囲の機能(レイアウト切り替え、関連レコードへ移動、レコードのエクスポート/インポート、一括置換等)のみを駆使し「関連レコードを含めたレコードの複製」を実現する方法を受講者の皆様にアイデアを出して頂き、そのアイデアに沿って全員一丸となって機能を開発しました。
カスタム App 利用者にとっては「複製ボタン」をクリックするだけの簡単な操作ですが、その裏でカスタム App 開発者はどれだけ多くの処理を実行しなければならないか感じて頂けたかと思います。そして、問題解決に向けていろいろなアイデアが飛び出た、楽しいトレーニングだったと思います!次回は 12 月に実践コースの予定がございますので、九州エリアで日程があう方は是非ご参加を検討してみてください!
イベント/セミナー | Claris FileMaker(九州・沖縄)
レコード複製
FileMaker Pro のレコード操作には「追加、複製、削除」がありますが「関連レコードを含めたレコードの複製」は用意されていません、なにかしらの方法で自分で開発するしかありません。そして、カスタム App の開発中に仕様の追加や変更が発生した場合、自力で開発した「関連レコードを含めたレコードの複製」も見直しを迫られる可能性があります。つまりメンテナンスしやすい機能にしておく必要があります。
FileMaker Data API を実行(create アクション)
そこで、最新の FileMaker Pro から利用可能な「FileMaker Data API を実行」の「create アクション」を使って解決してみましょう。https://help.claris.com/ja/pro-help/content/execute-filemaker-data-api.html
FileMaker Data API で「create アクション」を使うと、ターゲットレイアウトで指定されているテーブルオカレンスに対してレコードの作成が可能です。さらに、レイアウトに配置されたポータルのテーブルオカレンスに対して「レコード作成」が許可されている場合は、関連レコードを含めてレコードの作成が可能となります。https://help.claris.com/ja/data-api-guide/content/create-record.html
ステップ1:FileMaker Data API を実行(read アクション)
まずは、複製したいレコードの主キーを query 条件に登録、ターゲートレイアウトを指定してリクエストを作成し FileMaker Data API を実行します。例えばこんな感じです。
JSONSetElement ( "{}";
[ "action"; "read"; JSONString ];
[ "version"; "vLatest"; JSONString ];
[ "layouts"; "REST|タスク管理"; JSONString ];
[ "query";
JSONSetElement ( "[]";
[ "[+].主キー"; タスク管理::主キー; JSONString ]
); JSONArray ]
)
その結果、取得される JSON は以下のような内容になるはずです。複製したいフィールドにどれを含めるかは、ターゲットレイアウトで調整します。
{
"messages" :
[
{
"code" : "0",
"message" : "OK"
}
],
"response" :
{
"data" :
[
{
"fieldData" :
{
"カテゴリー" : "プロジェクトC",
"ステータス" : "キャンセル",
"タスク" : "報告書の作成(営業会議用)",
"優先度" : "高",
"完了日" : "",
"期限" : "05/02/2022",
"説明" : "X月X日の会議で必要な年度ごとの売り上げ数集計表を作成する"
},
"modId" : "11",
"portalData" :
{
"タスク添付ファイル" :
[
{
"modId" : "1",
"recordId" : "1",
"タスク添付ファイル::添付ファイル" : "PDFファイル見本_請求書.pdf",
"タスク添付ファイル::説明" : "請求書"
},
{
"modId" : "1",
"recordId" : "2",
"タスク添付ファイル::添付ファイル" : "公園.gif",
"タスク添付ファイル::説明" : "公園"
}
],
"担当者割り当て" :
[
{
"modId" : "1",
"recordId" : "1",
"タスク担当者::電子メール" : "fusako939@zqovogaqc.vq",
"タスク担当者::電話" : "0224-00-7845",
"担当者割り当て::担当者外部キー" : 20
},
{
"modId" : "0",
"recordId" : "2",
"タスク担当者::電子メール" : "hibiki2455@puamvlg.kt",
"タスク担当者::電話" : "055-478-3643",
"担当者割り当て::担当者外部キー" : 38
},
{
"modId" : "1",
"recordId" : "3",
"タスク担当者::電子メール" : "iyasuda@msvuuz.qga.ehu",
"タスク担当者::電話" : "022-139-8182",
"担当者割り当て::担当者外部キー" : 54
}
]
},
"portalDataInfo" :
[
{
"database" : "11_演習タスク_11_14完了時",
"foundCount" : 3,
"portalObjectName" : "担当者割り当て",
"returnedCount" : 3,
"table" : "担当者割り当て"
},
{
"database" : "11_演習タスク_11_14完了時",
"foundCount" : 2,
"returnedCount" : 2,
"table" : "タスク添付ファイル"
}
],
"recordId" : "3"
}
],
"dataInfo" :
{
"database" : "11_演習タスク_11_14完了時",
"foundCount" : 1,
"layout" : "REST|タスク管理",
"returnedCount" : 1,
"table" : "タスク管理",
"totalRecordCount" : 60
}
}
}
ステップ2:実行結果の JSON を整形
実行結果をよく見ると複製したいレコード、つまり create アクションに必要な JSON はほぼ出来上がっていることに皆様お気づきでしょうか?それは fieldData と portalData です。したがって、以下のように $requeest を作成してみます。
JSONSetElement ( "{}";
[ "action"; "create"; JSONString ];
[ "version"; "vLatest"; JSONString ];
[ "layouts"; "REST|タスク管理"; JSONString ];
[ "fieldData"; JSONGetElement ( $result; "response.data[0]fieldData" ); JSONObject ];
[ "portalData.担当者割り当て"; JSONGetElement ( $result; "response.data[0]portalData.担当者割り当て" ); JSONArray ];
[ "portalData.タスク添付ファイル"; JSONGetElement ( $result; "response.data[0]portalData.タスク添付ファイル" ); JSONArray ]
)
fieldData はよさげですが、このままでは portalData には不要な modId や recordId がリクエストに含まれた形になってしまいます。正攻法としてループ処理などを駆使してこれらを除去してもよいのですが、もっとエレガントな方法でなんとかします。
{
"modId" : "1", //<----- 不要
"recordId" : "3", //<----- 不要
"タスク担当者::電子メール" : "iyasuda@msvuuz.qga.ehu",
"タスク担当者::電話" : "022-139-8182",
"担当者割り当て::担当者外部キー" : 54
}
JSONFormatElements 関数
そこで登場するのが「JSONFormatElements」関数です。JSONFormatElements 関数の特性として、コメントアウトした行は整形される JSON には含まれません。この特性を利用すると綺麗に modId や recordId を除去できます。
{"modId":"1","recordId":"3","タスク担当者::電子メール":"iyasuda@msvuuz.qga.ehu","タスク担当者::電話":"022-139-8182","担当者割り当て::担当者外部キー":54}
例えば上記の「$実行結果JSON」を JSONFormatElements 関数で整形します。その結果「$実行結果JSON」は 以下のようになります。
{
"modId" : "1",
"recordId" : "3",
"タスク担当者::電子メール" : "iyasuda@msvuuz.qga.ehu",
"タスク担当者::電話" : "022-139-8182",
"担当者割り当て::担当者外部キー" : 54
}
次に Substitute 関数 を使って modId や recordId を行コメントで置換します。
Substitute (
$実行結果JSON;
[ "\"modId\""; "//\"modId\"" ];
[ "\"recordId\""; "//\"recordId\"" ]
)
行コメントで置き換えられるので、「$実行結果JSON」は次のようになります。
{
//"modId" : "1",
//"recordId" : "3",
"タスク担当者::電子メール" : "iyasuda@msvuuz.qga.ehu",
"タスク担当者::電話" : "022-139-8182",
"担当者割り当て::担当者外部キー" : 54
}
これを JSONFormatElements 関数でさらに整形します。
{
"タスク担当者::電子メール" : "iyasuda@msvuuz.qga.ehu",
"タスク担当者::電話" : "022-139-8182",
"担当者割り当て::担当者外部キー" : 54
}
綺麗に modId と recordId を除去できました!Substitute 関数で実行しているので、portalData の全ての内容から modId と recordId を除去できます。2 回 JSONFormatElements 関数を実行しているのでこのテクニックを WJSONFormatElements(ダブルジェイソンフォーマットエレメンツ)と呼称します。
WJSONFormatElements(ダブルジェイソンフォーマットエレメンツ)
ステップ 1:FileMaker Data API を実行(read アクション)の結果 $result から $request を作成している場合、次の WJSONFormatElements を実行して modId と recordId を除去します。
JSONFormatElements (
Substitute (
JSONFormatElements ( $request );
[ "\"modId\""; "//\"modId\"" ];
[ "\"recordId\""; "//\"recordId\"" ]
)
)
ステップ3:FileMaker Data API を実行(create アクション)
あとは整形されたリクエストをつかって、Data API の create アクションを実行すればエレガントな「関連レコードを含めたレコードの複製」が完了です!実際にスクリプトに必要な処理は数行しかありません。
# #
# Data API read リクエスト
変数を設定 [ $request ; 値: JSONSetElement ( "{}"; [ "action"; "read"; JSONString ]; [ "version"; "vLatest"; JSONString ]; [ "layouts"; "REST|タスク管理"; JSONString ]; [ "query"; JSONSetElement ( "[]"; [ "[+].主キー"; タスク管理::主キー; JSONString ] ); JSONArray ] ) ]
FileMaker Data API を実行 [ 選択 ; ターゲット: $result ; $request ]
#
# Data API create リクエスト
変数を設定 [ $request ; 値: JSONSetElement ( "{}"; [ "action"; "create"; JSONString ]; [ "version"; "vLatest"; JSONString ]; [ "layouts"; "REST|タスク管理"; JSONString ]; [ "fieldData"; JSONGetElement ( $result; "response.data[0]fieldData" ); JSONObject ]; [ "portalData.担当者割り当て"; J… ]
#
# WJSONFormatElements で整形
変数を設定 [ $request ; 値: JSONFormatElements ( Substitute ( JSONFormatElements ( $request ); [ "\"modId\""; "//\"modId\"" ]; [ "\"recordId\""; "//\"recordId\"" ] ) ) ]
FileMaker Data API を実行 [ 選択 ; ターゲット: $result ; $request ]
#
# #
If [ Get( 最終エラー ) ]
Else
レコード/検索条件/ページへ移動 [ 最後の ]
End If
#
#
#
#
#
考察
ターゲットレイアウト一つ、そして数行のスクリプトだけで「関連レコードを含めたレコードの複製」が可能になるとは便利になりましたね。しかもこの方法は、関連レコードが増えたとしてもターゲットレイアウトにポータルを追加するだけで簡単にメンテナンスできます。
ひとつだけ注意としてはフィールドタイプが「オブジェクト」の場合は、そのまま複製できないので何かしら追加処理が必要になりますね。ここは皆様も考えてみてください!それでは次回の「FileMaker Training 実践コース」 そして、Claris カンファレンス 2024 でお会いしましょう!
https://www.claris.com/ja/conference/2024