同一アプリ内でのボタン押下によるテーブルコピーについて

同一アプリ内にあるテーブルAに、テーブルBの値を各ボタンを押下した際にコピーしようと試みているのですが、いまいちキレイに実現してくれません。
長文になり申し訳ございませんが、お助けいただきますようお願い申し上げます。

テーブルA:内容
テーブルB:リスト外
※2つのテーブルのフィールドは一致していません。
※機器代と工事代でボタンを分けている理由は、テーブルBでは同じ行に入力されていますが、テーブルAでは同一フィールドにバラして入力するためです。

<現状の問題点>
①テーブルBの各フィールドの値や行追加・削除後にコピーボタンを押下すると、テーブルAに一度コピーはされるのですが、テーブルBが編集前の入力値にリセットされたり、追加した行が消えてしまいます。
➁機器代コピーボタン押下時は、機器代単価が0の行以外を、工事代コピーボタン押下時は、工事代単価が0の行以外をコピーしたいのですが、1回目のボタン押下時は、0の行以外のみをコピーしますが、いずれかのボタンを再度押下すると、機器代工事代問わず0の行もコピーされます。

エラーメッセージは、出ていません。

<実現したいこと>
①上記2点の問題解決
➁テーブルBからテーブルAにコピー後、テーブルAのルックアップフィールドの自動取得

<補足>
テーブルAには、別のテーブルCからプラグインを利用して、ルックアップ先のテーブルデータも展開しているため、テーブルAを都度クリアしての操作は避けたいです。

kintone.events.on (['app.record.create.show','app.record.edit.show'], (event) => {
       const record = event.record;
       const copyButton1 = document.createElement('button');
       copyButton1.id = 'button_outListCopy1';
       copyButton1.innerText = '機器代コピー';

       const copyButton2 = document.createElement('button');
       copyButton2.id = 'button_outListCopy2';
       copyButton2.innerText = '工事代コピー';

       if (document.getElementById('button_outListCopy1') !== null){
         return;
       }
       if (document.getElementById('button_outListCopy2') !== null){
        return;
      }

       copyButton1.onclick = () => {
          const newRecord = kintone.app.record.get().record;
          const contentsTable = record.内容.value;
          const outListTable = newRecord.リスト外.value;
          
          outListTable.forEach ((tableRow2) => {
              contentsTable.push({
                  value:{
                     '内容_行':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_並び順':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_種別':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_項目':{
                          value: tableRow2.value.リスト外_商品名.value,
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_数量':{
                          value: tableRow2.value.リスト外_数量.value,
                          type: 'NUMBER'
                     },
                     '内容_単位':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_単価':{
                          value: tableRow2.value.リスト外_機器代単価.value,
                          type: 'NUMBER'
                     },
                     '内容_金額':{
                          value: '',
                          type: 'CALC'
                     },
                     '内容_実在庫数':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_型番':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_商品No':{
                          value: '0',
                          type: 'NUMBER'
                     },
                     '内容_出庫登録':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },            
              }
              });
              if (tableRow2.value.リスト外_機器代単価.value > 1){
                kintone.app.record.set({record: record});
              }        
          });
       }
       
       copyButton2.onclick = () => {
          const newRecord = kintone.app.record.get().record;
          const contentsTable = record.内容.value;
          const outListTable = newRecord.リスト外.value;
        
          outListTable.forEach ((tableRow2) => {
              contentsTable.push({
                  value:{
                     '内容_行':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_並び順':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_種別':{
                          value: '基本工事費',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_項目':{
                          value: tableRow2.value.リスト外_商品名.value,
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_数量':{
                          value: tableRow2.value.リスト外_数量.value,
                          type: 'NUMBER'
                     },
                     '内容_単位':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_単価':{
                          value: tableRow2.value.リスト外_工事代単価.value,
                          type: 'NUMBER'
                     },
                     '内容_金額':{
                          value: '',
                          type: 'CALC'
                     },
                     '内容_実在庫数':{
                          value: '',
                          type: 'NUMBER'
                     },
                     '内容_型番':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },
                     '内容_商品No':{
                          value: '0',
                          type: 'NUMBER'
                     },
                     '内容_出庫登録':{
                          value: '',
                          type: 'SINGLE_LINE_TEXT'
                     },            
                  }
              });
              if (tableRow2.value.リスト外_工事代単価.value > 1){
                kintone.app.record.set({record: record});
              }        
          });
       }

        kintone.app.record.getSpaceElement('button_outListCopy1').appendChild(copyButton1);
        kintone.app.record.getSpaceElement('button_outListCopy2').appendChild(copyButton2);

     return event;
    });

@shi.K さん

こんにちは、少しお力添えできそうだったので回答してみました。
①と②に対して、順にご回答させていただきますね。


①テーブルBの各フィールドの値や行追加・削除後にコピーボタンを押下すると、テーブルAに一度コピーはされるのですが、テーブルBが編集前の入力値にリセットされたり、追加した行が消えてしまいます。

