テーブルを用いた計算の再計算について

お世話になっております。

 

現在、テーブル内に設置してあります金額(数値フィールド)に数値を入力したら、テーブル外に設置してあります残高(自動計算フィールド)で先ほどの数値を利用して計算し計算結果をテーブル内の支払時点残高(数値フィールド)にコピーしております。

<問題点>

以前に質問させて頂いた内容の改善というかリカバリーになるのですが、一度入力した金額の数値が間違えており、修正した際に支払時点残高の値が前後でおかしくなってしまいます。(下記画像参照)

そうなってしまった際に全体の計算を一度に計算しなおすことはできないかと考えております。

 

(やりたいこと)

ボタンをスペースフィールドに設置しそのボタンを押したら再度、計算するというものは考えており現在、スペースフィールドにボタンを設置するJSは作成済みです。

ご教授して頂けますと幸いです。

(比較画像)

(計算コード)

(() => {
  'use strict';

  let subTable = '入金記録'; // サブテーブルのフィールドコード
  let tableNum = '金額'; // サブテーブル「内」の数値フィールド
  let calc = '残高'; // サブテーブル「外」の自動計算フィールド
  let field = '支払時点残高'; // サブテーブル「内」の計算結果を挿入するフィールド

  const changeRowIndex = (event) => {
    let record = event.record;
    for (let i = 0; i < record[subTable].value.length; i++) {
      if (event.changes.row === record[subTable].value[i]) return i;
    }};

  kintone.events.on([
    `app.record.create.change.${tableNum}`, `app.record.edit.change.${tableNum}`
  ], (event) => {
    let rowIndex = changeRowIndex(event);

    setTimeout(() => {
      let recordData = kintone.app.record.get(), rec = recordData.record;

      rec[subTable].value[rowIndex].value[field].value = rec[calc].value;

      kintone.app.record.set(recordData);
    }, 500);

    return event;
  });
})();

 

画像で具体的な希望が理解できたので改めて確認させていただきたいのですが、自動計算フィールドは使わず、例えば「前の行の支払時点残高-次の行の金額=次の行の支払時点残高」といった実装はいかがでしょうか?ボタンによる計算でも恐らく同じような計算になると思います。

mls-hashimoto

いつもお世話になっております。

解決案をご提案して頂きありがとうございます。

 

2つ質問させて頂きます。

・自動計算フィールドは使用せずの場合ですとJSの発火タイミングが 「金額」が変更された時 でよろしいのでしょうか?

・ボタンによる計算の場合はJSのボタンをクリックしたときの処理で「前の行の支払時点残高-次の行の金額=次の行の支払時点残高」という計算処理を追加するという形でよろしいのでしょうか。

nekoko さま

>・自動計算フィールドは使用せずの場合ですとJSの発火タイミングが 「金額」が変更された時
その通りです。以下に都度全ての行を計算するサンプルを用意しましたが、恐らく「品目が現金繰越の場合は金額をそのままコピー」「それ以外の場合は前の行から金額を引く」といった動作になるかと推測いたしましたので、その場合は品目もchangeイベントに登録しておいた方が良いでしょう。

>・ボタンによる計算の場合はJSのボタンをクリックしたときの処理で「前の行の支払時点残高-次の行の金額=次の行の支払時点残高」という計算処理
その通りです。しかし、今まではevent.changes.rowを使って変更された行のみ計算されるようなコードを提示していましたが、今回のような実装ではサブテーブルの配列でループを回し、都度全ての行を計算させるような処理でも良いかもしれません(サブテーブルが数百行に渡る場合はこの限りではありませんが…)。

都度サブテーブルの全ての行を計算するコードは以下になります。

(() => {
  'use strict';

  let subTable = '入金記録'; // サブテーブルのフィールドコード
  let amount = '金額'; // 金額のフィールドコード
  let balance = '支払時点残高'; // 支払時点残高のフィールドコード
  let item = '品目'; // 品目のフィールドコード

  kintone.events.on([
    `app.record.create.change.${amount}`, `app.record.edit.change.${amount}`,
    `app.record.create.change.${item}`, `app.record.edit.change.${item}`
  ], (event) => {
    let record = event.record;

    record[subTable].value.forEach((row, index) => {
      if (!row.value[amount].value) {
        row.value[balance].value = '';
      } else if (row.value[item].value === '現金繰越') {
        row.value[balance].value = row.value[amount].value;
      } else {
        if (index > 0) row.value[balance].value = Number(record[subTable].value[(index - 1)].value[balance].value) - Number(row.value[amount].value);
      }
    });

    return event;
  });
})();

 

ボタンによる計算をさせる場合、スペースのIDを付与した上で以下のようになります。

(() => {
  'use strict';
  
  let subTable = '入金記録'; // サブテーブルのフィールドコード
  let amount = '金額'; // 金額のフィールドコード
  let balance = '支払時点残高'; // 支払時点残高のフィールドコード
  let item = '品目'; // 品目のフィールドコード
  let spaceId = ''; // ボタンを設置するスペースのID

  kintone.events.on([
    'app.record.create.show', 'app.record.edit.show'
  ], (event) => {
    let record = event.record;
    let button = document.createElement('button');

    button.innerHTML = '計算';
    button.onclick = () => {
      let recordData = kintone.app.record.get(), rec = recordData.record;

      rec[subTable].value.forEach((row, index) => {
        if (!row.value[amount].value) {
          row.value[balance].value = '';
        } else if (row.value[item].value === '現金繰越') {
          row.value[balance].value = row.value[amount].value;
        } else {
          if (index > 0) row.value[balance].value = Number(rec[subTable].value[(index - 1)].value[balance].value) - Number(row.value[amount].value);
        }
      });

      kintone.app.record.set(recordData);
    };

    kintone.app.record.getSpaceElement(spaceId).appendChild(button);

    return event;
  });
})();

mls-hashimoto

 

お世話になっております。

 

2パターンのコードのご教授ありがとうございます。

私の方でもボタンを利用したコードの作成をしておりましたが、HTMLやIf条件が足りておらずコードの完成までいけておらずご教授していただいたコードを見てとても勉強になりました。

再計算を実装してほしいと言ってきた方に動作を確認して頂いたところ問題ないとの事でしたのでこのまま実装させて頂きます。

時間のある時にループさせるコードを書いてみようと思います。

 

数々の質問にご教授して頂き誠にありがとうございます。