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

**URL:** <https://community.cybozu.dev/t/topic/742>\
**Category:** kintone 開発相談\
**Created:** [2017 年 6 月 7 日午前 7:36 UTC](https://community.cybozu.dev/t/topic/742 "2017-06-07T07:36:40Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Legacy\_Account1607](https://avatars.discourse-cdn.com/v4/letter/l/eada6e/32.png) [@Legacy\_Account1607](https://community.cybozu.dev/u/Legacy_Account1607)\
**Post date:** [2017 年 6 月 7 日午前 7:36 UTC](https://community.cybozu.dev/t/topic/742/1 "2017-06-07T07:36:40Z")

</div>

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

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

１．[関連テーブルの集計値を特定のフィールドに返したい](https://community.cybozu.dev/hc/ja/community/posts/115000000846-%E9%96%A2%E9%80%A3%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E9%9B%86%E8%A8%88%E5%80%A4%E3%82%92%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AB%E8%BF%94%E3%81%97%E3%81%9F%E3%81%84)

２．[後で追加したフィールドに一括で値を反映する方法](https://community.cybozu.dev/hc/ja/articles/201883830-%E5%BE%8C%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%9F%E8%A8%88%E7%AE%97%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AB%E4%B8%80%E6%8B%AC%E3%81%A7%E5%80%A4%E3%82%92%E5%8F%8D%E6%98%A0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

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

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

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

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

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

１のソース\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

(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 = ‘再計算’;

&nbsp;

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

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);

});

})();

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1479](https://avatars.discourse-cdn.com/v4/letter/l/e480ec/32.png) [@Legacy\_Account1479](https://community.cybozu.dev/u/Legacy_Account1479)\
**Post date:** [2017 年 6 月 8 日午前 1:58 UTC](https://community.cybozu.dev/t/topic/742/2 "2017-06-08T01:58:42Z")

</div>

takokichi さん

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

・レコード番号

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

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

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

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

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

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

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

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

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

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

以上、ご参考までに。

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1607](https://avatars.discourse-cdn.com/v4/letter/l/eada6e/32.png) [@Legacy\_Account1607](https://community.cybozu.dev/u/Legacy_Account1607)\
**Post date:** [2017 年 6 月 8 日午前 4:44 UTC](https://community.cybozu.dev/t/topic/742/3 "2017-06-08T04:44:50Z")

</div>

**本田様**

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

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

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

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

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

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

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

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

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1479](https://avatars.discourse-cdn.com/v4/letter/l/e480ec/32.png) [@Legacy\_Account1479](https://community.cybozu.dev/u/Legacy_Account1479)\
**Post date:** [2017 年 6 月 8 日午前 7:52 UTC](https://community.cybozu.dev/t/topic/742/4 "2017-06-08T07:52:11Z")

</div>

takokichi さん

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

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

&nbsp;

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

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

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

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

&nbsp;

&nbsp;

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

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

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

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

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

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

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

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1607](https://avatars.discourse-cdn.com/v4/letter/l/eada6e/32.png) [@Legacy\_Account1607](https://community.cybozu.dev/u/Legacy_Account1607)\
**Post date:** [2017 年 6 月 16 日午前 9:41 UTC](https://community.cybozu.dev/t/topic/742/5 "2017-06-16T09:41:09Z")

</div>

本田様

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

&nbsp;

以下のソースで関連レコードで取得したレコード（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  
},  
},

}  
}  
);

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1479](https://avatars.discourse-cdn.com/v4/letter/l/e480ec/32.png) [@Legacy\_Account1479](https://community.cybozu.dev/u/Legacy_Account1479)\
**Post date:** [2017 年 6 月 19 日午前 10:00 UTC](https://community.cybozu.dev/t/topic/742/6 "2017-06-19T10:00:36Z")

</div>

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を使う
});
}
}

```

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1607](https://avatars.discourse-cdn.com/v4/letter/l/eada6e/32.png) [@Legacy\_Account1607](https://community.cybozu.dev/u/Legacy_Account1607)\
**Post date:** [2017 年 6 月 20 日午前 9:10 UTC](https://community.cybozu.dev/t/topic/742/7 "2017-06-20T09:10:10Z")

</div>

本田智明様

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

&nbsp;

無事実装できました。

またご指定いただいたとおり、100件以上の更新となるため、GETの部分に関しては[こちら](https://community.cybozu.dev/hc/ja/articles/201501294?mobile_site=true)を参考に同期処理に書き換えました。

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

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

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1479](https://avatars.discourse-cdn.com/v4/letter/l/e480ec/32.png) [@Legacy\_Account1479](https://community.cybozu.dev/u/Legacy_Account1479)\
**Post date:** [2017 年 6 月 22 日午前 4:20 UTC](https://community.cybozu.dev/t/topic/742/8 "2017-06-22T04:20:59Z")

</div>

takokichi さん

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex015/uploads/cybozu/original/1X/d5c841c3c5a6cb66eed514001c1b45147c9e1f4f.png) [@system](https://community.cybozu.dev/u/system)\
**Post date:** [2025 年 9 月 18 日午前 5:28 UTC](https://community.cybozu.dev/t/topic/742/9 "2025-09-18T05:28:46Z")

</div>

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。