こちらの理由ですが、

const record = event.record;

copyButton1.onclick = () => {
          const newRecord = kintone.app.record.get().record;
          const contentsTable = record.内容.value;
          const outListTable = newRecord.リスト外.value;
       
          outListTable.forEach ((tableRow2) => {
              contentsTable.push({
                  //~テーブルの中身は略~
              });
              if (tableRow2.value.リスト外_機器代単価.value > 1){
                kintone.app.record.set({record: record});
              }        
          });
       }

このようにされていますが、リスト外_機器代単価.value > 1の時にcopyButton1.onclick()のスコープ外で宣言しているレコードを新規作成・編集画面表示時のeventオブジェクトのconst record = event.record;kintone.app.record.set({record: record});で更新してしまっているからそうなるんじゃないかなと思っています。
テストした状況としても、テーブルBを編集前に押してテストしていませんか?

const record = event.record;

copyButton1.onclick = () => {
          const rec =  kintone.app.record.get();
          const newRecord = rec.record;
          const contentsTable = record.内容.value;
          const outListTable = newRecord.リスト外.value;
       
          outListTable.forEach ((tableRow2) => {
              contentsTable.push({
                  //~テーブルの中身は略~
              });
              if (tableRow2.value.リスト外_機器代単価.value > 1){
                kintone.app.record.set(rec);
              }        
          });
       }

に変えてあげればパッと見では解決するんじゃないかなと思っています。


➁機器代コピーボタン押下時は、機器代単価が0の行以外を、工事代コピーボタン押下時は、工事代単価が0の行以外をコピーしたいのですが、1回目のボタン押下時は、0の行以外のみをコピーしますが、いずれかのボタンを再度押下すると、機器代工事代問わず0の行もコピーされます。

見てて思いましたが、ボタンを押すたびにAテーブルにBテーブルの中身を新規追加し続けているように見えます。
恐らく実現されたい事をしようと思うと、BテーブルからAテーブルに何行目にコピーしたといったデータ(行番号など)を行ごとに記録してコピーするデータを比較しながら挿入しなければならないんじゃないかなと思ってます :sweat_drops:


以上回答になったかわかりませんが、回答させていただきました。
「いいね!」 1

@y_minamitani9534
ご回答いただき、ありがとうございます。

①教えていただいたコードをもとに、早速試してみたのですが…
コピーすらされなくなってしまいました。エラーも出ておりません。
テストしていた状況としましては、
・アクションボタンで別アプリからコピーしてきたテーブルBを未編集でボタン押下
・一度ボタン押下しコピー後に、テーブルBを編集し、もう一度押下
・一度ボタン押下しコピー後にテーブルAでコピーされた行を削除、テーブルBを編集し、もう一度押下
など、いろんなパターンを想定していたのですが、動作を固定した方が良さそうですか?

もしくは、一度ボタンでコピーした後は、下記リンク先で他の方にご回答されているようにchangeイベントで追加・編集した行のみをpushした方がいいのでしょうか?
https://community.cybozu.dev/t/topic/8042
こちらでも機器代のみ、工事代のみ、機器代・工事代のみのパターンでテーブルBが入力されている場合によって、書き分けできるのでしょうか?

➁については、試していないのですが、ご意見をお伺いするに、大変そうなので、テーブルA側で単価0の行削除の処理を入れてみようかなと思います。

@shi.K さん

反映されない原因として、こちらに変えていただいたら反映されるかと思われます :sweat_drops:

const record = event.record;

copyButton1.onclick = () => {
          const rec =  kintone.app.record.get();
          const newRecord = rec.record;
          //↓ここが record.内容.value; になっていたので以下のように変更しました。
          const contentsTable = rec.内容.value;
          const outListTable = newRecord.リスト外.value;
       
          outListTable.forEach ((tableRow2) => {
              contentsTable.push({
                  //~テーブルの中身は略~
              });
              if (tableRow2.value.リスト外_機器代単価.value > 1){
                kintone.app.record.set(rec);
              }        
          });
       }

上記コメントで修正部分書いてますが、kintone.app.record.get();で取得したものに対して変更してなかったので、テーブルAに反映されなかったものだと思われます。


こちらでも機器代のみ、工事代のみ、機器代・工事代のみのパターンでテーブルBが入力されている場合によって、書き分けできるのでしょうか?

こちらですが、問題なくできますよ!
if文を以下のように else if使ってあげて条件分岐してあげてもいいですし、switch文つかってもできますね。

if(//条件1をこちらに){
    //条件1にあてはまったらこちらの処理が実行
}else if(//条件2をこちらに){
    //条件2にあてはまったらこちらの処理が実行
}else{
    //条件1も条件2もどちらも当てはまらなければこちらの処理を実行
}

ちなみに上から順番に条件を見ていきますので、途中でどちらにもあてはまるような条件が出てきてしまったらそちらで処理されてしまうので注意が必要です。
詳しくはこちら↓


