お世話になります。
kintone Tips & サンプルの、「関連レコードの件数を取得するワザ」を
参考に、関連レコード数をスペースに入力することはできたのですが、
関連レコードを画像のように複数置いて、それぞれのレコード数を取得し、
数値フィールドにセットされるようにする方法をお教えいただけますでしょうか?
画像:
目的は、レコード数を使って計算をするためです。
取得した値をフィールドにセットせずに計算結果だけを取り出す方法もあるかとは思いますが、最終的に作りたいデータが複雑になる可能性があるため、状態を把握するためにも、一旦数値フィールドにレコード数を入力したいと考えております。
念のため、「関連レコードの件数を取得するワザ」のサンプルコードも下記にて記載させていただきます。
/*
* value of RelatedRecords program
* Copyright (c) 2016 Cybozu
*
* Licensed under the MIT License
*/
(function() {
‘use strict’;
// 関連レコードの絞り込みに利用するフィールドコード
var FIELDNAME_A = ‘CompanyName’; // Aアプリ
var FIELDNAME_B = ‘CustomerName’; // Bアプリ
kintone.events.on(‘app.record.detail.show’, function(event) {
// 関連レコードで取得しているアプリの対象レコードを全件取得
function fetchRecords(opt_Field, opt_offset, opt_limit, opt_records) {
var Id = kintone.app.getRelatedRecordsTargetAppId(‘relation’);
var offset = opt_offset || 0;
var limit = opt_limit || 100;
var allRecords = opt_records || [];
var params = {app: Id, query: opt_Field + ’ order by レコード番号 asc limit ’ + 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(opt_Field, offset + limit, limit, allRecords);
}
return allRecords;
});
}
// 関連レコードの「表示するレコードの条件」に合わせてクエリを作成
var CompanyNameValue = event.record[FIELDNAME_A].value;
var opt_Field = FIELDNAME_B + ‘=’ + ‘"’ + CompanyNameValue + ‘"’;
fetchRecords(opt_Field).then(function(records) {
// スペースフィールドにBアプリのレコード数を反映
var num = records.length;
var divTotalAmount = document.createElement(‘div’);
divTotalAmount.style.fontWeight = ‘bold’;
divTotalAmount.style.textAlign = ‘center’;
divTotalAmount.style.fontSize = 12;
divTotalAmount.innerHTML = num;
kintone.app.record.getSpaceElement(‘num’).appendChild(divTotalAmount);
return event;
});
});
})();
レコードの値をセットする方法を読んでも上手く設定できませんでした。
javascriptの知識は一覧画面の値を条件によって色を付けたり、アラートを鳴らすといった程度なら、サンプルを見ながら何とか設定できるという程度です。
お手数ですが、宜しくお願いいたします。
k_yamamoto様
お世話になっております。
cstapの江田と申します。
参考にされたコードでは関連レコードを非同期で取得しているので、取得後にレコードの値をセットするにはPromiseを利用するとよいです。
https://developer.cybozu.io/hc/ja/articles/204564604
また、こちらの記事のコメントが似たような案件なので参考になるかと思います。
https://developer.cybozu.io/hc/ja/community/posts/360017851006#community_comment_360002846572
cstap 江田様
コメントありがとうございます。
「kintoneアプリは非同期処理」というのが関わっているんですね・・・。
いろんな可能性を調べて混乱しておりました。
調べる方向がはっきりと分かったのでpromiseについて頑張って調べてみます!
cstap 江田様
お世話になります。
すみません、教えていただいたURLのコードにてスペースに集計数を
入力できることを確認したあと、同じく教えていただいたURL記載のコードを参考に、
kintone.promiseを使用したコードを書いてみましたが、数値フィールドに値を入力することができませんでした。
そこで質問(1)ですが、下記記述での間違いをお教えいただけませんでしょうか。
まずは確認のためできるだけコードを書き換えずに値が入力されるようにしたコードが下記になります。
関連レコード一覧のフィールドコード:案件一覧
関連レコード内の集計したいフィールド名:合計費用
数値を入力したい数値フィールドのフィールドコード:total
(因みに関連レコードの参照アプリは「案件管理(営業支援パック)」を使用)
~~~~~~~~~~~~~~~~~~~~~
(function() {
“use strict”;
kintone.events.on([‘app.record.create.submit’,‘app.record.edit.submit’], function(event){
return new kintone.Promise(function(resolve){
RelatedRecordsFieldManager.prototype.getFieldProperties().then(function(){
(new RelatedRecordsFieldManager(‘案件一覧’)).getRecords(event.record).then(function(records){
//RelatedRecordsFieldManager(‘関連レコード一覧4’))の’関連レコード一覧4’を’案件一覧’へ変更
//合計数値の合計値☆
event.record.total.value = records.reduce(function(sum, record){
//sale4をtotalに変更
return sum + Number(record.合計費用.value);
//(record.sale.value)を、(record.合計費用.value)に変更
}, 0);
resolve(event);
});
});
});
});
// コンストラクタ定義(参照URLのコードをそのままコピペしてます)
var RelatedRecordsFieldManager = (function(fieldCode){
function RelatedRecordsFieldManager(fieldCode) {
this.fieldCode = fieldCode;
this.targetAppId = kintone.app.getRelatedRecordsTargetAppId(fieldCode);
this.property = this.fieldProperties[fieldCode].referenceTable;
}
RelatedRecordsFieldManager.prototype = {
selfAppId: kintone.app.getId(),
records: [],
limit: 500,
offset: 0,
getFieldProperties: function(){
return kintone.api(kintone.api.url(‘/k/v1/app/form/fields’, true), ‘GET’, {
app: RelatedRecordsFieldManager.prototype.selfAppId,
}).then(function(response){
RelatedRecordsFieldManager.prototype.fieldProperties = response.properties;
});
},
query: function(record){
return (
this.property.condition.relatedField +
‘="’ +
record[this.property.condition.field].value +
(this.property.filterCond ? ‘" and ’ : ‘"’) +
this.property.filterCond
);
},
getRecords: function(record){
var _this = this;
return kintone.api(kintone.api.url(’/k/v1/records’, true), ‘GET’, {
app: this.targetAppId,
query:
this.query(record) +
’ order by ’ + this.property.sort +
’ limit ’ + this.limit +
’ offset ’ + this.offset
}).then(function(response){
_this.records = _this.records.concat(response.records);
_this.offset += response.records.length;
if(response.records.length === _this.limit){
return _this.getRecords(record);
}else{
return _this.records;
}
});
}
}
return RelatedRecordsFieldManager;
})();
//コンストラクタ定義ここまで
});
~~~~~~~~~~~~~~~~~~~~~
質問2:
また、わたしが実際に数値フィールドに入力したい値は、レコード数なので、「合計数値の合計値☆」記述部分は下記のようになるかと思われますが間違っておりますでしょうか。
event.record.total.value = Number(records.length);
質問3:
さらに、複数の関連レコード一覧を設置しレコード数を集計するときは、上記コードの
resolve(event);
の、前に、
下記コードのようにコードを追加する、という方法でよろしいでしょうか。
RelatedRecordsFieldManager.prototype.getFieldProperties().then(function(){
(new RelatedRecordsFieldManager(‘案件一覧2’)).getRecords(event.record).then(function(records){
event.record.total2.value = Number(records.length);
}
k_yamamoto様
お世話になっております。 質問1、質問2についてはそちらで問題ないかと思います。 ただ、Array.lengthはもともと数値型を返すので、Number()は不要です。
質問3について、もし非同期処理を直列で書くのであれば、resolve(event)は「案件一覧2」側のthenの中に記述する必要があります。 また、フィールドプロパティは既に取得しているので、再度RelatedRecordsFieldManager.prototype.getFieldProperties()を記述する必要はありません。
Promise.allを用いると並列で処理できるので便利です。
(function(){"use strict";kintone.events.on(['app.record.create.submit','app.record.edit.submit'],function(event){returnnewkintone.Promise(function(resolve){RelatedRecordsFieldManager.prototype.getFieldProperties().then(function(){kintone.Promise.all([(newRelatedRecordsFieldManager('案件一覧')).getRecords(event.record),(newRelatedRecordsFieldManager('案件一覧2')).getRecords(event.record)]).then(function(responses){event.record.total.value=responses[0].length;event.record.total2.value=responses[1].length;resolve(event);});});});});...})();
cstap 江田様
お世話になっております。
思い通りの結果ができました!
本当にありがとうございます。
また、このコードのおかげで自動計算を利用した集計結果同士の計算もできるようになりました。
新たな集計項目ができた際、関連データ一覧に表示させている他のアプリのデータのフィールドコードを確認しなくて良いのでミスを減らすことができ、作業がしやすいです!
集計作業がんばります!
お世話になります。
こちらの案件と同じことをしたいのですが、
javascriptの知識は皆無で、今まで色々なサイトの情報を参考に理解せずにサンプルコードをコピペコピペでしのいできましたが
いよいよ限界を感じています。
実現したいことは、関連レコードのレコード数を最終的に数値フィールドにセットしたい、です。
関連レコードは1つで大丈夫です。関連レコード数をスペースに入力するところまでは出来たのですが、
数値フィールドへのセットが出来ないまま力尽きています。
・関連レコードのフィールド名:relation
・スペースフィールドのフィールド名:num
・関連レコード内の集計したいフィールド名:担当者名
・数値を入力したい数値フィールドのフィールドコード:total
▼以下、色んなサイトのコピペをつぎはぎした記述の修正点を教えていただけると幸いです。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(function () {
“use strict”;
kintone.events.on([‘app.record.detail.show’, ‘app.record.edit.show’], function (event) {
// まず、アプリのフィールド設定を取得しておく
RelatedRecordsFieldManager.prototype.getFieldProperties().then(function () {
// 関連する担当者一覧のレコードを取得する
(new RelatedRecordsFieldManager(‘relation’)).getRecords(event.record).then(function (records) {
// spaceにレコード数を表示
kintone.app.record.getSpaceElement(“num”).innerHTML = records.length;
event.record.total.value = responses[0].length;
resolve(event);
});
});
});
// コンストラクタ定義
var RelatedRecordsFieldManager = (function(fieldCode){
function RelatedRecordsFieldManager(fieldCode) {
this.fieldCode = fieldCode;
this.targetAppId = kintone.app.getRelatedRecordsTargetAppId(fieldCode);
this.property = this.fieldProperties[fieldCode].referenceTable;
}
RelatedRecordsFieldManager.prototype = {
selfAppId: kintone.app.getId(),
records: [],
limit: 500,
offset: 0,
getFieldProperties: function(){
return kintone.api(kintone.api.url(‘/k/v1/app/form/fields’, true), ‘GET’, {
app: RelatedRecordsFieldManager.prototype.selfAppId,
}).then(function(response){
RelatedRecordsFieldManager.prototype.fieldProperties = response.properties;
});
},
query: function(record){
return (
this.property.condition.relatedField +
‘="’ +
record[this.property.condition.field].value +
(this.property.filterCond ? ‘" and ’ : ‘"’) +
this.property.filterCond
);
},
getRecords: function(record){
var _this = this;
return kintone.api(kintone.api.url(’/k/v1/records’, true), ‘GET’, {
app: this.targetAppId,
query:
this.query(record) +
’ order by ’ + this.property.sort +
’ limit ’ + this.limit +
’ offset ’ + this.offset
}).then(function(response){
_this.records = _this.records.concat(response.records);
_this.offset += response.records.length;
if(response.records.length === _this.limit){
return _this.getRecords(record);
}else{
return _this.records;
}
});
}
}
return RelatedRecordsFieldManager;
})();
})();