関連レコードの対象件数表示ができなく全レコードしか表示できない

初めて投稿させていただきます。

いつもこのサイトを見て勉強させていただいてます。

まったくの初心者で、kintoneに携わることにより初めてJavaScriptに向き合い始めています。

タイトルの通りなのですが、ある対象ユーザアプリ(Aアプリ)に対して、

そのユーザに対する顧客情報(Bアプリ)から関連レコードにて情報を引っ張ってきて

いるのですが、その関連レコードの件数を、スペースフィールドに表示したく。

ただ、Tipsの「プチ情報」や「関連レコードの項目を条件付きで集計」など、

とにかく参考にしてやってみているのですが、アプリBの全件が取得されてしまい、

Aアプリに関連した関連レコードだけの件数が取得できません。

ここで躓いてしまっていて、できればこれがクリアできたら、

STEP2として、スペースフィールドでなく、数値フィールドや文字列フィールドに

入れることができたらなぁ・・・と思っているのですが、野望のままです。。。

Aアプリに表示されている関連フィールドの件数だけを表示するんは、

どうしたらいいか、どなたかご教授いただけないでしょうか。

すみませんが、よろしくお願いいたします。

 

以下、そのコードになります。。。


(function() {
“use strict”;

kintone.events.on([‘app.record.detail.show’, ‘app.record.edit.show’], function(event) {

function fetchRecords(appId, opt_offset, opt_limit, opt_records) {
var Id = kintone.app.getRelatedRecordsTargetAppId(‘Relation’);
var offset = opt_offset || 0;
var limit = opt_limit || 500;
var allRecords = opt_records || [];
var params = {app: Id, query: ‘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(appId, offset + limit, limit, allRecords);
}
return allRecords;
});
}

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 divTotalAmount = document.createElement(‘div’);
divTotalAmount.style.fontWeight = ‘bold’;
divTotalAmount.style.textAlign = ‘center’;
divTotalAmount.style.fontSize = 12;
//divTotalAmount.innerHTML = num;
divTotalAmount.innerHTML = data_count + “件”;
kintone.app.record.getSpaceElement(“num”).appendChild(divTotalAmount);
return event;

});
});
})();


Hiro様

お世話になっております。
cstapの江田と申します。

queryに条件式を追加すれば、条件付きでレコードを取得できます。
https://developer.cybozu.io/hc/ja/articles/202331474#step2

また、fields.jsonを用いて、関連レコードフィールドの条件を取得できます。
https://developer.cybozu.io/hc/ja/articles/204783170

サンプルコードを書いてみました。
ご参考になればと思います。

(function() {
"use strict";
kintone.events.on(['app.record.detail.show', 'app.record.edit.show'], function(event) {
function getRelationFieldConditionData(){
var relationFieldConditionData = {};
relationFieldConditionData.id = kintone.app.getRelatedRecordsTargetAppId('Relation');
return kintone.api('/k/v1/app/form/fields', 'GET', {app:kintone.app.getId()}).then(function(resp) {
relationFieldConditionData.field = resp.properties.Relation.referenceTable.condition.field;
relationFieldConditionData.relatedField = resp.properties.Relation.referenceTable.condition.relatedField;
return relationFieldConditionData;
});
}
function fetchRecords(relationFieldConditionData, opt_offset, opt_records) {
var offset = opt_offset || 0;
var limit = 500;
var allRecords = opt_records || [];
var params = {
app: relationFieldConditionData.id,
query: relationFieldConditionData.relatedField + ' = "' + event.record[relationFieldConditionData.field].value + '" 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(relationFieldConditionData, offset + limit, allRecords);
}
return allRecords;
});
}
getRelationFieldConditionData().then(function(relationFieldConditionData){
return fetchRecords(relationFieldConditionData);
}).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 divTotalAmount = document.createElement('div');
divTotalAmount.style.fontWeight = 'bold';
divTotalAmount.style.textAlign = 'center';
divTotalAmount.style.fontSize = 12;
//divTotalAmount.innerHTML = num;
divTotalAmount.innerHTML = data_count + "件";
kintone.app.record.getSpaceElement("num").appendChild(divTotalAmount);
return event;
});
});
})();

STEP2のフィールドに入力する際には、こちらを参考にすると良いかと思います。
https://developer.cybozu.io/hc/ja/articles/201941984#step4
「app.record.create.submit」と「app.record.edit.submit」イベントでこれを行えばうまくいくと思います。

サイボウズスタートアップス  江田篤史 様

 

大変お世話になります。

このたびは本当にありがとうございます。

サンプルコードまでご教授くださり、本当に助かりました。

