新規投稿
フォローする

計算フィールドのコピー

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

テーブルに入力した数値を使用して、テーブル外にて自動計算させている計算フィールドの値を計算後にテーブル内に設置してあるフィールドにコピーしたいと考えております。

ご教授して頂けないでしょうか。

(コード)

(function () {
  'use strict';
  const events = [ 'app.record.create.change.残高','app.record.edit.change.残高'];
  kintone.events.on(events, function (event) {
    let currentRow = event.changes.row.value;
    currentRow.支払時点残高.value = event.record.残高.value;
    return event;
  });
})();

 

0

11件のコメント

Avatar
mls-hashimoto

「残高」が自動計算のフィールドでしょうか?自動計算フィールドはchangeイベントを使うことができないため「changeイベントに使用するフィールド(サブテーブル内)」「自動計算フィールド(サブテーブル外)」「計算結果を代入するフィールド(サブテーブル内)」の3つのフィールドがあるかと思います。

例によって自動計算フィールドはchangeイベント内では計算が終了していない状態のため、

①自動計算の計算式と同じ計算をJavaScriptで実行(event.changes.rowが使えるのでこちらの方がおすすめです)

②計算が終わる処理を追加

どちらかで行う必要があります。

②の場合、changeイベントを抜けるためevent.changes.rowが使えなくなるので

(() => {
  'use strict';

  const subTable = 'テーブル'; // サブテーブルのフィールドコード
const events = ['app.record.create.change.残高','app.record.edit.change.残高'];
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(events, (event) => {
  let record = event.record;
  let rowIndex = changeRowIndex(event);

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

    rec[subTable].value[rowIndex].value['支払時点残高'].value = rec['残高'].value;

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

    return event;
});
})();

といったようにサブテーブルのインデックス番号を求める必要があります。

mls-hashimotoにより編集されました
1
Avatar
nekoko

mls-hashimoto

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

>「残高」が自動計算のフィールドでしょうか?

説明不足で申し訳ございません。おっしゃる通り 残高 です。

方法及び、②にて使用するコードのご教授ありがとうございます。

おすすめして頂いた①を実装したいのですが、計算に用いる数値が毎月変わるので②の方法で試してみようと思います。

 

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

1
Avatar
nekoko

mls-hashimoto様 

こんにちは、お世話になっております。

 

いくつか分からない点が出てきましたのでご質問させていただきます。

 

1・頂いたコードの1行目が (() => { となってるのですが (function () { と記載しないのはなぜなのでしょうか?

2・求めたサブテーブルのインデックス番号を用いてコピーするコードを書けばよろしいのでしょうか?

 

宜しくお願い致します。

nekokoにより編集されました
0
Avatar
村濱一樹

よこからすいません。

1に関しては、新しいJavaScriptの書き方です!こちらを参照してみてください。

1
Avatar
mls-hashimoto

nekoko さま

1.村濱さまが回答された通りです。

2.その通りです。サブテーブル(配列)の値を書き換える場合、配列の何番目かを指定する必要があり、その何番目かの数字をchangeRowIndexで取得しています。

1
Avatar
nekoko

村濱一樹様、mls-hashimoto様

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

 

ご回答ありがとうございます。

村濱様、説明されているページのリンクありがとうございます。

changeRowIndex を今まで使用したことが無いので調べながらコードの作成をしていきたいと思います。

 

また不明な点が出てきましたら質問させて頂きます。

 

1
Avatar
nekoko

村濱一樹様、mls-hashimoto様

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

changeRowIndexを調べてもなかなか検索にヒットせず、自力でのコード作成が止まっております。

コピーしたいテーブルの対象インデックス番号?が7と言う事はわかりました。

なにかヒントを頂けないでしょうか。

 

 

 

0
Avatar
mls-hashimoto

nekoko さま

changeRowIndexは私が先のコードで作ったオリジナルの関数なので検索しても出てこないかと思います。
インデックス番号が7ということは、サブテーブルの8行目を変更したということですね。そのようにサブテーブルの何行目を変更したかを求めるための関数がchangeRowIndexです。

サブテーブル(配列)上のフィールドの値にアクセスしたり、値を変更するには、

record['テーブル'].value[/*インデックス番号*/].value[/*サブテーブル上のフィールド*/].value

と記述する必要があります。例としてレコードを開いた状態でコンソールツールから

let record = kintone.app.record.get().record;
console.log('1行目:' + record['テーブル'].value[0].value[/*サブテーブル上のフィールドコード*/].value);
console.log('2行目:' + record['テーブル'].value[1].value[/*サブテーブル上のフィールドコード*/].value);

等を実行すればどういう構造か分かるかと思います。

そして、nekoko さまが本来求めている「テーブルに入力した数値を使用して、テーブル外にて自動計算させている計算フィールドの値を計算後にテーブル内に設置してあるフィールドにコピー」ですが、changeイベントの中で処理を記述すると自動計算が終わっていないので、setTimeoutを使ってchangeイベントが終わってから動作させるようにする必要があり、その場合は上に記述したインデックス番号を指定する方法でサブテーブルの値を書き換える必要があります。

全容は

(() => {
  '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);
  }, 0);

  return event;
});
})();

こんな形になるかと思います(${...}等もただの新しい書き方なので気にしないでください)。

 

ちなみに、私が選択肢①としておすすめした方法(計算フィールドは使用せず、自動計算の計算式と同じ計算をJavaScriptで実行)であれば、event.changes.row(changeイベント内で使える、変更したサブテーブルの行を取得する機能)が使えるので、インデックス番号を求める必要はなく

(() => {
  'use strict';

  let tableNum = ''; // サブテーブル「内」の数値フィールド

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

  row.value[tableNum].value = /* 何らかの計算 */;

  return event;
});
})();

これだけで記述できます。月ごとに計算式が変わるとのことですが、例えば同じ月なら年が違っても同じ計算式(2021年9月の計算式=2022年9月の計算式)であれば月ごとの計算式を宣言し、現在月またはレコードの月を参照して適合する計算式を使用、といったことも可能で、違っても計算式に使用する値をフィールドとして設置しておく、といった方法も取れるかと思います。

mls-hashimotoにより編集されました
1
Avatar
nekoko

mls-hashimoto様

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

 

教えて頂いた関数 changeRowIndex はオリジナルだったのですね。とても便利な関数でしたので既存の関数かと思ってしまいました。

関数、コードの解説ありがとうございます。時間があるときに勉強になるので構造を確認したいと思います。

 

ご提示して頂いた1つ目のコードを読み込んで動作確認をしたのですが計算前の数値が反映されたてしまったのでコードの入力間違えの確認やコンソール等で原因を探していきたいと思います。

また2つ目のコードを応用することで前月の繰越金額を当月に反映させることが出来そうなので(数値フィールドにコピーして設置等)こちらも試してみようと思います。

一つ一つご丁寧にご教授して頂きありがとうございます。

 

 

0
Avatar
mls-hashimoto

nekoko さま

私が設定したsetTimeoutが早すぎるのかもしれません。

}, 0);

この部分の数値を1000辺りにすれば計算後の数値を取れるかもしれません(1=1000分の1秒)。

1
Avatar
nekoko

mls-hashimoto

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

 

教えて頂いた数値に変更したところうまく反映されました。

今後運用していきながら数値を調整していきたいと思います。

 

1から一つずつ丁寧に教えて頂きありがとうございました。

 

1
サインインしてコメントを残してください。