新規投稿
フォローする

関連テーブルの値で計算した値を一括更新ボタンですべてのレコードに反映したい

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

以下のサイトを参考に関連テーブルの値を計算し、フィールドに格納する検討をしております。

1.関連テーブルの集計値を特定のフィールドに返したい

2.後で追加したフィールドに一括で値を反映する方法

このときに以下の通り実装をしたいと考えております。

1.一括更新ボタンを押下した際に一覧のすべてのレコードについて、関連テーブルを再度取得し、計算し、数値フィールドに登録する。

2.一括更新ボタンを実装し一覧のレコードに対し一括で実装する。

1に関しては、実装できたので2を別に実装した際に、集計値が更新されると思いましたがされませんでした。

別途一括更新の際に再計算する必要があるのでしょうか。

1のソース************************************************************************

(function() {
"use strict";

//レコードの追加、編集、詳細画面で適用する

var events = [
'app.record.detail.show',
'app.record.edit.show'
]
kintone.events.on(events, function(event) {
// var client_rid = event.recordId;

// 関連テーブルのAppIdを取得
var related = kintone.app.getRelatedRecordsTargetAppId('仕入れ情報');

// レコード取得関数(100行制限)
function fetchRecords(appId, opt_offset, opt_limit, opt_records) {

var offset = opt_offset || 0;
var limit = opt_limit || 100;

var allRecords = opt_records || [];

// 詳細画面のレコードの情報取得
var record = event.record;
var bukkenNo = record["物件No"].value;

var s_query = '物件No="' + bukkenNo + '" limit ';

var params = {app: related, query: s_query + limit + ' offset ' + offset};

return kintone.api('/k/v1/records', 'GET', params).then(function(resp) {
allRecords = allRecords.concat(resp.records);

if (resp.records.length === limit) {
return fetchRecords(related, offset + limit, limit, allRecords);
}
return allRecords;
});
}


// 小数点n位までを残す関数(切上げ)
// number=対象の数値
// n=残したい小数点以下の桁数
function floatFormat( number, n ) {

var _pow = Math.pow( 10 , n ) ;

return Math.ceil
( number * _pow ) / _pow ;
}

fetchRecords(kintone.app.getId()).then(function(records) {
var amount = 0;
var data_count = 0;
for (var i = 0; i < records.length; i++) {
amount = amount + parseFloat(records[i].税抜き金額.value);
data_count++;
}


//集計値設定()
var appid = kintone.app.getId();
var recid = kintone.app.record.getId();

//売上高取得
var record_2 = event.record;
var sales = record_2["売上高"].value;

// 利益率=(売上高-仕入れ情報「税抜き金額」小計)/売上高 × 100
// 0除算の場合エラーになるため|0で0設定
var interestRate = (sales - amount)/sales*100|0;
interestRate = floatFormat(interestRate,2);
//仕入情報が更新されている場合、再度修正して仕入れ計と利益率更新

//初期登録時、仕入れ計と利益率に初期値登録
if ( ((record_2.仕入れ計.value != amount) || (record_2.利益率.value != interestRate)) ||
((record_2.仕入れ計.value == "") || (record_2.利益率.value == ""))){
var Param = {
"app":appid,
"id":recid,
"record":{
"仕入れ計":{
"value": amount
},
"利益率":{
"value": interestRate
},
},
};

kintone.api("/k/v1/record",
"PUT",Param,
function(resp){
location.reload(true);
// alert("登録成功");
},
function(resp){
// alert("登録エラー");
}
);
};

});

return event;

});
})();

2のソース*********************************************************************

(function () {

"use strict";

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

if (document.getElementById ('my_index_button') != null) {

return;

}

var myIndexButton = document.createElement('button');

myIndexButton.id = 'my_index_button';

myIndexButton.innerHTML = '再計算';

 

// ボタンクリック時の処理

myIndexButton.onclick = function() {

var appId = kintone.app.getId();

kintone.api('/k/v1/records', 'GET', {app: appId}, function(resp) {

//////// 空更新オブジェクトの生成

var param = {

"app": appId,

"records": []

};

for (var i = 0; i < resp['records'].length; i++) {

param['records'][i] = {

"id": resp['records'][i]['物件No']['value'],

"record": {}

}

}

kintone.api(kintone.api.url('/k/v1/records', true), 'PUT', param, function(resp) {

// success

console.log(resp);

}, function(error) {

// error

console.log(param);

console.log(error);

});

});

}

kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);

});

})();

 

0

7件のコメント

Avatar
本田智明

takokichi さん

レコードの更新の際に更新キーとして使用できるフィールドは以下の2種類が存在します。

・レコード番号

・「値の重複を禁止する」にチェックがされた、文字列(1行)または数値フィールド

