別アプリのテーブルデータを現アプリのテーブルに取得する

初めて投稿させていただきます。
社内でkintoneを使うことになったのですが、コードに強い方がいなく、教えて頂きたいです。

別アプリの指定レコードのテーブルデータを、現アプリのレコード編集画面時に同一のテーブルに表示させたいのですが、上手くできません。
以下の記事の「パターン1:REST APIを使って参照する」が、おそらく目的に使いものと思い、色々トライしてみました。

(上記の記事でいえば、「旅費精算申請」アプリから「旅費」テーブルのデータを取得し、「出張申請」アプリに作った「旅費」テーブルに表示したいです)
指定のアプリを使って、別アプリの指定レコード(出張申請番号=2)のサブテーブル情報を、レコード編集画面時にスペースへ表示させる事まではできました。
ただ、やりたいことは"スペース”ではなく、”テーブル”へ表示させないのですが、それが上手くできません。
作ってみたコードは下になります。

分かる方がいらっしゃれば、教えていただけると大変助かります。

何卒宜しくお願いいたします。


(() => {
  'use strict';

  kintone.events.on(['app.record.edit.show','app.record.create.show'],(event) => {

    // 「旅費精算申請アプリ」のアプリのIDに書き換えてください
    const APP_ID = 65;

    // 「出張申請番号」として利用する「レコード番号」を取得
    const applicationNumber = kintone.app.record.getId();

    // フィールドコードを変数に格納
    const businessTripExpenses = '旅費';
    const date = '旅費日付';
    const transportation = '手段';
    const summary = '旅費摘要';
    const amount = '旅費金額';
    const receipt = '旅費領収書';
    
    // 「旅費精算申請アプリ」のサブテーブルオブジェクトを取得
    const travelExpenseAppRecord = event.record;
    const tableRows = travelExpenseAppRecord[businessTripExpenses].value;

    // 「旅費精算申請アプリ」情報を表示する表を作成
    const tableHtml = `<thead><tr>
        <th>${date}</th>
        <th>${transportation}</th>
        <th>${summary}</th>
        <th>${amount}</th>
        <th>${receipt}</th>
      </tr></thead>
    </tbody>`;

    // スペースフィールドに作成した表を表示
    const tableEl = document.createElement('table');
    tableEl.id = 'table';
    tableEl.border = '1';
    tableEl.style.textAlign = 'center';
    tableEl.style.padding = '10px';
    tableEl.insertAdjacentHTML('afterbegin', tableHtml);
    kintone.app.record.getSpaceElement('tableSpace').appendChild(tableEl);

    // 「旅費精算申請アプリ」から「出張申請番号」が同じのレコードを取得
    const params = {
      'app': APP_ID,
      'query': `出張申請番号 = 2`
    };
    return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {

      const travelExpenseAppRecords = resp.records;


      // 取得した「旅費精算申請アプリ」のテーブルデータを作成した表に格納
      const tableRows = travelExpenseAppRecords[0][businessTripExpenses].value;
      const tableRef = document.getElementById('table');

      tableRows.forEach((row) => {
        const tableRow = tableRef.insertRow(-1);
        const cell1 = tableRow.insertCell(-1);
        const cell2 = tableRow.insertCell(-1);
        const cell3 = tableRow.insertCell(-1);
        const cell4 = tableRow.insertCell(-1);
        const cell5 = tableRow.insertCell(-1);

        cell1.appendChild(document.createTextNode(row.value[date].value));
        cell2.appendChild(document.createTextNode(row.value[transportation].value));
        cell3.appendChild(document.createTextNode(row.value[summary].value));
        cell4.appendChild(document.createTextNode(row.value[amount].value));
        cell5.appendChild(document.createTextNode(row.value[receipt].value));
      });
      return event;
    });
  });
})();

サブテーブル(レコード内フィールド)へ反映させるためには、今回の場合
フィールドの値を書き換える
が必要です。
リンク先にちょうどサブテーブルの行追加や1行目の入力が掲載されているので参考になると思います。

      const travelExpenseAppRecords = resp.records;


      // 取得した「旅費精算申請アプリ」のテーブルデータを作成した表に格納
      const tableRows = travelExpenseAppRecords[0][businessTripExpenses].value;
      const tableRef = document.getElementById('table');

      tableRows.forEach((row) => {
        const tableRow = tableRef.insertRow(-1);
        const cell1 = tableRow.insertCell(-1);
        const cell2 = tableRow.insertCell(-1);
        const cell3 = tableRow.insertCell(-1);
        const cell4 = tableRow.insertCell(-1);
        const cell5 = tableRow.insertCell(-1);

        cell1.appendChild(document.createTextNode(row.value[date].value));
        cell2.appendChild(document.createTextNode(row.value[transportation].value));
        cell3.appendChild(document.createTextNode(row.value[summary].value));
        cell4.appendChild(document.createTextNode(row.value[amount].value));
        cell5.appendChild(document.createTextNode(row.value[receipt].value));
      });

この部分で「取得したレコードの1件目(travelExpenseAppRecords[0])にあるサブテーブルの行数分処理をループ(forEach)させ、ループ内でスペースに表示する内容を描画」という処理になっているんですが、この部分をサブテーブル内フィールドへの値の書き換えに変えるイメージです。