テーブルA側で単価0の行削除の処理を入れてみようかなと思います。

恐らくですが、こちらしてもBテーブルの情報をボタンを押すたびに重複した内容を転記されるんじゃないかなと思います…
条件として、Bテーブルの行レコードに何か識別べきる行番号などをふってあげて、Aテーブルに転記するさいにAテーブルに対象の行番号は存在するのか?存在すのであれば、更新のみ。存在しないのであれば、新規に行を追加してあげないといけないんじゃないのかなと思います :sweat_drops:

「いいね!」 1

@y_minamitani9534
ご回答いただき、ありがとうございます。

反映されない原因として、こちらに変えていただいたら反映されるかと思われます :sweat_drops:

こちら残念ながら、ご提示いただいたコードでは、実現できませんでした。
教えていただいたヒントと途中まで出来ていたコードをもとに、最終的にはイベントを分けて、下記のようなコードで理想に近づけることができました!

  //リスト外をボタンでコピーする
    kintone.events.on (['app.record.create.show','app.record.edit.show'], (event) => {
       const record = event.record;
       const copy_button = document.createElement('button');
       copy_button.id = 'button_outListCopy';
       copy_button.innerText = 'リスト外をコピー';

       if (record.リスト外追加.value.length !== 0){
         if (document.getElementById('button_outListCopy') !== null){
               return;
         }
       }

       copy_button.onclick = () => {
          const newRecord = kintone.app.record.get().record;
          const contentsTable = record.内容.value;
          const outListTable = newRecord.リスト外.value;
          
          outListTable.forEach ((tableRow2) => {
             const equipmentFee = {
                      //~テーブルの中身は略~
             };

             const constructionFee = {
                     //~テーブルの中身は略~
             };

             if (tableRow2.value.リスト外_機器代単価.value > 1 && tableRow2.value.リスト外_工事代単価.value > 1){
               contentsTable.push(equipmentFee,constructionFee);
               kintone.app.record.set({record: record});
             } else if (tableRow2.value.リスト外_機器代単価.value > 1){
               contentsTable.push(equipmentFee);
               kintone.app.record.set({record: record});
             } else if (tableRow2.value.リスト外_工事代単価.value > 1){
               contentsTable.push(constructionFee);
               kintone.app.record.set({record: record});
             }

          });

       }

       kintone.app.record.getSpaceElement('button_outListCopy').appendChild(copy_button);

     return event;
    });

    //リスト外を行ごとにチェックボックスでコピー
    kintone.events.on (['app.record.create.change.リスト外_コピー',
                        'app.record.edit.change.リスト外_コピー'], (event) => {
       const record = event.record;
       const changes = event.changes;
       const contentsTable = record.内容.value;
       const equipmentFee = {
                //~テーブルの中身は略~
             };
       const constructionFee = {
                //~テーブルの中身は略~
             };

       if (changes.field.value.length !== 0){
         if (changes.row.value.リスト外_機器代単価.value > 1 && changes.row.value.リスト外_工事代単価.value > 1){
           contentsTable.push(equipmentFee,constructionFee);
         } else if (changes.row.value.リスト外_機器代単価.value > 1){
           contentsTable.push(equipmentFee);
         } else if (changes.row.value.リスト外_工事代単価.value > 1){
           contentsTable.push(constructionFee);
         }
         changes.field.value = [];
       }
 
     return event;
    });

また、機器代・工事代単価が0の行が何度もコピーされてしまう現象については、私がif文を入れるところを間違えていたみたいです… :sweat_drops:

ご丁寧にいろいろと教えていただき、本当にありがとうございました :bowing_woman:

「いいね!」 1

@shi.K さん

解決したようでなによりです :sweat_drops:
私完全に見落としてましたが、ボタン1と2があったのですね :sweat_drops:
やはりrecord.内容.valueの部分がどうしても気になってしまいますね…通常.onclick()などで使う形として、kintone.app.record.get()で現在表示しているレコードの最新の状態を取得してきて利用する形になるので…
まぁでもうまく行ってるようでしたら、問題ございませんよね :sweat_drops:
こちらいらぬ考えかもしれませんので、お忘れください :sweat_smile:

@y_minamitani9534 様のお力添えがあったからこそです。

はい、ボタン1と2がありましたが、if文でなんとか書き分けられたため、ボタンを1つに統合できました。

やはりrecord.内容.value の部分がどうしても気になってしまいますね …通常.onclick()などで使う形として、kintone.app.record.get() で現在表示しているレコードの最新の状態を取得してきて利用する形になるので…

そうなんですね :thinking:
ただ、そちらにkintone.app.record.get()を利用すると、どうにも動作しませんでした…。
「内容」がコピー先のテーブルのため、pushするときには、最新状態か否かがあまり関係なかったのでしょうか…。
また後学のためにも頭の片隅に入れておきます。

お付き合いくださり、本当にありがとうございました。

「いいね!」 1

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