Job Runner 案件 – レコード1行が準備できた時を使ってテーブルに書き出す

公開日:

注意

本記事は情報提供を目的としており、本記事の内容は無保証、サポートの対象外です。
サポート窓口、問合せ窓口にご質問をいただいても対応いたしかねますのでご了承ください。

システム開発グループ テクニカルマネージャーの浅利です。

少し前にカスタマインの Job Runner をつかってレコードを追加したりテーブルを操作する必要があったのですが、そこで少しテクニックが必要だったので、今回はその話をします。

やりたいこと

あるアプリAには、日付や金額の入ったデータがたまっていきます。
ひと月に一回 Job Runner を実行して、先月ひと月分の日付のアプリAのレコードを集計結果等を入れるアプリBにテーブルとして書き込む、というシナリオです。

テーブルではなく関連レコードの方がいいかなと思ったのですが、事情があって(=アプリAにはないマスタデータからの値も一緒に同じ行に入れたい)テーブルでやることになりました。(マスタデータもルックアップが使えればよかったのですが..)

※ブログ用に、実際の案件とは変えて書いてます

Job Runner で実装した大まかな動きは、以下のようになります。

  • Job Runner の定期実行タスク(1ヶ月に1回)とします。
  • Job Runner が実行されたら、まずアプリBに1件レコードを追加します。
  • アプリAから、先月ひと月ぶんのレコードをすべて取得します。
  • 取得したアプリAのレコードそれぞれについて、また別のアプリからマスタデータを取得します。
  • その2つを合わせて、先ほど追加したアプリBのレコードのテーブルに1行追加します。
    それをアプリAから取得した全レコードぶん繰り返します。

試行錯誤

さっそく Job Runner の実装ですが、

まずは 「実行予定時刻になった時」と「他のアクションの実行が完了した時」に、「kintone 接続設定を行う」により、アプリA・アプリB・マスタアプリについて接続設定を行いますが、それは省略します。

アプリBに1レコード追加するにあたって使えそうな”やること”は、一般的な「レコードを追加する」か、テーブルがあるので「テーブルデータをセットしたレコードを追加する」でしょうか。
しかし、今回はアプリAのレコード1件ずつに対してマスタアプリからデータを取り出してくっつけないといけないため、「テーブルデータをセットしたレコードを追加する」は使えませんでした。
そこで「レコードを追加する」を使います。

次にアプリAから日付を”先月のもの”という条件で取得します。
条件を組み立ててレコードを取得する」にて、getdate関数を使って日付の条件で取得します。今回は月初に定期実行して先月ぶんのレコードを取得するため、日付がgetdate(“先月月初”) 以降 且つ 日付がgetdate(“先月末日”) 以前とします。

アプリAから取得したレコード1件1件に対して、関連するデータをマスタアプリから取得したいため、「レコード1行が準備できた時」で「キーを指定してレコードを取得する」を使い、マスターコードの値をもとに取得しました。

最後に「他のアクションの実行が完了した時」に「レコードをテーブルに書き出す」で、上でアプリBに追加したレコードのテーブルへ行を追加することにしました。

→ でも結論から言うとこれではダメでした。

この Job Runner を実行してみたところ、以下のエラーになってしまいました。

どうやら「テーブル1」が存在しないようです。でもアプリBにはそのフィールドコードのテーブルあるよね??

実は「レコードをテーブルに書き出す」は、「レコードを追加する」のレコードのテーブルには使えません。

というのも、この「レコードを追加する」の時点では、フィールドマッピングに指定したフィールドや値しかこのレコードにはなく、テーブルがまだ存在しないんです。

どうすればいいかは、「Job Runnerでレコードを追加し、直後にそのレコードを取得して処理を行えますか?」の「テーブルを2つ含むレコードを追加する」のところに書いてありました。

まず「レコードを追加する」を「即時実行する」モードに変えて、その後でアプリBからそのレコードを取得すればよいそうです。
(テーブルに追加するときだけでなく、こうすることでフィールドマッピングで指定しなかった他のフィールドもすべて用意されます。kintone側で設定したフィールドの初期値も入ります)