私の技量ではまだまだなのを痛感しました・・・。

本件で1ヶ月以上悩んでいて、どうにか自力で完成させたかったのですが。。

 

クエリー・・・なのかなぁとまではなんとなく思いましがが、

「fields.json」まではまったく思い至りませんでした。

 

自分なりに解釈しながら、サンプルコードを参考にさせていただき、

見事、やっと出したい数値が見れました!!涙が出ました。ありがとうございます。

細かいところでは、「opt_****」の理解も乏しく、まだまだ勉強が必要です。

 

ちゃんと内容理解したところで、教えて頂いたリンクを元に、STEP2に挑みたいと思います。

(また時間かかる予想がついていますが・・・)

ひとまず、ご報告まで。

 

本当にありがとうございます。また、よろしくお願いいたします。

 

江田 様

 

先日はご教授いただきありがとうございました。

早速、あのあとから、

https://developer.cybozu.io/hc/ja/articles/201941984#step4と

app.record.create.submit」と「app.record.edit.submit」イベント等
またいろいろなコミュニティを参考にやってみてるのですが、
どうしてもうまくいかず・・・。

改めて、STEP2としてやりたいことは、Aアプリに組み込んでいるBアプリの
関連フィールドの件数を、Aアプリのレコード一覧で表示させたときに
その数値が反映されるようにしたいのです。
Aアプリのレコード一覧で見たときに、Bアプリの関連レコードの件数が
いくつあるか、または無いのかをレコード詳細を開かずに確認したいのです。

いろいろやっているうちに、スペースフィールドに入れた数値を
数値フィールド(または文字列フィールド)に値を返す(コピー?)のか、
スペースフィールドへ表示させた値とは別に考えてAアプリの別フィールドに
値を表示させるのかすら、わからなくなって疑問が増えていくばかりです。。

前回のところから、app.record.create.submitとapp.record.edit.submit
を足して・・・
変数total1を指定して、

total1 = total1 + parseFloat(records[i][‘数値フィールド’(?)][‘value’]);
event.record[‘数値フィールド’][‘value’] = total1;

のようなやり方だったりするのかなと思い、いろいろ試してみましたが、
結果が出るどころか、なにも表示されることなく。

再度のお願いで大変恐縮なのですが、手段をご教授頂けると幸いです。
よろしくお願いいたします。

Hiro様

お世話になっております。
以下のようなコードで実装できるかと思います。
件数のフィールドコードは「件数」としています。

(function() {
"use strict";
kintone.events.on(['app.record.edit.submit', 'app.record.create.submit'], function(event) {
function getRelationFieldConditionData(){
var relationFieldConditionData = {};
relationFieldConditionData.id = kintone.app.getRelatedRecordsTargetAppId('Relation');
return kintone.api('/k/v1/app/form/fields', 'GET', {app:kintone.app.getId()}).then(function(resp) {
relationFieldConditionData.field = resp.properties.Relation.referenceTable.condition.field;
relationFieldConditionData.relatedField = resp.properties.Relation.referenceTable.condition.relatedField;
return relationFieldConditionData;
});
}
function fetchRecords(relationFieldConditionData, opt_offset, opt_records) {
var offset = opt_offset || 0;
var limit = 500;
var allRecords = opt_records || [];
var params = {
app: relationFieldConditionData.id,
query: relationFieldConditionData.relatedField + ' = "' + event.record[relationFieldConditionData.field].value + '" 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(relationFieldConditionData, offset + limit, allRecords);
}
return allRecords;
});
}
return getRelationFieldConditionData().then(function(relationFieldConditionData){
return fetchRecords(relationFieldConditionData);
}).then(function(records){
var data_count = 0;
for (var i = 0; i < records.length; i++) {
data_count++;
}
event.record.件数.value = data_count;
return event;
});
});
})();

江田 様

今回もお世話になっております。
返信くださり、大変ありがとうございます。

event.record.Total.value = data_count;
return event;

のところは、何度か行きついたりしたのですが、
やっぱり反応しないので、もっと複雑なものと思っていたのですが、

