複数のサブテーブルごとjavascriptで計算したい

いつもお世話になっております。色々調べたり模索してみましたがどうにも動きません。

javascript初心者のため、基本的なところが誤っているのかもしれません。

ご教授いただけますと大変ありがたいです。

【参考URL】

テーブルのjavaを利用した自動計算について

計算時の”0入れなきゃいけない問題

 

見積書を作成するアプリを作っています。

初期費用と月額費用のサブテーブルが独立して存在しているため、テーブル1、テーブル2と複数のサブテーブルが存在しています。

また、別のテーブル3に1、2の統計が反映されるようにしたいです。

初期・月額の片方のサブテーブルが空欄になる場合があるため、計算エラーを回避すべく、javascriptで計算をしたいと思っています。

 

【項目】

初期費用テーブル:Table_1

初期費用 単価:price_1

初期費用 数量:num_1

初期費用 小計(フィールド名:初期費用):sales_1

月額費用テーブル:Table_2

月額費用 単価:price_2

月額費用 数量:num_2

月額費用 小計(フィールド名:月額費用):sales_2

合計金額テーブル:Table_3

初期費用 統計(フィールド名:初期費用小計):total_1

月額費用 統計(フィールド名:月額費用小計):total_2

※小計の部分が紛らわしくてすみません。

=======================

(function () {
“use strict”;

// 桁区切り→数値
var number = function (numberFormatStr) {
if (typeof numberFormatStr === ‘string’) {
return parseInt(numberFormatStr.replace(/,/g, ‘’), 10);
} else {
return numberFormatStr;
}
}

// 計算する数値フィールドを編集不可にする
var events1 = [
“app.record.create.show”, “app.record.edit.show”,
“app.record.create.change.Table_1”, “app.record.edit.change.Table_1”,
“app.record.create.change.Table_2”, “app.record.edit.change.Table_2”,
];
kintone.events.on(events1, function (event) {
var table_1 = event.record.Table_1.value;
for (var i = 0, l = table_1.length; i < l; i++) {
table_1[i].value.sales_1.disabled = true;
}
event.record.total_1.disabled = true;
return event;
});

kintone.events.on(events1, function (event) {
var table_2 = event.record.Table_2.value;
for (var i = 0, l = table_2.length; i < l; i++) {
table_2[i].value.sales_2.disabled = true;
}
event.record.total_2.disabled = true;
return event;
});

// 小計、総計の計算
var events2 = [
“app.record.edit.show”, “app.record.create.show”,
“app.record.create.change.Table_1”, “app.record.edit.change.Table_1”,
“app.record.create.change.price_1”, “app.record.edit.change.price_1”,
“app.record.create.change.num_1”, “app.record.edit.change.num_1”,
“app.record.create.change.sales_1”, “app.record.edit.change.sales_1”,
“app.record.create.change.total_1”, “app.record.edit.change.total_1”,
“app.record.create.change.Table_2”, “app.record.edit.change.Table_2”,
“app.record.create.change.price_2”, “app.record.edit.change.price_2”,
“app.record.create.change.num_2”, “app.record.edit.change.num_2”,
“app.record.create.change.sales_2”, “app.record.edit.change.sales_2”,
“app.record.create.change.total_2”, “app.record.edit.change.total_2”,
];
//テーブル1を計算する
kintone.events.on(events2, function (event) {
var table_1 = record.Table_1.value;
var total_1 = 0;

for (var i = 0, l = table_1.length; i < l; i++) {
var row_1 = table_1[i].value; // テーブルの1行
// 小計を計算
if (row_1.price_1.value && row_1.num_1.value) {
var sales_1 = number(row_1.price_1.value) * number(row_1.num_1.value);
row_1.sales_1.value = sales_1.toLocaleString();
total_1 += sales_1;
} else {
// priceかnumが空の場合はnull
row_1.sales_1.value = null;
}
row_1.price_1.value = row_1.price_1.value ? number(row_1.price_1.value).toLocaleString() : ‘’;
}
record.total_1.value = total_1;
return event;
});

//テーブル2を計算する
kintone.events.on(events2, function (event) {
var table_2 = record.Table_2.value;
var total_2 = 0;

for (var i = 0, l = table_2.length; i < l; i++) {
var row_2 = table_2[i].value; // テーブルの1行
// 小計を計算
if (row_2.price_2.value && row_2.num_2.value) {
var sales_2 = number(row_2.price_2.value) * number(row_2.num_2.value);
row_2.sales_2.value = sales_2.toLocaleString();
total_2 += sales_2;
} else {
// priceかnumが空の場合はnull
row_2.sales_2.value = null;
}
row_2.price_2.value = row_2.price_2.value ? number(row_2.price_2.value).toLocaleString() : ‘’;
}
record.total_2.value = total_2;
return event;
});
})();

 

