一覧画面に計算ボタンを作成して、ボタンをクリックすると、条件に合った計算をしてそのデータを同じアプリ内に登録する処理を実現させたいと思っています。
納品日 仕入先コード 納品先コード 納品金額 ・・・・・
上記のようなフィールドがあり、仕入れ先コードや納品先コードは複数あります。実現したいのは、納品日が当月の仕入先コードと納品先コードが同じものの納品金額を合計して、その合計の○○%の値を納品金額のフィールドに登録したいのです。
こういったことは実現可能でしょうか?
一覧画面に計算ボタンを作成して、ボタンをクリックすると、条件に合った計算をしてそのデータを同じアプリ内に登録する処理を実現させたいと思っています。
納品日 仕入先コード 納品先コード 納品金額 ・・・・・
上記のようなフィールドがあり、仕入れ先コードや納品先コードは複数あります。実現したいのは、納品日が当月の仕入先コードと納品先コードが同じものの納品金額を合計して、その合計の○○%の値を納品金額のフィールドに登録したいのです。
こういったことは実現可能でしょうか?
garden さん
対象レコードを取得して、集計・納品金額の登録は、JavaScript カスタマイズで可能です。
ただし、どちらかというと、業務分析と業務フローの検討が重要です。
当月といっても、対象データが月内にすべて揃っているのかどうか?
揃っていない場合は、月の締め日を決めて、運用することになると思います。
また、締め処理以降に入力漏れが判明した場合の運用はどうするのか?
仕入れ・納品の返品・キャンセルの扱いや単純な入力ミス対応など
現在、マニュアルで集計されているのであれば他にも、細かい要件がいろいろ出てくると思います。
それらに対する業務フローと、システム対応の範囲などの検討が必要だと思います。
納品金額がどう使われるのかにもよりますが、納品金額の集計・登録時のシステムトラブル時の影響と
リカバリー方法なども検討しておいたほうが良いと思います。
ご回答ありがとうございます。rex0220様のおっしゃる通り、業務フローをしっかり決める必要があると思います。
そこまで考えていただいてご回答いただきありがとうございます。そのあたりの事はしっかり決めるとして、今回
のようなことを実現するにあたって、どのようなJavaScriptを記述したらいいでしょうか。
一番わからないのが、複数の仕入先コードと納品先コードがある中で、仕入れ先コードと納品先コードが同じもの
の納品金額の合計を出す部分です。もしよろしければ、簡単でいいのでどのようにしたらいいかを教えていただければ
幸いです。
kintone の集計方法については、「kintone カスタマイズ関連リンク集 集計処理」にまとめています。
この中で、キーが複数で集計しやすいのは、下記の二つだと思います。
仕入先コードと納品先コードをキーに納品金額を集計するのは、それぞれ下記のようなコードになります。
var summary = recordsSummary(records,['仕入先コード','納品先コード'],['納品金額']);
var rs1 = convertToRows(records);
var result1 = alasql(
"SELECT a.[仕入先コード], a.[納品先コード], SUM(a.[納品金額]) as [納品金額] \
FROM ? AS a \
GROUP BY a.[仕入先コード], a.[納品先コード]", [rs1]);
どちらも、関数の部分はリンク先のものがそのまま使えますので、詳細はリンク先を見てください。
alasql のほうは、一般的なSQLと同じように書けますので、汎用的です。
回答していただき本当にありがとうございます。頂いた情報をもとに、とりあえず納品金額の合計を表示してみようかなと
試してみたのですが、うまくいきませんでした。まったくの初心者で手さぐりでやっているもので、まったく見当違いなことを
しているのかもしれません。以下のように書いてみたのですが、どこをどうしたらいいのか、できれば教えて頂ければ
幸いです。
(function() {
“use strict”;
kintone.events.on(‘app.record.index.show’, function(event) {
// メニュ右側の空白部分にボタンを設置
var MenuButton = document.createElement(‘button’);
MenuButton.id = ‘Menu_Button’;
MenuButton.innerHTML = ‘ボタン’;
MenuButton.onclick = function () {
var query= kintone.app.getQuery();
kintone.api(
kintone.api.url(‘/k/v1/records’, true),
‘GET’, {
app: 42,
query: query
},
function(resp) {
var summary1 = recordsSummary(resp.records,[‘仕入先コード’,‘納品先’],[‘納品金額’]);
window.alert(summary1);
function recordsSummary(records, keys, sumKeys) {
var sumKeys2 = sumKeys.concat([‘$count’]);
var hash = records.reduce(function(res,record) {
// 集計キーを作成
var key = keys.reduce(function(s,k) {
if(s) s += ‘\t’;
s += record[k][‘value’];
return s;
},‘’);
// 初めての集計キー
if(!(key in res)) {
// 集計キーをオブジェクトに設定
var keyList = keys.reduce(function(h,k) {
h[k] = record[k][‘value’];
return h;
},{});
// 集計項目の初期値を設定
res[key] = sumKeys2.reduce(function(h,k) {
h[k] = 0;
return h;
}, keyList);
}
// データを集計(加算)
sumKeys.forEach(function(k){
if(record[k][‘value’])
res[key][k] += Number(record[k][‘value’]);
});
res[key][‘$count’]++;
return res;
},{});
// キーソート
var hashKeys = Object.keys(hash);
hashKeys.sort();
// 配列化
var summary = [];
for(var i in hashKeys){
var k = hashKeys[i];
if(hash.hasOwnProperty(k)){
summary.push(hash[k]);
}
}
return summary;
}
});
}
kintone.app.getHeaderMenuSpaceElement().appendChild(MenuButton);
});
})();
appId を自アプリ、 alert をconsole.table に変更して、試したところ問題なく集計されました。
たぶん、フィールドコードが合っていないとか、単純なミスがあるような気がします。
kintone.api(
kintone.api.url('/k/v1/records', true),
'GET', {
app: event.appId,
query: query
},
function(resp) {
var summary1 = recordsSummary(resp.records, ['仕入先コード', '納品先'], ['納品金額']);
console.table(summary1);
テスト結果
rex0220様
ご返信が遅くなってしまい、申し訳ございません。私もconsole.table に変更して、rex様のように集計されました。
ありがとうございます。そこでまた質問になってしまうのですが、各仕入先コード、納品先別の納品金額に0.8をかけた
金額を、納品金額のとろこに新しいデータとして登録をしたいのですが、どのようコードを書いたらいいのかを
できたら教えて頂きたいです。
アプリの構成が分かりませんので、分かる部分だけで、record を組み立てると下記のようになります。
あとは、レコードの一括登録 の手順で登録は出来ます。
他に、いろいろ細かな要件があると思いますので、これをベースに検討してください。
var summary1 = recordsSummary(resp.records, ['仕入先コード', '納品先'], ['納品金額']);
console.table(summary1);
var records = summary1.map(function(data) {
return {
'仕入先コード': { value: data['仕入先コード'] },
'納品先': { value: data['納品先'] },
'納品金額': { value: parseInt(data['納品金額'] * 0.8) }
}
});
console.log('records:', records);
rex0220様
いつも本当にありがとうございます。頂いたコードをもとに試してみました。
レコードの一括登録のところでエラーになってしまうのですが、どのあたりが問題でしょうか。
いつも質問ばかりで申し訳ありません。お手すきの時にでも教えて頂けますでしょうか。
(function() {
“use strict”;
moment.locale(‘ja’);
kintone.events.on(‘app.record.index.show’, function(event) {
var MenuButton = document.createElement(‘button’);
MenuButton.id = ‘Menu_Button’;
MenuButton.innerHTML = ‘ボタン’;
kintone.app.getHeaderMenuSpaceElement().appendChild(MenuButton);
MenuButton.onclick = function () {
var query= kintone.app.getQuery();
var appId = kintone.app.getId();
kintone.api(
kintone.api.url(‘/k/v1/records’, true),
‘GET’, {
app: appId,
query: query
},
function(resp) {
var summary1 = recordsSummary(resp.records,[‘仕入先コード’,‘納品先’],[‘納品金額’]);
console.table(summary1);
var d1 = moment();
var records = summary1.map(function(data) {
return {
‘仕入先コード’: { value: data[‘仕入先コード’] },
‘納品日’: { value: moment(d1).endOf(‘month’).format(‘YYYY-MM-DD’) },
‘発注番号’: { value: data[‘仕入先コード’] + moment(d1).endOf(‘month’).format(‘MMDD’) },
‘納品数’: { value: ‘-1’ },
‘単価’: { value: parseInt(data[‘納品金額’] * 0.08) },
‘納品金額’: { value: ‘-’ + parseInt(data[‘納品金額’] * 0.08) },
};
});
console.log(‘records:’, records);
kintone.api(kintone.api.url(“/k/v1/records”, true), ‘POST’, {“app” : 42, “record” : records }, function(res){
// 成功時の処理
console.log(“success”);
} ,function(err){
// 失敗時の処理
console.log(“error”);
}
);
});
function recordsSummary(records, keys, sumKeys) {
var sumKeys2 = sumKeys.concat([‘$count’]);
var hash = records.reduce(function(res,record) {
// 集計キーを作成
var key = keys.reduce(function(s,k) {
if(s) s += ‘\t’;
s += record[k][‘value’];
return s;
},‘’);
// 初めての集計キー
if(!(key in res)) {
// 集計キーをオブジェクトに設定
var keyList = keys.reduce(function(h,k) {
h[k] = record[k][‘value’];
return h;
},{});
// 集計項目の初期値を設定
res[key] = sumKeys2.reduce(function(h,k) {
h[k] = 0;
return h;
}, keyList);
}
// データを集計(加算)
sumKeys.forEach(function(k){
if(record[k][‘value’])
res[key][k] += Number(record[k][‘value’]);
});
res[key][‘$count’]++;
return res;
},{});
// キーソート
var hashKeys = Object.keys(hash);
hashKeys.sort();
// 配列化
var summary = [];
for(var i in hashKeys){
var k = hashKeys[i];
if(hash.hasOwnProperty(k)){
summary.push(hash[k]);
}
}
return summary;
}
};
});
})();
どのようなエラーが出ていますか?
ざっと見たところ、“record” が誤っていると思います。
⇒ “records”
{“app” : 42, “record” : records }
ご返信ありがとうございます。"records"に直してみましたが、登録されませんでした。
コンソールのログを見ると、データの内容は正常に表示されているのですが、
一括登録の処理のところで、”error”と表示されデータの登録ができない状態です。
私のソースのどこかがおかしいのだとは思うのですが、ほかに何か原因は考えられますでしょうか?
console.log(“error”, err); にして、エラー内容を確認しましょう。
ありがとうございます。すでに登録してあるデータで、おかしいものがあったので削除して試したところ
正常に登録できました。一人ではどうしていいか困っていたので、教えて頂き本当にありがとうございます。
あと最後に一つだけ教えて頂きたいことがあります。できればこの処理を実行する際に条件をつけたいです。
仕入先コードが複数ある中で、例えば「A01」と「A02」が含まれるデータだけに、今回の処理を適用して
データの登録を行いたいと思うのですが、その条件はどのように記載したらよろしいでしょうか?
レコードの一括取得(クエリで条件を指定) を参考にしてください。 in が使えると思います。
あと、作成されたコードだと、100 件のレコードしか処理しないなど問題がありますので、本番用開発はその辺も考慮してください。
kintone Utility for JavaScript を使ってみたよ を使うと容易だと思います。
本当にいろいろとありがとうございます。kintone Utility for JavaScript を使ってみたよ こちらを参考にして、データの登録ができました。
ただ、クエリの指定がうまくいきません。kintone.app.getQuery();に、プラスして仕入先コードの条件を入れたいのですが、そのような
ことはできますでしょうか?
kintone.app.getQueryCondition() こちらを使ってみてください。
limit, offset の指定がありません。
いつもありがとうございます。
var query= kintone.app.getQueryCondition() + “and” + ‘仕入先コード in (“752”,“140”)’;
のような形で記載してみたのですが、うまくいきませんでした。おそらく記載方法がちがうのだと
思うのですが、よろしければ教えて頂けますでしょうか。
連結時にスペースが必要です。
結果を、console.log(query); で、検証しましょう。