ルックアップの自動取得をレコード一覧を開いたタイミングで実行はできますか?

(function(){
'use strict';
kintone.events.on(['app.record.index.show','app.record.create.show','app.record.edit.show'], (event)=>{
event.record['ルックアップ'].lookup = true;
  return event;
});
})();

このようなjavascriptを用意しました

レコード編集時やレコード作成(複製)時は、ルックアップフィールドの再取得が実行されるのですが、一覧時にはindex.jsのエラーが出ており実行されていませんでした

ドキュメントや過去の質問なども見てみたのですが、該当する回答が見つからず…

こちらについて解決方法、もしくは制約などについてご教授いただけますでしょうか?

こちら の「実行できる操作」に記載されていますが、index.showやindex.edit.showでルックアップの自動取得はできないようになっています(記載がない場合できません)。

アドバイスありがとうございます

↓こちらの部分でしょうか
まだまだリファレンスの見方も不慣れでお手間をおかけしました

色々調査や思考した結果、仮に全件のレコードに入力された特定のルックアップフィールドを再取得する場合は、

ボタン配置
↓
全レコードを取得
↓
各レコードで更新
↓
再取得

のような流れになりますでしょうか?

また参考になるフォーラムの投稿など、もしご存知でしたらご教授いただけると幸いです

何卒よろしくお願いいたします

 

iwi さま

そのようなイメージで問題ありません。レコード一覧の閲覧画面(index.show)でルックアップの再取得をさせる場合は、REST APIでレコードの更新をする必要があります。また表示する度に実行するわけにはいかないのでボタンを設置してそのクリックイベント等で実装するのが良いかと思います。

以下のような形で可能ですが、REST APIによるルックアップの自動取得はcreate.showやedit.show(ルックアップの検索結果が1件だった場合に自動取得)とは動作が異なり「ルックアップの『コピー元のフィールド』がレコード番号または重複禁止に設定したフィールドに限り自動取得」となります。
また、総レコード数が分からないので、何万件あっても問題ないように@kintone/rest-api-client を使用しています。あらかじめこちらを読み込んだ上でご使用下さい。

(() => {
  'use strict';

  const lookup = 'ルックアップ'; // ルックアップフィールドのフィールドコード
  const client = new KintoneRestAPIClient();

  kintone.events.on('app.record.index.show', (event) => {
    if (document.getElementById('lookup-update')) return event;

    let appId = event.appId;
    let button = document.createElement('button');

    button.id = 'lookup-update';
    button.innerHTML = 'ルックアップ更新';
    button.onclick = async () => {
      if (!confirm('実行しますか?')) return;

      let getRecordsParam = {
        app: appId
      };

      let records = await client.record.getAllRecords(getRecordsParam);

      let updateRecordsParam = {
        app: appId,
        records: []
      };

      records.forEach((record, index) => {
        if (!record[lookup].value) return;

        updateRecordsParam.records.push({
          id: record['$id'].value,
          record: {
            [lookup]: {
              value: record[lookup].value
            }
          }
        });
      });

      let update = await client.record.updateAllRecords(updateRecordsParam);

      alert('完了しました');
      location.reload();
    };

    kintone.app.getHeaderMenuSpaceElement().appendChild(button);

    return event;
  });
})();

mis-hashimoto 様

ご返信ありがとうございます
また完璧なコードまでご提示いただき本当にありがとうございます!

早速、開発環境のアプリでテストしてみたところ無事動きました

@kintone/rest-api-client

などでレコードの全件取得は他でも流用できそうなので非常に助かります!

以下、すでに私にはまだ理解が追いつかいない部分があるなか、さらなる質問となり大変恐縮ですが
ルックアップフィールドがテーブル内のデータの場合はどのような処理になりますでしょうか?※甘えてしまいすいません…