また、レコード番号を指定する場合とそれ以外のフィールドを指定する場合で、

リクエストパラメータの設定方法が異なります。

参考いただいたページではレコード番号を指定していましたが、載せていただいたソースコードでは

レコード番号以外のフィールドだと想定される”物件No”を指定されているため、

レコード番号以外を指定する場合の書き方で、パラメータを作成する必要がありそうです。

詳しくはdeveloper networkに存在する、kintone REST API レコード更新(PUT)のページを参考に、

コードを修正してみてください。

また、一回のAPI呼び出しで更新できるのは100件までのため、それ以上のレコード数を更新する場合には

もうひと工夫が必要になりそうです。

以上、ご参考までに。

 

0
Avatar
takokichi

本田様

早急に回答頂きありがとうございます。

”物件No”フィールドですが、レコード番号のフィールドでフィールドコードをこちらで変更したものです。

補足が足りず申し訳ありません。

今回の件では現在関連テーブルで再計算している集計値を一括更新で更新できるのか。

この工夫ができず悩んでいる次第です。

100件の件は関連テーブルに関しては、了解済みです。(そこまでデータがないため考慮しません)

一括更新に際しては工夫が必要だとおもっております。

関連テーブルの一括更新が出来次第問題にしようかとおもっておりました。

 

0
Avatar
本田智明

takokichi さん

レコード番号のフィールドコードを変更しておられたのですね!

レコードIDであれば必ず $id で指定が行えるため、レコードIDの使用をオススメします。

 

>今回の件では現在関連テーブルで再計算している集計値を一括更新で更新できるのか。

上記については、可能だと考えています。

ソース1において、レコード単位での関連レコードの集計値を算出する処理はできていると

考えられます。(動作確認はされていると思います)

 

 

ただ、ソース1ではレコード単位でのイベントを検知しているため、

例えば1件のレコードを受け取って集計値を返すように処理を変更し、

ソース2でレコードの一括取得を行っている部分でレコード1件毎にソース1の処理を呼ぶ事で、

一覧画面から各レコードの集計値を取得できると考えられます。

各レコードの集計値を取得後、レコードの一括更新でフィールドに値をセットすれば、

目的の処理が実装できるかと思います。

(直接フィールドに値をセットしているため、空更新でなくページの更新の処理を行えば良いと思います)

 

 

0
Avatar
takokichi

本田様

コメントありがとうございます。

 

以下のソースで関連レコードで取得したレコード(siireRec)を使用し、

アプリのレコードに(respdata)値を設定し、更新しようと試みました。

がアプリのレコードが引き継げずに苦戦しております。

引き継ぐ方法(JSの知識になるかもしれませんが。。。)はございますでしょうか。


fetchRecords(respdata['records'][i]).then(function(siireRec) {

var amount = 0;
var data_count = 0;
for (var i = 0; i < siireRec.length; i++) {
amount = amount + parseFloat(siireRec[i].税抜き金額.value);
data_count++;
}

var sales = respdata['records'][i]['売上高']['value'];

// 利益率=(売上高-仕入れ情報「税抜き金額」小計)/売上高 × 100
// 0除算の場合エラーになるため|0で0設定
var interestRate = (sales - amount)/sales*100|0;
interestRate = floatFormat(interestRate,2);


//オブジェクトに値をセット
param['records'][i] = {

"id": respdata['records'][i]['物件No']['value'],

"record":{
"仕入れ計":{
"value": amount
},
"利益率":{
"value": interestRate
},
},

}
}
);

0
Avatar
本田智明

takokichi さん

1行目のrespdata['records'][i]を、then以降のfunctionにて使いたい、とのご要望だと思います。

1行目のfetchRecords()を呼んでいる処理があると思いますが、fetchRecords()を呼ぶ前に、

適当な変数に対してrespdata['records'][i]をセットし、then以降のfunctionでその変数を

呼び出す事で、レコードが引き継げると思います。

以下のようなコードのイメージです。

// レコードのバックアップ用変数
var recordBackup = '';
function func1() {
for (var i = 0; i < respdata['records'].length; i++) {
recordBackup = respdata['records'][i];
fetchRecords(respdata['records'][i]).then(function(siireRec) {
// respdata['records'][i]の代わりにrecordBackupを使う
});
}
}

 

本田智明により編集されました
1
Avatar
takokichi

本田智明様

ご丁寧にソースまで記載していただきありがとうございました。

 

無事実装できました。

またご指定いただいたとおり、100件以上の更新となるため、GETの部分に関してはこちらを参考に同期処理に書き換えました。

PUTに関してはid指定のため同期処理のままにしております。

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

 

 

1
Avatar
本田智明

takokichi さん

動作したようで良かったです!

0
ログインしてコメントを残してください。