(著者:落合 雄一)
はじめに
前回、kintone REST APIを利用し、アプリ情報やレコード情報の取得を取り扱いました。
今回は、kintone REST APIを利用したレコードの更新(ルックアップ自動更新)を扱います。頑張っていきましょう\(^o^)/
ルックアップについて
ルックアップは、登録/更新時にコピー元からデータを取得し、コピー先フィールドにデータをコピーします。
しかし、コピー元のデータを更新してもコピー先フィールドは変更されません(>_<)
これは困りましたね・・・
ということで、ルックアップの自動更新にチャレンジしてみましょう(*^^*)
アプリの準備
今回は、顧客マスターアプリと顧客マスターアプリをルックアップしている見積もり管理アプリを使います。
顧客マスターアプリ
下記のような顧客マスターアプリを用意します。
フィールド名 |
フィールドタイプ |
フィールドコード |
備考 |
レコード番号 |
レコード番号 |
レコード番号 |
|
会社 |
文字列(1行) |
company |
必須項目 |
部署 |
文字列(1行) |
post |
|
電話番号 |
リンク |
tel |
入力値の種類:電話番号 |
この顧客マスターアプリにJavaScriptを登録することで、ルックアップの自動更新を実現します。
見積もり管理アプリ
下記のような見積もり管理アプリを用意します。
フィールド名 |
フィールドタイプ |
フィールドコード |
備考 |
ルックアップ |
ルックアップ |
lookup |
関連付けるアプリ:顧客マスター コピー元のフィールド:レコード番号 ほかのフィールドのコピー: 会社⇐[顧客マスター]会社 部署⇐[顧客マスター]部署 電話番号⇐[顧客マスター]電話番号 コピー元のレコード選択時に表示するフィールド: 会社, 部署 |
会社 |
文字列(1行) |
company |
必須項目 |
部署 |
文字列(1行) |
post |
|
電話番号 |
リンク |
tel |
入力値の種類:電話番号 |
テーブル |
テーブル |
Table |
|
テーブル[製品] |
文字列(1行) |
product |
|
テーブル[個数] |
数値 |
個数 |
最小値:0以上 |
テーブル[単価] |
数値 |
単価 |
最小値:0以上 単位:¥ |
テーブル[価格] |
計算 |
price |
計算式:個数*単価 計算式を表示しない 単位:¥ |
小計 |
計算 |
subtotal |
計算式:SUM(price) 計算式を表示しない 単位:¥ |
消費税 |
計算 |
tax |
計算式:subtotal*0.08 計算式を表示しない 単位:¥ |
合計 |
計算 |
total |
計算式:subtotal+tax 計算式を表示しない 単位:¥ |
レコード番号で顧客マスターアプリからルックアップし、会社, 部署, 電話番号をコピーします。
作成できたら、アプリIDは後で使うので控えておいてくださいφ( ̄ー ̄ )メモメモ
実装する処理を整理してみる
コーディングを始める前に、今回やりたいことと、実現するための処理の流れを考えてみましょう!
やりたいこと
- 顧客マスターアプリの情報が更新されたとき、見積もり管理アプリに登録されたデータも更新する
実装する処理
顧客マスターアプリで、レコードが更新されたときに以下の処理を行います。
- 見積もり管理アプリの対象レコードを一括取得
- レコード更新用のデータを準備し、1.の対象レコードを一括更新
- 処理の成功、失敗を知らせるメッセージを表示
別アプリのデータを更新するので、更新処理がうまくいったかどうかを実行後にメッセージでお知らせしましょう!
1~3 は処理の順番を守る必要がある、ということが重要なポイントになってきます。
それでは、JavaScriptの処理を書いていきましょう!
更新時イベント
今回の処理は、顧客マスターアプリのレコード更新時に行います!
レコード保存時に行われるイベントには、「保存実行前」と「保存成功後」の2種類があります。
例:
また、フィールドの設定画面から「必須」や「値の重複の禁止」などを設定しておくと、こちらも保存前にチェックされてエラーメッセージが表示されますね。
ここでは「製品標準の入力チェック」と呼ぶことにします。
これらの保存イベントや製品標準の入力チェックは、下記の順番で実行されます。
- 保存実行前イベントが発生
- 製品標準の入力チェック(必須、重複禁止、型チェック等)
- レコードが保存される
- 保存成功後イベントが発生
第8回は「編集中レコードの値を、保存前に書き換える処理」だったため、1の「保存実行前イベント」を利用しました。
今回は、「入力チェックをすべて通って、レコードに保存された値」を使って別アプリのレコード更新を行う必要があるので、4の「保存成功後イベント」を利用しましょう!
レコードの編集は、レコード画面とレコード一覧画面の2か所で行うことができるため、以下の2つのイベントを使います。
もうお馴染みの形ですね(^^♪
更新が必要なレコードの一括取得
レコードの一括取得は、前回やりましたね(^^♪
「レコード一括取得後の処理」というコメントのところに、このあとやりたい処理を書き足してくことになります。
下記の 2. 3. の部分ですね。
- 見積もり管理アプリの対象レコードを一括取得
- レコード更新(ルックアップの内容を更新)するためのデータを準備
- 2. のデータを使って、見積もり管理アプリの対象レコードを一括更新
2と3は、処理の順番も重要です。
でも先ほどの書き方の中に2と3を組み込んでしまうと、2と3が同時に動いてしまうため処理順が守られません。
そこで、「順番通りに処理を実行してもらう」ために、Promise というJavaScriptの書き方を使います!
Promiseについては、ここでは詳しく解説しませんが、
- 「.then」で順番に実行する処理をつなぐ
- エラーは「.catch」で拾える
ということだけ覚えておいてください。
※Promiseについて勉強したい方は、この記事の最後にリンクを貼っておきますので、そちらをご覧ください。
また、kintone REST APIでの一括取得は、デフォルトで1度に100件までとなりますが、レコードの取得(GET)を参考に「query」パラメータの「limit」オプションを使用することで1度に500件まで取得することができます。
500件以上のルックアップの自動更新を行いたい場合は、「offset の制限値を考慮したレコード一括取得について」などを参考にしてください。今回は100件までの場合のみの説明になります^^;
ルックアップの一括更新
ここで、レコード一括更新のkintone REST APIのドキュメントを確認してみましょう(^^♪
リクエストパラメータ
※パラメータ名 idとupdateKeyのどちらかを指定する必要があります。両方を指定すると、エラーになります。
パラメータ名 | 指定する値 | 必須 | 説明 |
---|---|---|---|
app | 数値又は文字列 | 必須 | アプリの ID を指定します。 |
records | 配列 | 必須 | 更新するレコードの情報を指定します。 本パラメータの値は、更新したいレコードIDと更新したいレコード情報をセットにしたオブジェクトを配列で記述します。 |
records.id | 数値又は文字列 | 省略可 ※updateKeyを指定する際には指定不可 |
更新するレコードの番号。 records 配列内に記述します。 |
records.updateKey | Object | 省略可 ※idを指定する際には指定不可 |
重複禁止フィールドコードと値を指定します。 指定できるフィールドは重複を禁止が設定された文字列(1行)と数値のみです。 |
records.record | Object | 省略可 | レコードの情報(フィールドコードとフィールドの値)をオブジェクトで指定します。 ※フィールド値の仕様についてはフィールドの形式により異なります。 詳細については フィールド形式をご確認ください。 ※省略した場合は、データは更新されません。 |
records.revision | 数値又は文字列 | 省略可 | 期待しているリビジョン番号。 実際のリビジョン番号と一致しない場合はエラーとなります(いずれのレコードも更新しない)。 ただし、値が-1あるいは指定しなかった場合はリビジョン番号の検証を行いません。 |
必要なパラメータは、アプリIDと更新したいレコードIDと更新したいレコード情報をセットにしたオブジェクトですね。
というわけで、更新したいレコードIDと更新したいレコード情報をセットにしたオブジェクトを作成する関数を用意しておきましょう(^^♪
更新するフィールドは、ルックアップのみとなります。
このレコードの更新情報を使ってkintone REST APIで一括更新することで、コピー先フィールドを更新することができます。
ここまで来ると、あとはレコードの一括更新APIを使って更新するだけですね(^^♪
こちらも、Promiseに対応した書き方になっています。
そして更新したいレコードデータは、先ほど書いた「createPutRecords」関数を呼び出して取得しました。
まとめるとこんな感じのJavaScriptになります。
※見積り管理のアプリのアプリIDは環境によって変えてください。
では、このJavaScriptを顧客マスターアプリに登録しレコードの更新を行ってみましょう(^^♪
こんな感じでレコードを編集し保存すると・・・
アラートが表示されましたね!
では、見積もり管理アプリのルックアップしているレコードに更新内容が反映されているか確認してみましょう。
バッチリですね\(^o^)/
最後に
今回は、kintone REST APIを使ってルックアップを自動更新する方法を紹介しました!
しかし、今回のサンプルだと100件までしかルックアップの自動更新ができないので、offset の制限値を考慮した kintone のレコード一括取得についてを参考に実装にチャレンジしてみてください(^^♪
Let’s kintoneカスタマイズ\(^o^)/
参考リンク
- kintoneにおけるPromiseの書き方の基本
- kintone API で Promise を使ってみよう!
- kintone.Promiseとは
- offset の制限値を考慮したレコード一括取得について
このTipsは、2022年7月版 kintone で確認したものになります。
<<第10回 kintone REST APIを利用したレコード取得 | 第12回 jQueryを利用してみよう>>
デモ環境
こちらのデモ環境から実際に動作を確認できます。
(顧客マスタ) https://dev-demo.cybozu.com/k/17/
(見積もり管理) https://dev-demo.cybozu.com/k/18/
デモ環境アカウントとパスワードは、サインイン後にこちらのページでご確認ください。
レコードを更新しようとしたときにエラーが発生しました。
message: "ルックアップの参照先から値をコピーできません。「コピー元のフィールド」に指定したフィールドの設定で「値の重複を禁止する」を選択しておく必要があります。"
この問題を解決する方法を教えてください。
Tuan Tu 様
お世話になっております。
cybozu developer network 事務局です。
こちらで動作確認を行いましたが、正常に動作いたしました。
「アプリの準備」の設定が記事通りに設定されているかどうか、再度ご確認いただけますでしょうか?
cybozu Development team様
回答ありがとうございました。
フィールドのインストールでエラーを見つけて修正しました。
cybozu Development team 様
当回の内容を応用して、REST APIでGETした既存レコードのフィールド情報(管理番号)を1つカウントアップし
レコード追加画面のフィールド(管理番号)に反映させたいと思っています。
ただ、レコード追加画面なのでその後のPUTが使えません(←理解合ってますでしょうか?)。
一方で、Kintoneのeventにreturnしないと画面上のフィールドに反映されないので、当回の構文(.then~)を使ってなんとか頑張っていますが、どうにも解決できません。。
上記のことを実現したいときに、なにか良い方法があればヒントは頂けると幸いです。
どうぞよろしくお願い致します。
続けて、すみません。以下補足になります。PUTが使えないので代わりに、
以下のようにしていますがフィールドに反映してくれません。
そもそも不可能なことをこの構文でやろうとしてるのでしょうか?
ちなみにKanriNoには値が入っており、
KanriNoを代入する前は、record['管理番号']['value']の初期値を戻しているので、
問題がないように思っています。(以下のalertで確認済み)
ーーーーーーーーーーーーーーーーーーー
kintone.events.on('app.record.create.show', function(event) {
var record = event.record;
・・・・
//alert(record['管理番号']['value']); ←フィールドの初期値を表示(○)
record['管理番号']['value']= KanriNo;
//alert(record['管理番号']['value']); ←KanriNoを表示(○)
}).then(function(resp) {
// 処理成功
alert('更新が完了しました');
return event;
・・・
モツナベ様
お世話になっております。cybozu developer network 運営でございます。
レコード追加画面上で値を反映させたい場合は、レコード追加イベントでeventオブジェクトを書き換えてください。
続けて投稿いただいたコメントのコードのようになるご認識で問題ありませんが、今回のようにREST APIでGETした既存レコードのフィールド情報(管理番号)を利用する場合は、非同期処理の完了を待って次の処理を行う必要があります。
記述方法はkintoneにおけるPromiseの書き方の基本を参考にしてください。
また、恐れ入りますが、こちらのコメント欄は記事内容のフィードバック目的となっているため、
上記を確認・試してみて不明な点がある場合など、技術的なご質問はcybozu developer コミュニティをご活用ください。
よろしくお願い致します。