出来ないなりに該当部分を試行錯誤してみたのですが、、、当然のようにエラーが出てしまっています
※テーブルのフィールドコードは"テーブル"としています

 

      records.forEach((record, index) => {
          //↓1行追加
      record.テーブル.lookup.forEach((row) => {

        if (!record.テーブル[lookup].value) return; //編集

          updateRecordsParam.records.push({
            id: record['$id'].value,
            record: {
              [lookup]: {
                value: record[lookup].value
              }
            }
          });
      }); //追加
      });

※編集部分は「.(ドット)」や「[]」の使い分けもまだしっかりと理解出来ていない状況ですがエラーが出ないようこちらに落ち着いた次第です…

本当に恐縮ですが、こちらについてアドバイスやご教授いただくことは可能でしょうか?
何卒よろしくお願いいたします

iwi さま

サブテーブルのPUTは少し癖があり、間違えるとサブテーブルの行が消えてしまうので、あらかじめ「レコードの変更履歴を記録する(設定→高度な設定)」が有効になっていて「このバージョンに戻す」が使えるようにしておくことをおすすめします。

サブテーブルは変更したい行のみ変更することができず、全ての行をリクエストボディに入れる必要がありますが、各行に振られている「id」さえあれば問題ありません。その上で更新したい行のみオブジェクトを追加していきます。以下のような形になります。

(() => {
  'use strict';

  const subTable = 'テーブル'; // サブテーブルのフィールドコード
  const lookup = 'ルックアップ'; // ルックアップフィールドのフィールドコード
  const client = new KintoneRestAPIClient();

  kintone.events.on('app.record.index.show', (event) => {
    if (document.getElementById('lookup-update')) return event;

    let appId = event.appId;
    let button = document.createElement('button');

    button.id = 'lookup-update';
    button.innerHTML = 'ルックアップ更新';
    button.onclick = async () => {
      if (!confirm('実行しますか?')) return;

      let getRecordsParam = {
        app: appId
      };

      let records = await client.record.getAllRecords(getRecordsParam);

      let updateRecordsParam = {
        app: appId,
        records: []
      };

      records.forEach((record) => {
      let tableValue = record[subTable].value.map((row) => {
          let tableRow = {
            id: row.id
          };

          if (row.value[lookup].value) {
            tableRow.value = {
              [lookup]: {
                value: row.value[lookup].value
              }
            };
          }

          return tableRow;
        });

        updateRecordsParam.records.push({
          id: record['$id'].value,
          record: {
            [subTable]: {
              value: tableValue
            }
          }
        });
      });

      let update = await client.record.updateAllRecords(updateRecordsParam);

      alert('完了しました');
      location.reload();
    };

    kintone.app.getHeaderMenuSpaceElement().appendChild(button);

    return event;
  });
})();

 

また、ドットとブラケット([])の使い分けですが、オブジェクトの中にアクセスする際、ドットで繋ぐと次の値は文字列、ブラケットで繋ぐと変数として扱うことができ、

let record = {
'ルックアップ': {
value: 'ルックアップの値'
}
}

というオブジェクトがあった場合

// ①
record.ルックアップ.value;
// ②
record['ルックアップ']['value'];
// ③
let lookup = 'ルックアップ';
record[lookup].value;
// ④
let look = 'ルック', a = 'val'
record[look + 'アップ'][a + 'ue'];

いずれも同じ意味になります。また、オブジェクトの宣言においてkey(左側)を変数にする場合もブラケット記法にする必要があります。私はよく「record[‘ルックアップ’].value」と書きますが、単純にフィールドコードであることが分かりやすくなる意味で使っているだけです。

このあたりは慣れてくれば必ず理解できるようになります。

mls-hashimoto 様

詳細本当に本当にありがとうございます
またお礼の返事が遅れてしまい申し訳ありません

実際に動くことが確認できました!!

また詳細なコードだけでなく、javascriptの書き方までご教授いただき本当に感謝ですm(_ _)m
引き続きkintoneのチュートリアル等の勉強はもちろん、本でも基礎から学びはじめました

色々試してみたいことがあるので、また不明な点などこちらのコミュニティに質問させていただくこともあるかもしれませんが、頑張って習得したいと思います

本当にありがとうございました