return getRelationFieldConditionData().then(function(relationFieldConditionData){
           fetchRecords(relationFieldConditionData);

 

のところを、

return getRelationFieldConditionData().then(function(relationFieldConditionData){
return fetchRecords(relationFieldConditionData);

 

と、returnを付けなければ、どうやっても動かなかったということなんですね。。
まだわからないことが多いので当然と言ったらそれまでなのですが・・・
kintone.Promiseのこともしっかり勉強したいと思います。

そして、再度の質問になってしまうようで恐縮なのですが、
アプリAを対象に一括レコード読み込みしてデータの更新をする以外に
アプリAのレコード一覧を開いたときに、今回出した「件数」フィールドの値が
すべて更新&表示されるようにしようと思ったら、プログラミング制御で
できるものなのでしょうか。

Hiro様

お世話になっております。
以下のようなコードで実装できるかと思います

(function() {
"use strict";
kintone.events.on('app.record.index.show', function(event) {
var changed = false;
var relationFieldConditionData = {};
var putBody = {
"app": kintone.app.getId(),
"records":[]
};
function getRelationFieldConditionData(){
var relationFieldConditionData = {};
relationFieldConditionData.id = kintone.app.getRelatedRecordsTargetAppId('Relation');
return kintone.api('/k/v1/app/form/fields', 'GET', {app:kintone.app.getId()}).then(function(resp) {
relationFieldConditionData.field = resp.properties.Relation.referenceTable.condition.field;
relationFieldConditionData.relatedField = resp.properties.Relation.referenceTable.condition.relatedField;
return relationFieldConditionData;
});
}
function fetchUserRecords(offset=0, allRecords=[]) {
let limit = 500;
let params = {
app: kintone.app.getId(),
query: '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 fetchAllRecords(offset + limit, allRecords);
}
return allRecords;
});
}
function fetchRelationRecords(relation_value, opt_offset=0, opt_records=[]) {
var offset = opt_offset;
var limit = 500;
var allRecords = opt_records;
var params = {
app: relationFieldConditionData.id,
query: relationFieldConditionData.relatedField + ' = "' + relation_value + '" 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 fetchRelationRecords(relationFieldConditionData, offset + limit, allRecords);
}
return allRecords;
});
}
getRelationFieldConditionData().then(function(resp){
relationFieldConditionData = resp;
return fetchUserRecords();
}).then(function(userRecords){
var promises = [];
userRecords.forEach(function(userRecord){
promises.push(
fetchRelationRecords(userRecord[relationFieldConditionData.field].value).then(function(relationRecords){
if(userRecord.件数.value != relationRecords.length){
putBody.records.push({
"id": userRecord.$id.value,
"record": {
"件数": {
"value":relationRecords.length
}
}
});
changed = true;
}
})
);
});
Promise.all(promises).then(function(){
if(changed){
kintone.api('/k/v1/records', 'PUT', putBody, function(){
location.reload();
});
}
});
});
});
})();

江田 様

いつもお世話になります。
ご連絡が遅くなりましたが、作動させたい通りに実装できました!

理解してからの返信にしようと思っていましたが、
最初のコードから、全体的にこんなに変わると思っていなく、
まだまだ・・・というか、意味不明なところがたくさんあります。

空更新を行うのかも?というところは、ヒットしていましたが、
少し時間をかけて理解しながら勉強します。

この度は、本当にありがとうございました。
これを元に、理解を深めていきたいと思います。

江田 様

お世話になります。
たびたびすみません。

動作環境が整うたびに次なる質問が出てきてしまい、
大変恐縮なのですが、もう一つ教えてください。

件数フィールドを編集不可にしたいのです。ただ、
「event.record.件数.disabled = true;」
を、どのように実装させればいいのかわからず。

理解が浅いので、更に疑問が生じてしまっているのですが、
上記を実装させることができた場合、
① 数字(件数)が入ったフィールドだけが編集不可になる
② すべての件数フィールドに対して編集不可にできる

できれば、②で実装させたいのですが、可能でしょうか。

ご教授いただきたく、よろしくお願いいたします。

Hiro様

お世話になっております。 cstapの江田です。

前回提示したコードには何点か誤りがありました。 大変申し訳ございません。

今回や、以前までの件をまとめて書き直したので、ご参考になればと思います。

