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

見積書を目的に、テーブル自動計算で、下記のjavaを利用しアプリを活用しています。

問題なく動作をしているのですが、単価(sales)に1,000,000を超えた数値が入力された場合、下記フィールド以外のフィールド個所を打ち直したり消したりすると表記がおかしくなります。(以下、編集といいます。)

例)入力値”1000000”と数値のみを入力

1度目の編集では”1,000,000”となり

2度目の編集では”1,000”となり

これ以降の編集では変化がありません。

数値が変わると問題がありますので何か対策をしたいのですが

方法があるのでしょうか?

ご教授のほどよろしくお願いいたします。

 

/**
* テーブル:Table
* 単価:price(文字列フィールド)
* 個数:num(数値フィールド)
* 小計:sales(文字列フィールド)
*
* 総計:total(数値フィールド)
*/

(function () {
“use strict”;
function loadJS(src) {
document.write(‘<script type=“text/javascript” src="’ + src + ‘"></script>’);
}
// jQuery の JavaScript ファイル
loadJS(“https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js”);

// 数値→桁区切り
var numberFormat = function (num) {
if (typeof num === ‘number’) {
return num.toString().replace(/^\d+[^.]/, function (t) {
return t.replace(/([\d]+?)(?=(?:\d{3})+$)/g, function (t) {
return t + ‘,’;
});
});
} else {
return num;
}
}

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

/**
* 計算処理
*/
var myCalculate = function (record) {
var table = record.Table.value;
var total = 0;
for (var i = 0, l = table.length; i < l; i++) {
var row = table[i].value; // テーブルの1行
// 小計を計算
var price = number(row.price.value);
var num = row.num.value;
if (price && num) {
var sales = price * num;
row.sales.value = numberFormat(sales);
total += sales;
} else {
// priceかnumが空の場合はnull
row.sales.value = null;
}
row.price.value = numberFormat(price);
}
record.total.value = total;
};

// イベント
kintone.events.on([“app.record.edit.show”, “app.record.create.show”], function (event) {
// 編集時に計算するイベント
$(document.body).on(‘change’, “input[type=‘text’]”, function () {
var record = kintone.app.record.get();
myCalculate(record.record);
kintone.app.record.set(record);
});

// 無理やりDOM操作で編集不可に
$(document).on(‘click’, ‘.add-row-image-gaia’, function () {
var ele = $(‘.value-139700’).children(); // 小計のclass
ele.addClass(‘disabled-cybozu’);
ele.children(‘input’).attr(‘disabled’, ‘disabled’);
});

// 無理やりDOM操作で行削除イベント
$(document).on(‘click’, ‘.remove-row-image-gaia’, function () {
var record = kintone.app.record.get();
myCalculate(record.record);
kintone.app.record.set(record);
});

return event;
});

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

return event;
});

// 登録、編集時の処理
kintone.events.on([“app.record.edit.submit”, “app.record.create.submit”], function (event) {
myCalculate(event.record);

return event;
});

})();

青山さん

計算・書式のために、桁区切りをつけたり取ったりしてわかりにくくなっており、問題もあるようです。
またkintone API があまり充実していなかった頃に、作成されたスクリプトだと思われます。
この機会に作り直しては、いかがでしょうか?

・jQuery によるイベント処理を廃止して、フィールド値変更時イベント、を使う。
テーブルを指定すると、行追加・削除のイベントも拾えます。
“app.record.create.change.Table”, “app.record.edit.change.Table”,
・単価:price、小計:sales を数値フィールドに変更し、「桁区切りを表示する」を設定

rex0220さん

 

ご返信ありがとうございます。

プリントクリエイターを使用して帳票印刷しています。

テーブルを追加時に自動計算を行う際にフィールドへ”0値”を入力しないと

計算せず0値を入れると今度は見積書自体が0だらけになる場合があり

この様な形で運用しておりました。

前回問合せ時のURL↓

https://cybozudev.zendesk.com/hc/ja/community/posts/206081586-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89-%E6%95%B0%E5%80%A4-%E8%A8%88%E7%AE%97-%E3%81%AE%E5%80%A4%E3%81%8C-0-%E3%81%AE%E5%A0%B4%E5%90%88

 

この様なことも可能でしょうか?

 

プリントクリエーターは、使ったことがありませんが、仕様を見ると数値の桁区切り機能もあるようです。
ただ厄介なことに数値が null の場合の表示が 0 表示になるようですね。
整理すると下記コードで行けそうな気がします。ただし切り貼りしただけですので検証をお願いします。

(function () {
"use strict";

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

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

// 小計、総計の計算
var events2 = [
"app.record.edit.show", "app.record.create.show",
"app.record.create.change.Table", "app.record.edit.change.Table",
"app.record.create.change.price", "app.record.edit.change.price",
"app.record.create.change.num", "app.record.edit.change.num"
];
kintone.events.on(events2, function (event) {
var table = record.Table.value;
var total = 0;
for (var i = 0, l = table.length; i < l; i++) {
var row = table[i].value; // テーブルの1行
// 小計を計算
if (row.price.value && row.num.value) {
var sales = number(row.price.value) * number(row.num.value);
row.sales.value = sales.toLocaleString();
total += sales;
} else {
// priceかnumが空の場合はnull
row.sales.value = null;
}
row.price.value = row.price.value ? number(row.price.value).toLocaleString() : '';
}
record.total.value = total;
return event;
};

})();

肝心の問題点がわかりました。

区切りを削除する処理が、1文字しか削除していません。
ここだけ直しても、問題は解消されると思います。

誤り
numberFormatStr.replace(‘,’, ‘’)


numberFormatStr.replace(/,/g, ‘’)

 

 

rex0220さん

 

ご返信ありがとうございます。

>ここだけ直しても、問題は解消されると思います。

これで解決しました。ありがとうございます。

>区切りを削除する処理が1文字、誤りが「(‘,’, ‘’)」正が「(/,/g, ‘’)」

とあるのですが、この違いをどう理解したらいいかわかりません。

何か参考になるサイトか、違いをご教授頂ければ幸いです。

 

 

 

numberFormatStr.replace(‘,’, ‘’) は、最初の’,‘の1文字だけ’’に置換します。(結果的に1文字削除)
numberFormatStr.replace(/,/g, ‘’) は、’,'の文字すべてを置換します。

/,/g は、正規表現というもので、g を指定すると指定した文字列パターン/,/にマッチングする文字列がすべて対象になります。
正規表現については、下記が基本です。

正規表現 https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

他に検索するといろいろありますのでいくつかわかりやすいものを探してみてください。
最初は、正規表現 入門などで勉強するといいかもしれません。
正規表現は、覚えると便利ですよ。

Alex2013さん

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

まだまだ勉強不足なので少しですが理解できたように思います。

ありがとうございました。

一度勉強してみます。

また不明なことがありましたらご教授頂ければと思います。