以上です。よろしくお願いします。

佐野さん

こんにちは。ひよこです。

テーブルのカスタマイズはkintone カスタマイズのなかでも難しいと思っているのですが、しっかりかけていてすごいです!!
動かないとのことでしたが、動かない原因は大きく2点あります

①ブラウザの開発者ツールで、テーブル1を計算する部分とテーブル2を計算する部分で、record がないというエラーが出ています。
なので、record の定義が必要です。

//テーブル1を計算する
kintone.events.on(events2, function (event) {
var record = event.record; // これが必要
var table_1 = record.Table_1.value;

// テーブル2を計算する部分についても、同じようにrecord を定義してください。

②小計は数値フィールドだと思うのですが、ここに文字列をセットしているので、エラーになります。

・初期費用と月額費用の小計を計算している部分やprice や num が空のときは、number 関数を通さずに parseInt する
・数値フィールドにセットするところは文字列にしない

var sales_1 = number(row_1.price_1.value) * number(row_1.num_1.value);
row_1.sales_1.value = sales_1.toLocaleString();

row_1.price_1.value = row_1.price_1.value ? number(row_1.price_1.value).toLocaleString() : '';

ではなく

var sales_1 = parseInt(row_1.price_1.value, 10) * parseInt(row_1.num_1.value, 10);
record.total_1.value = total_1;

row_1.price_1.value = row_1.price_1.value ? parseInt(row_1.price_1.value,10) : '';

です。
月額小計(Table2)についても同じように修正してみてください。

桁区切りで表示する場合は、アプリのフォーム設定で桁区切り表示したほうがいいと思います。

ひよこ様

大変ご丁寧なコード記載とご説明をいただき、ありがとうございます!!

お褒めの言葉をいただき恐縮です。0ベースから手さぐり状態で向き合っており、勉強をさせていただく所存です。

 

さっそく以下のように修正をしてみました。

//テーブル1を計算する
kintone.events.on(events2, function (event) {
var record = event.record; //recordを定義
var table_1 = record.Table_1.value;
var total_1 = 0;

for (var i = 0, l = table_1.length; i < l; i++) {
var row_1 = table_1[i].value; // テーブルの1行
// 小計を計算
if (row_1.price_1.value && row_1.num_1.value) {
// 初期費用と月額費用の小計を計算している部分やprice や num が空のときは
// number 関数を通さずに parseInt する
var sales_1 = parseInt(row_1.price_1.value, 10) * parseInt(row_1.num_1.value, 10);
record.total_1.value = total_1;
total_1 += sales_1;
} else {
// priceかnumが空の場合はnull
row_1.sales_1.value = null;
}
row_1.price_1.value = row_1.price_1.value ? parseInt(row_1.price_1.value,10) : '';
}
record.total_1.value = total_1;
return event;
});

//テーブル2を計算する
kintone.events.on(events2, function (event) {
var record = event.record; //recordを定義
var table_2 = record.Table_2.value;
var total_2 = 0;

for (var i = 0, l = table_2.length; i < l; i++) {
var row_2 = table_2[i].value; // テーブルの1行
// 小計を計算
if (row_2.price_2.value && row_2.num_2.value) {
var sales_2 = parseInt(row_2.price_2.value, 10) * parseInt(row_2.num_2.value, 10);
record.total_2.value = total_2;
total_2 += sales_2;
} else {
// priceかnumが空の場合はnull
row_2.sales_2.value = null;
}
row_2.price_2.value = row_2.price_2.value ? parseInt(row_2.price_2.value,10) : '';
}
record.total_2.value = total_2;
return event;
});

ですが、やはりうごきません。。

私が間違って解釈をしてしまっているのでしょうか。

 

また、編集不可にもならず、入力もできてしまいます。

根本的に間違っているのでしょうか…初歩的な質問で申し訳ありません。

もしお気づきの点があればご指摘いただけますとありがたいです。

// 計算する数値フィールドを編集不可にする
var events1 = [
"app.record.create.show", "app.record.edit.show",
"app.record.create.change.Table_1", "app.record.edit.change.Table_1",
"app.record.create.change.Table_2", "app.record.edit.change.Table_2",
];

kintone.events.on(events1, function (event) {
var table_1 = event.record.Table_1.value;
for (var i = 0, l = table_1.length; i < l; i++) {
table_1[i].value.sales_1.disabled = true;
}
event.record.total_1.disabled = true;
return event;
});

kintone.events.on(events1, function (event) {
var table_2 = event.record.Table_2.value;
for (var i = 0, l = table_2.length; i < l; i++) {
table_2[i].value.sales_2.disabled = true;
}
event.record.total_2.disabled = true;
return event;
});

色々と大変わかりやすいご説明をいただきありがとうございます。

よろしくお願いいたします。

佐野さん

こんにちは。ひよこです。

パット見た感じは特に問題なさそうに見えます…。

ブラウザの開発者ツールを開いて、なにかメッセージは出ていますか?
あと、問題ないとは思うのですが、もういちど「アプリを更新」をしてみてください。

 

 

ひよこ様

 

こんにちは、お返事がだいぶ遅くなってしまい大変申し訳ございません。

お気にかけてくださり、ありがとうございます!!

アプリ更新はされていて灰色の状態です!

 

F12でみてみますと以下のようなエラーがでていました。

show.js:1084 Uncaught TypeError: Cannot set property 'disabled' of undefined
at download.do?app=3&contentId=1544&jsType=DESKTOP&hash=e54700808216386dd81f10e3b7a41153307e41d6:24
at show.js:253
at Array.forEach (<anonymous>)
at u (show.js:1026)
at Sw (show.js:253)
at Tw (show.js:253)
at IH (show.js:409)
at $3.<anonymous> (show.js:903)
at ck (show.js:125)
at dk (show.js:124)

disabledを定義しないといけないということなのでしょうか…?

参考にしたコードでは特に定義していなかったので、関数かなにかだと思っておりました。

もし思い当たることありましたらお伝えいただけますと幸いです。

【編集不可設定コード 追記】

テーブル違いのフィールドがまざってしまっていたので

(totalはTable_3のフィールド)それが原因かと思い書き直したら、disabledのエラーではなく

Cannot read property ‘value’ of undefinedというエラーになりました。

【コード変更後】

// 計算する数値フィールドを編集不可にする
var events1 = [
"app.record.create.show", "app.record.edit.show",
"app.record.create.change.Table_1", "app.record.edit.change.Table_1",
"app.record.create.change.Table_2", "app.record.edit.change.Table_2",
"app.record.create.change.Table_3", "app.record.edit.change.Table_3",
];

kintone.events.on(events1, function (event) {
var table_1 = event.record.Table_1.value;
for (var i = 0, l = table_1.length; i < l; i++) {
table_1[i].value.sales_1.disabled = true;
}
return event;
});

kintone.events.on(events1, function (event) {
var table_2 = event.record.Table_2.value;
for (var i = 0, l = table_2.length; i < l; i++) {
table_2[i].value.sales_2.disabled = true;
}
return event;
});

kintone.events.on(events1, function (event) {
var table_3 = event.record.Table_3.value;
for (var i = 0, l = table_3.length; i < l; i++) {
table_3[i].value.total_1.disabled = true;
table_3[i].value.total_2.disabled = true;
}
return event;
});

他にも原因を探ってみます。ありがとうございます。

佐野さん

こんにちは。

value が存在しないと言われるときは、だいたいそのフィールドの情報を取得できてないので、フィールドコードが間違っている事が多いです。
テーブルや各フィールドのフィールドコードが、プログラムと合っているか確認してみてください(後ろにスペースが入っていないかなど)!

ひよこ様

お返事が大変遅くなってしまい、大変申し訳ございません。

色々試行錯誤したのですが結局動かずじまいでした…。

ご尽力いただきましたのに本当に申し訳ないのですが

プログラムで計算はあきらめて、別の方法にて動かすことにしました。

 

印刷時に表示されなければいいので、単価等の初期値に「0」をいれておき、計算は既存の計算式を使い

プリントイベントの時にテーブル内の項目に「0」があったら非表示にする

という形にしました。

kintone.events.on('app.record.print.show', function(event) {

//初期費用または月額費用に「0」があった場合テーブルごと非表示にする

var record = event.record; //recordを定義

var table_1 = record['初期費用'].value;
var table_2 = record['月額費用'].value;
var row_1 = table_1[0].value;//初期費用テーブルの1行目
var row_2 = table_2[0].value;//月額費用テーブルの1行目

//初期費用の単価が0(初期値)のとき非表示
if (row_1.price_1.value == "0") {
kintone.app.record.setFieldShown('初期費用明細', false);
kintone.app.record.setFieldShown('初期費用', false);

//月額費用の単価が0(初期値)のとき非表示
} else if (row_2.price_2.value == "0") {
kintone.app.record.setFieldShown('月額費用明細', false);
kintone.app.record.setFieldShown('月額費用', false);

} else {
//何もしない
}

でもとても悔しいので、また時間をみつけて検証は重ねていきたいと思います!

重ね重ねありがとうございました!

 

また問題点がみつかりましたらまた相談にのっていただけると嬉しいです!

よろしくお願いします。