(function(){"use strict";//件数フィールドを編集不可にするkintone.events.on(['app.record.index.edit.show','app.record.edit.show','app.record.create.show'],function(event){event.record.件数.disabled=true;returnevent;});//一覧表示時に件数更新kintone.events.on('app.record.index.show',function(event){varchanged=false;varputBody={"app":kintone.app.getId(),"records":[]};getRelationFieldConditionData().then(function(relationFieldConditionData){varpromises=[];event.records.forEach(function(userRecord){promises.push(fetchRelationRecords(relationFieldConditionData,userRecord[relationFieldConditionData.field].value).then(function(relationRecords){if(userRecord.件数.value!=relationRecords.length){putBody.records.push({"id":userRecord.$id.value,"record":{"件数":{"value":relationRecords.length}}});changed=true;}}));});Promise.all(promises).then(function(){if(changed){kintone.api('/k/v1/records','PUT',putBody,function(){location.reload();});}});});});//詳細表示時に件数更新kintone.events.on('app.record.detail.show',function(event){varuserRecord=event.record;getRelationFieldConditionData().then(function(relationFieldConditionData){fetchRelationRecords(relationFieldConditionData,userRecord[relationFieldConditionData.field].value).then(function(relationRecords){if(userRecord.件数.value!=relationRecords.length){varputBody={"app":kintone.app.getId(),"id":userRecord.$id.value,"record":{"件数":{"value":relationRecords.length}}};kintone.api('/k/v1/record','PUT',putBody,function(){location.reload();});}});});});//submit時に件数挿入kintone.events.on(['app.record.edit.submit','app.record.create.submit'],function(event){varuserRecord=event.record;returngetRelationFieldConditionData().then(function(relationFieldConditionData){returnfetchRelationRecords(relationFieldConditionData,userRecord[relationFieldConditionData.field].value).then(function(relationRecords){userRecord.件数.value=relationRecords.length;returnevent;});});});functiongetRelationFieldConditionData(){varrelationFieldConditionData={};relationFieldConditionData.id=kintone.app.getRelatedRecordsTargetAppId('Relation');returnkintone.api('/k/v1/app/form/fields','GET',{app:kintone.app.getId()}).then(function(resp){relationFieldConditionData.field=resp.properties.Relation.referenceTable.condition.field;relationFieldConditionData.relatedField=resp.properties.Relation.referenceTable.condition.relatedField;returnrelationFieldConditionData;});}functionfetchRelationRecords(relationFieldConditionData,relation\_value,opt\_offset,opt\_records){varoffset=opt\_offset||0;varlimit=500;varallRecords=opt\_records||[];varparams={app:relationFieldConditionData.id,fields:["レコード番号"],query:relationFieldConditionData.relatedField+' = "'+relation\_value+'" order by レコード番号 asc limit '+limit+' offset '+offset};returnkintone.api('/k/v1/records','GET',params).then(function(resp){allRecords=allRecords.concat(resp.records);if(resp.records.length===limit){returnfetchRelationRecords(relationFieldConditionData,relation\_value,offset+limit,allRecords);}returnallRecords;});}})();

江田 様

お世話になります。
返信遅れましてすみません。

ひとつひとつ丁寧に読みながら完成させてました。
自分のやりたいことが、こんな長いコードになるとは・・・。
改めて深いものを感じました。

私がきちんと理解するのには、まだだいぶ努力が必要ですが、
それでも得るものがすでにたくさんあったので、これを元に
いろいろ勉強していきます。

本当に、本件につきまして、ありがとうございました。
また質問させていただくので、よろしくお願いいたします!

Hiro 様

横から大変失礼致します。

大変恐縮でございますが、Hiroさんの投稿を参考にさせていただきたく模索しておりますが、初心者のためぜんぜん進まずここにコメントさせて頂きました。 自分の投稿は関連レコード集計について です。やりたいことはHiroさんとまったく同じように思われますが、現Hiroさんのコードだけでは自分のコードをどう修正して対応すればいいのか分からず、焦っております。もし可能であれば、Hiroさんのコードになっているアプリの画像を添付していただけることは可能でしょうか?頂ければそれをマネしてアプリを作成し、動かしてから、自分のアプリを修正してみたいです。もし難しいそうであればなにかアドバイスいただけることは可能でしょうか?本当に申し訳ございませんが、何卒よろしくお願い致します。

玲香 様

 こんにちは。
私の場合は、ツリーを見て頂くとおり、江田様に大変お世話になったので、
ほぼ自力ではできていません。私は超初心者です(笑)。

これに関しては去年はハマってしまっていて、ぜんぜん答えが出せずにいたのですが、
問題がクリアになってから、カウント数を出すためには、

https://developer.cybozu.io/hc/ja/articles/213209606-%E9%96%A2%E9%80%A3%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E4%BB%B6%E6%95%B0%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%83%AF%E3%82%B6 

で、ちょうど情報が更新されていましたので、そちらを参考にしても良いかと思われます。

私は、スペースフィールドでなく、「文字列(一行)」に入れたかったので、更に相談させていただきました。

添付がほしいとのことでしたので、添付いたします。
フィールドコードの指定は、この二つだけです。

ご確認いただけると幸いです!!

Hiro 様

お世話になっております。早速お返事いただき、本当にありがとうございます。

私も初心者のため、頭を悩める毎日です。江田様にも色々と教わってもらっているところです。Hiroさん、色々と教えていただき、本当にありがとうございます。

まだまだ全然わかってないですが、参考にさせて頂きます。