橋本大輔さま
さっそくコメント頂きまして、大変ありがとうございます。
私のためにお時間を作って頂き、また、考えて頂いたことについて、心より感謝申し上げます。

参考URL、確認させていただきました。
私は全くの素人ですが、橋本さまのご指摘箇所のコードをサブテーブル内フィールドへ変更するような対応を試みればよいのだろうと、との印象が元々あり、それが今回間違いないことが分かって、大変嬉しく思っています。

ただ、どう変更すればよいのかが分からず、これまで10時間程度悩み、今回投稿に至りました。
甘えてしまいすみませんが、ズバリではなくとも、何か方向性が掴めるようなサンプルコードなどありましたら、ご教示頂きたく、どうぞお願いいたします。

sakana さま

方向性が掴めるようなサンプルコードであればkintoneにおけるテーブル操作の基本が参考になると思います。とはいえこれだけ覚えれば良いかというとそうではなく、実際にはREST APIやPromiseも知っておかなければならない(投稿されたコードはどちらもできていますが、意味を理解できていないと応用ができません)ので、本気で覚えられるならチュートリアルを1から進めてもかなり時間が掛かると思います。
とはいえお困りなのも事実だと思うので、今回のことが解決したら時間のある時にチュートリアルを進めるのが良いでしょう。

ズバリで回答する場合は各フィールドのフィールドコードだけでなくフィールド形式も分からないと私も回答できないので、簡単なサンプルですが

	return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
		event.record[businessTripExpenses].value = resp.records[0][businessTripExpenses].value.map((row) => {
			return {
				value: {
					[date]: {
						type: 'DATE',
						value: row.value[date].value
					},
					[transportation]: {
						type: '',
						value: row.value[transportation].value
					},
					// サブテーブルのフィールド分記載
				}
			}
		});

		return event;
	});

こんな感じになります(出張申請アプリのサブテーブルや各フィールドのフィールドコード=旅費精算申請アプリのフィールドコードという前提で記載しています。違う場合は[date]や[transportation]をそれぞれ出張申請アプリのフィールドコードに書き換えます)。

これらを出張申請アプリのサブテーブルにあるフィールド分足す必要があり、またフィールドのvalue(値)だけでなく、フィールドのtype(フィールド形式)も必要です。
こちらについてはフィールド形式のページを参照して下さい。

1 Like

両アプリに配置しているサブテーブルが同じ設定であれば、
レコード取得処理 “GET” で取得したサブテーブルの value を、
イベントオブジェクトのサブテーブルの value に代入する方法で、
コピーすることもできます。以下にサンプルコード記載します。

※ どちらもサブテーブルのフィールドコードが “テーブル” の場合の、
サンプルコードを記載します。

(() => {
  "use strict";

  kintone.events.on("app.record.create.show", async (event) => {
    const record = event.record;
    const body = {
      app: {コピー元アプリのアプリID},
      id: {コピー元アプリのレコードID},
    };

    const resp = await kintone.api(
      kintone.api.url("/k/v1/record.json", true),
      "GET",
      body
    );
    const table = resp.record.テーブル.value;
    record.テーブル.value = table;
    return event;
  });
})();

余裕が出てきたら以下のページも確認してみてください。

1 Like

橋本大輔さま

ありがとうございます!できました!!
最終的なコードは下になりました!

私のつたない説明でもサンプルコードを検討いただけたことに大変感謝しています。
また、このような短時間で回答をいただけるとは、正直、全く思っていなかったため、心より驚いております。
感謝の言葉しか申し上げられませんが、この度は、ありがとうございました。
なぜこれで上手くいくのか理解が追い付いていませんが、チュートリアルなど見て勉強させていただきます。

(() => {
  'use strict';

  kintone.events.on(['app.record.edit.show','app.record.create.show'],(event) => {

    // 「旅費精算申請アプリ」のアプリのID
    const APP_ID = 65;

    // 「出張申請番号」として利用する「レコード番号」を取得
    const applicationNumber = kintone.app.record.getId();

    // フィールドコードを変数に格納
    const businessTripExpenses = '旅費';
    const date = '旅費日付';
    const transportation = '手段';
    const summary = '旅費摘要';
    const amount = '旅費金額';
    const receipt = '旅費領収書';
    
    // 「旅費精算申請アプリ」のサブテーブルオブジェクトを取得
    const travelExpenseAppRecord = event.record;
    const tableRows = travelExpenseAppRecord[businessTripExpenses].value;

    // 「旅費精算申請アプリ」から「出張申請番号」が2のレコードを取得
    const params = {
      'app': APP_ID,
      'query': `出張申請番号 = 2`
    };
    return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
    event.record[businessTripExpenses].value = resp.records[0][businessTripExpenses].value.map((row) => {
			  return {
				value: {
					[date]: {
						type: 'DATE',
						value: row.value[date].value
					},
					
					[transportation]: {
						type: 'DROP_DOWN',
						value: row.value[transportation].value
					},
					
					[summary]: {
						type: 'SINGLE_LINE_TEXT',
						value: row.value[summary].value
					},
										
					[amount]: {
						type: 'NUMBER',
						value: row.value[amount].value
					},

					[receipt]: {
						type: 'CHECK_BOX',
						value: row.value[receipt].value
					},
				}
			}
		});
		return event;
    });
  });
})();
1 Like

このトピックは最後の返信から 60 分が経過したので自動的にクローズされました。新たに返信することはできません。