# アプリのテーブルから他のアプリのテーブルにデータを移したい

**URL:** <https://community.cybozu.dev/t/topic/83>\
**Category:** kintone 開発相談\
**Created:** [2022 年 9 月 20 日午前 2:36 UTC](https://community.cybozu.dev/t/topic/83 "2022-09-20T02:36:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Legacy\_Account37](https://avatars.discourse-cdn.com/v4/letter/l/977dab/32.png) [@Legacy\_Account37](https://community.cybozu.dev/u/Legacy_Account37)\
**Post date:** [2022 年 9 月 20 日午前 2:36 UTC](https://community.cybozu.dev/t/topic/83/1 "2022-09-20T02:36:21Z")

</div>

【実現したいこと】

アプリ（案件管理）でレコード更新時、記入されているテーブルの一部のデータを他のアプリ（請求書管理）にコピーしたいと思っております。

その際、請求書管理アプリ内で[請求月]・[取引先コード]を条件に、既に同条件のレコードがあれば、レコードのテーブルを追加してコピー、なければレコード作成しテーブルにコピーできればと考えております。

案件管理のテーブルから請求書管理のテーブルにコピーするデータは[明細行ID]・[行の種類]・[請求明細名]・[数量]・[単位]・[単価]・[金額]の7つです。

【問題点】

①下記コードで実行したところ、既存レコードにおいてはクエリでの検索は問題なく出来ておりましたが、テーブルを追加してコピーはできませんでした。

②下記コードだと新しくレコード作るものははいっていないためどうのように記述すればよろしいでしょうか。

コミュニティ内で参考にできそうなコードをもとに作成してみました。しかし、エラーはでておりませんが、うまくテーブルの値が反映されませんでした。初心者で無知なためご教授いただければ幸いです。

&nbsp;

&nbsp; kintone.events.on([“app.record.create.submit”, “app.record.edit.submit”],  
&nbsp; async function(event) {  
&nbsp; &nbsp; &nbsp; &nbsp; const record = event.record;  
&nbsp; &nbsp; &nbsp; &nbsp; const seitable =record.請求書.value;  
&nbsp; &nbsp; &nbsp; &nbsp; const torihikicode = record.取引先コード.value;  
&nbsp; &nbsp; &nbsp; &nbsp; const month = record.請求月.value;

&nbsp; &nbsp; &nbsp; &nbsp; for (var o = 0; o \< seitable.length; o++) {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const mei = seitable[o].value[“明細行ID”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const gyou = seitable[o].value[“行の種類”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const sei = seitable[o].value[“請求明細名”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const suu = seitable[o].value[“数量”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const tani = seitable[o].value[“単位”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const tanka = seitable[o].value[“単価”].value  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const kingaku = seitable[o].value[“金額”].value

```
 &nbsp; &nbsp; &nbsp; &nbsp;const paramForGetStock1 = {'app': 603,  

```

&nbsp; &nbsp; &nbsp; &nbsp;‘query’: ‘請求月 in ("’ + month + ‘") and 取引先コード= "’ +torihikicode+ ‘"’,}

&nbsp; &nbsp; &nbsp; &nbsp;const resp = await kintone.api(kintone.api.url(‘/k/v1/records’,true),‘GET’, paramForGetStock1);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(resp);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!resp.records.length) return;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resp.records.forEach(async function(record) {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const seikyuTable = record[“請求明細行”].value;  
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let seikyuTable\_ID = [];  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var m = 0; m \< seikyuTable.length; m++) {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; seikyuTable\_ID[m] = seikyuTable[m].value[“ID”]}  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let appended\_subtable = [];  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let subtable = [];  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!seikyuTable\_ID.includes(mei)) {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (let m = 0; m \< seikyuTable.length; m++) {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subtable.push(seikyuTable[m]);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subtable.push({  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value: {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “明細行ID”: {“value”:mei},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “行の種類”:{“value”:gyou},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “請求明細名”:{“value”:sei},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “数量”:{“value”:suu},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “単位”:{“value”:tani},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “単価”:{“value”:tanka},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “金額”: {“value”:kingaku}  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }});

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const paramForPut1 = {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “app”: 603,  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “id”: resp.records[0].$id.value,  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “record”: {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “明細行ID”: {“value”:mei},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “行の種類”:{“value”:gyou},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “請求明細名”:{“value”:sei},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “数量”:{“value”:suu},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “単位”:{“value”:tani},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “単価”:{“value”:tanka},  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; “金額”: {“value”:kingaku}  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }  
}

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(paramForPut1);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appended\_subtable.push(paramForPut1);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; subtable = subtable.concat(appended\_subtable);&nbsp;  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var put\_record = {};  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put\_record[“請求明細行”] = {  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value: subtable  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const put\_resp = await kintone.api(kintone.api.url(“/k/v1/record.json”, true), “PUT”, paramForPut1);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(put\_resp);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}else {}

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.alert(“請求書管理に反映しました。”);  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return event;  
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })}})

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1177](https://avatars.discourse-cdn.com/v4/letter/l/77aa72/32.png) [@Legacy\_Account1177](https://community.cybozu.dev/u/Legacy_Account1177)\
**Post date:** [2022 年 9 月 20 日午前 8:40 UTC](https://community.cybozu.dev/t/topic/83/2 "2022-09-20T08:40:22Z")

</div>

動作確認等はしておりませんが、おそらく以下のような形で可能かと思います。  
PUTで更新するサブテーブルについても行を更新するのか追加するのかの判定が必要なので「明細行ID」が一致する行は更新、一致しない行は追加するようにしています。

```
(() => {
  'use strict';

  kintone.events.on([
  'app.record.create.submit', 'app.record.edit.submit'
], async (event) => {
  let record= event.record;
  let copyFields = ['明細行ID', '行の種類', '請求明細名', '数量', '単位', '単価', '金額'];
  let subTableValue = [];

    record['請求書'].value.forEach((row) => {
    let subTableRow = {value: {}};

    copyFields.forEach((field) => {
      subTableRow.value[field] = {
        value: row.value[field].value
      };
    });

      subTableValue.push(subTableRow);
  });

    let paramForGetStock1 = {
    app: 603,
    query: `請求月 in ("${record['請求月'].value}") and 取引先コード = "${record['取引先コード'].value}"`
  };

    let resp = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', paramForGetStock1);

  if (resp.records.length) {
    subTableValue.forEach((row) => {
      let matchIndex = resp.records[0]['請求明細行'].value.findIndex((respRow) => respRow.value['明細行ID'].value === row.value['明細行ID'].value);

        if (matchIndex >= 0) {
        resp.records[0]['請求明細行'].value[matchIndex].value = row.value;
      } else {
        resp.records[0]['請求明細行'].value.push({
value: row.value
});
      }
    });

      let putRecord = {
      app: 603,
      id: resp.records[0]['$id'].value,
      record: {
        '請求明細行': {
          value: resp.records[0]['請求明細行'].value
        }
      }
    };

      await kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', putRecord);
  } else {
    let postRecord = {
      app: 603,
      record: {
        '請求明細行': {
          value: subTableValue
        }
      }
    };

      await kintone.api(kintone.api.url('/k/v1/record', true), 'POST', postRecord);
  }

    return event;
});
})();

```

---

<div class="post-metadata">

**Author:** ![Legacy\_Account37](https://avatars.discourse-cdn.com/v4/letter/l/977dab/32.png) [@Legacy\_Account37](https://community.cybozu.dev/u/Legacy_Account37)\
**Post date:** [2022 年 9 月 20 日午前 9:07 UTC](https://community.cybozu.dev/t/topic/83/3 "2022-09-20T09:07:44Z")

</div>

mls-hashimoto様

コードのお手本、まことにありがとうございます。

頂いたコードをもとにやってみます!

大変お手数ですが、わからないことがあれば再度ご質問させて頂ければと思います。

---

<div class="post-metadata">

**Author:** ![Legacy\_Account37](https://avatars.discourse-cdn.com/v4/letter/l/977dab/32.png) [@Legacy\_Account37](https://community.cybozu.dev/u/Legacy_Account37)\
**Post date:** [2022 年 9 月 21 日午前 3:01 UTC](https://community.cybozu.dev/t/topic/83/4 "2022-09-21T03:01:59Z")

</div>

mls-hashimoto様

教えて頂いたコードを実行してみたのですが、画像のようなエラーが出てしまいます。

自力で原因を探してみたのですが、うまくできずご意見頂ければと思います。

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1177](https://avatars.discourse-cdn.com/v4/letter/l/77aa72/32.png) [@Legacy\_Account1177](https://community.cybozu.dev/u/Legacy_Account1177)\
**Post date:** [2022 年 9 月 21 日午前 5:04 UTC](https://community.cybozu.dev/t/topic/83/5 "2022-09-21T05:04:45Z")

</div>

izumi keisuke さま

クエリ文字列の「請求月 in (…)」 が「 請求月 = (…)」になっています。提示されたコードから請求書管理アプリの請求月フィールドはドロップダウン、チェックボックスまたはラジオボタンという認識でしたが、違っていたでしょうか？

フィールドごとに使用できる演算子に違いがあり、ドロップダウンやラジオボタンでは「in (…)」文字列フィールド等では「 = …（括弧は使用しない）」と使い分ける必要があるので「請求月 in (“8”)」か「請求月 = “8”」となるのが正しいクエリ文字列です。

[このあたり](https://community.cybozu.dev/hc/ja/articles/202331474#q1) で詳しく解説されています。

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1177](https://avatars.discourse-cdn.com/v4/letter/l/77aa72/32.png) [@Legacy\_Account1177](https://community.cybozu.dev/u/Legacy_Account1177)\
**Post date:** [2022 年 9 月 21 日午前 5:31 UTC](https://community.cybozu.dev/t/topic/83/6 "2022-09-21T05:31:12Z")

</div>

動作確認して不具合のあった部分を直しました。

```
(() => {
  'use strict';

kintone.events.on([
    'app.record.create.submit', 'app.record.edit.submit'
], async (event) => {
  let record = event.record;
    let copyFields = ['明細行ID', '行の種類', '請求明細名', '数量', '単位', '単価', '金額'];
  let subTableValue = [];

    record['請求書'].value.forEach((row) => {
    let subTableRow = {value: {}};

    copyFields.forEach((field) => {
      subTableRow.value[field] = {
        value: row.value[field].value
      };
    });

      subTableValue.push(subTableRow);
  });

    let paramForGetStock1 = {
    app: 603,
    query: `請求月 in ("${record['請求月'].value}") and 取引先コード = "${record['取引先コード'].value}"`
  };

    let resp = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', paramForGetStock1);

    if (resp.records.length) {
    subTableValue.forEach((row) => {
      let matchIndex = resp.records[0]['請求明細行'].value.findIndex((respRow) => respRow.value['明細行ID'].value === row.value['明細行ID'].value);

        if (matchIndex >= 0) {
        resp.records[0]['請求明細行'].value[matchIndex].value = row.value;
      } else {
        resp.records[0]['請求明細行'].value.push(row);
      }
    });

      let putRecord = {
      app: 603,
      id: resp.records[0]['$id'].value,
      record: {
        '請求明細行': {
          value: resp.records[0]['請求明細行'].value
        }
      }
    };

      await kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', putRecord);
  } else {
    let postRecord = {
      app: 603,
        record: {
        '請求月': {
          value: record['請求月'].value
        },
        '取引先コード': {
          value: record['取引先コード'].value
        },
        '請求明細行': {
          value: subTableValue
        }/* 他に初期登録しておきたいフィールドがあれば追加 */
      }
      };

      await kintone.api(kintone.api.url('/k/v1/record', true), 'POST', postRecord);
  }

    return event;
});
})();

```

---

<div class="post-metadata">

**Author:** ![Legacy\_Account37](https://avatars.discourse-cdn.com/v4/letter/l/977dab/32.png) [@Legacy\_Account37](https://community.cybozu.dev/u/Legacy_Account37)\
**Post date:** [2022 年 9 月 21 日午前 9:56 UTC](https://community.cybozu.dev/t/topic/83/7 "2022-09-21T09:56:35Z")

</div>

mls-hashimoto様

ご指摘いただきありがとうございます。

教えて頂いたコードで無事実装でき動作確認できました。

誠にありがとうございます。

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex015/uploads/cybozu/original/1X/d5c841c3c5a6cb66eed514001c1b45147c9e1f4f.png) [@system](https://community.cybozu.dev/u/system)\
**Post date:** [2024 年 6 月 7 日午前 2:25 UTC](https://community.cybozu.dev/t/topic/83/8 "2024-06-07T02:25:15Z")

</div>

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。