その際、レコード番号 = $4[0][‘$id’] のように書く必要があるそうです。これも先ほどの「Job Runnerでレコードを追加し、直後にそのレコードを取得して処理を行えますか?」にちゃんと書いてありました。

※ ↓ ちなみに、レコード番号 = $4.レコード番号 とか = $4[0].レコード番号 とかではダメでした。

追加したレコードを取得し、そこに「レコードをテーブルに書き出す」ように直すことで、ひとまずアプリBに書き込むことができるようになりました。

おまけ: 追加要望

ここでお客さんからこんな要望が入ります。

  1. 日付順に並んでるけど、日付はあまり重要じゃないんです。
     金額が大事なので、金額が一番高いものから順にテーブルに並べてほしい
  1. 金額順に並べたら、上から順に「1」「2」「3」…と順位を入れてほしい

1は簡単ですね。
アプリAから「条件を組み立ててレコードを取得する」をやるところで、「並び順追加」を行い、金額の降順にすればいいです。

2は、実は今回「レコード1行が準備できた時」に続く処理から「レコードをテーブルに書き出す」を行っているがためにやれる方法があります。
この「レコードをテーブルに書き出す」のフィールドマッピングで、式で、= count($5[0].テーブル) + 1 とすることです。

こうすると、レコードをテーブルに書き出す直前のテーブルの行数が count(..) で取得できるので、
1つ目は(まだテーブルが0行なので+ 1すると) 1、2つめは(テーブルに1行目のみが入っているので+1すると) 2、… となります。

メモ

なお、この「レコードをテーブルに書き出す」の後に続けて、count($5[0].テーブル1) を使って、
”今 ${count($5[0].テーブル1)}行目です” のように「ログにメッセージを出力する」しようと思ったのですが、
うまくいく場合とうまくいかない場合がありました。

なぜなら、「レコード1行が準備できた時」に続くやることは並列に実行されるからです。

1行目で「レコードをテーブルに書き出す」→「ログにメッセージを出力する」→2行目で「レコードをテーブルに書き出す」→「ログにメッセージを出力する」→3行目で…という順番に毎回なってくれればいいですが、

他のやることとの組み合わせやかかる時間によって、1行目で「レコードをテーブルに書き出す」→2行目で「レコードをテーブルに書き出す」→3行目で~ →… → 1行目ぶんの実行が完了した時ぶんの「ログにメッセージを出力する」→2行目ぶんの「ログにメッセージを出力する」→…のような実行順になったりして、
1行目分の実行が完了した時ぶんの「ログにメッセージを出力する」時点ですでにテーブルには何行も入っていることがあります。

今回の実装についても、「レコードをテーブルに書き出す」の前にやる処理によっては順番が前後してしまう可能性があるんじゃないかと思います。

完成

最終的に完成したアプリと、Job Runner の実装がこちらです。

※この案件はブログ用の架空の案件です。

まとめ

以上、カスタマイン(今回は Job Runner)で実行してみてうまくいかないときは、ドキュメントやサポートサイトを見ながら、このように試行錯誤します、という例でした。

今回はブログ用に比較的シンプルにした案件ですが、弊社のキミノマホロではもっと複雑だったり大規模だったりの案件も扱っていますので、ぜひお問い合わせください。

また、もしみなさんご自身でカスタマインで開発する際には、考え方の参考にしていただけたらと思います。さらにドキュメントやサポートサイトを見ても解決しないときは、チャットサポートもぜひご活用ください。

必要なものを、必要なだけ。
業務改善の新しいカタチ

kintoneを活用した業務改善・システム開発サービス

kintoneを活用した業務改善・システム開発サービス

投稿者プロフィール

アバター画像
淺利(あさり)
Webとか.NETとかスマホとかマイコンとかシーケンサーとか、いろいろやってるエンジニアです