【kintone】JavaScriptカスタマイズ入門④

# はじめに
今回は、レコード更新要否の判定とkintone.Promiseを利用したレコード処理の同期について、ご説明いたします。kintone REST APIには呼び出し回数の制限があり、マスタアプリ上の備考項目など、トランザクションアプリへの反映が不要な項目が更新された場合は、データ更新処理を行わないよう判定したいところです。また、kintone REST APIのレコード処理は非同期処理のため、kintone.Promiseを利用したレコード処理の同期が必要となります。
### レコード更新要否の判定
マスタアプリ側で、トランザクションアプリから参照されない項目が更新された場合はトランザクションアプリの更新処理を行わないように判定処理を行います。
まずは、マスタアプリでレコード編集画面が表示されるイベントで、編集前のレコード内容を変数に複製します。
```js
    // 変更前のレコード内容を格納用バッファ
    var orgRecord=[];
    var events = [
        // レコード編集画面表示時(既存レコードを編集モードで表示)
        'app.record.edit.show'
    ];
    //レコード編集画面の表示イベントで、契約先コードをグローバル変数に格納する。
    kintone.events.on(events, function(event) {
        var record = event.record;
        // 現在のレコードの複製を作成
        orgRecord = Object.assign({}, record);
    });
```
次にレコード更新要否の判定は、レコード編集画面で保存ボタン押下され保存成功したイベントで行います。変数に複製した初期状態のレコードと保存成功後のレコード、それぞれのトランザクションアプリから参照されている項目が変更されているかを判定し、変更されていた場合は更新フラグを立てます。
```js
    var events2 = [
        // レコード編集画面の保存成功後イベント
        'app.record.edit.submit.success'
    ];
    // 更新要否フラグを設定する。
    kintone.events.on(events2, function(event) {
        // 更新要否フラグ
        var change_flg = false;

        // 保存後レコードを取得
        var modRecord = event.record;

        /* ****************************************** */
        /* 各項目の不一致を元に更新要否フラグを設定する。 */
        /* ****************************************** */
        // 各項目別に変更前後を比較し、差異があれば更新フラグを立てる。
        // 担当者名
        var tantousyaName;
        if (typeof modRecord["担当者名"].value === "undefined") {
          tantousyaName = "";
        }
        else{
            tantousyaName = modRecord["担当者名"].value;
        }
        if(orgRecord["担当者名"].value != tantousyaName){
            change_flg = true;
        };
        // 電話番号
        var telNo;
        if (typeof modRecord["電話番号"].value === "undefined") {
            telNo= "";
        }
        else{
            telNo = modRecord["電話番号"].value;
        }
        if(orgRecord["電話番号"].value != telNo){
            change_flg = true;
        };
```
### レコード処理の同期（kintone.Promise）
kintone REST APIのレコード処理は非同期処理のため、レコード一括取得処理、レコード一括更新処理の順に連続で処理を行っても正常に動作しません。この対策として、kintone.Promiseという仕組みが用意されています。簡単な利用方法としては、レコード処理APIの呼び出し関数にthen()関数で処理をつなぐ形となります。then()関数 の引数には「引数を1つもった無名関数」をセットします。この無名関数の引数には「then()関数のつなぎ元の処理結果(レコード処理APIの実行結果)」が格納されるので、無名関数内でレコード取得結果を利用することができます。なお、then()関数にもthen()関数を繋ぐことができるので、複数アプリのレコード更新を１つずつ順に行うこともできます。さらに最後にcatch()関数を繋いでおくとthen()関数で発生した例外を拾ってくれます。下記のサンプルでは無名関数内でレコード取得結果を元に更新用レコード配列を生成後、レコード一括更新処理を呼び出します。
```js
        /************************************************* */
        /* 更新要否フラグを元に問合せ管理アプリの更新処理を行う */
        /************************************************* */
        // 問合せ管理アプリのアプリID
        const appId = 1647;
        //出力するフィールドのフィールドコード
        var fields = ["レコード番号"];
        // 問合せ管理アプリから、顧客管理アプリで保存した会社名のレコードを抽出する。
        var  strQuery = ' 会社名 = "' + orgRecord['会社名'].value + '"'
        var  strOption = ' order by レコード番号 desc ';        
        // レコード一括取得処理
        getRecords(appId, fields, strQuery, strOption).then(function(resp){
            // 要更新
            if(change_flg == true) {
                // 抽出レコードを取得
                var respRecords = resp;

                // 顧客管理アプリの更新用オブジェクト
                var NewRecords = [];
                // 更新用レコード生成
                for (var i = 0; i < respRecords.length; i++) {
                    // レコードID
                    var rec_id = respRecords[i]['レコード番号'].value
                    // 更新内容
                    // 会社名（ルックアップ項目）を更新する
                    var kin_record = {
                        "会社名":{ value : orgRecord['会社名'].value },
                    };
                    // 顧客管理アプリの更新用レコードを追加
                    NewRecords[i] = {
                        "id": rec_id,
                        "record": kin_record
                    };
                }
                //レコード一括更新
                return putAllRecords(0,appId,NewRecords);
            };
        }).catch(function(error) { 
            console.log(error);
            // エラー時の処理
            alert('問合せ管理アプリの更新処理に失敗しました。\n' + error);
        });
```
### おわりに
kintoneのJavaScriptカスタマイズ入門として、kintone REST APIを利用したデータ更新処理をご説明いたしました。マスタデータの一括更新については、次のような注意点も考慮が必要となります。
+ 更新対象のトランザクションアプリが複数、または多段式になっている場合は、レコード更新件数の増加よる処理時間増加やjavascript実行時間のタイムアウトによる更新失敗などのリスクが発生するため、処理負荷の検討・検証が必要になります。
+ マスタ更新1回の反映対象のアプリ数・レコード件数が多く、かつマスタデータの更新の頻度が低い場合は、データ更新処理の実装ではなくkintoneアプリのCSVデータ一括取込み機能による手動更新による運用も検討対象となります。