kintoneエバンジェリストに指名いただきましたラジカルブリッジの斎藤と申します。
当社Webサイト内の「kintoneブログ」でもkintoneに関する様々な小ネタを発信しておりますが、今後はこちらのdeveloper networkでも情報発信をしていきたいと思っていますのでどうぞ宜しくお願いいたします。
今回は、運用中のアプリに新たに「計算」フィールドを追加した際に、JavaScriptを用いて計算フィールドに一括で値を反映する方法を紹介します。
kintoneは、一度作成したアプリでも後で簡単にフィールドを追加することができるため、最初に全ての要件が揃っていなくてもまずは作り始められるというのが素晴らしいところです。
しかしながら、数値フィールドの計算結果を格納するような計算フィールドを後で追加した場合、そのままでは既存のレコードには自動的に計算結果が格納されません。
レコードの詳細画面を開いて、何も変更せずに再保存することで計算フィールドに計算結果を反映することはできますが、大量のレコードが登録されているような場合、全てのレコードに対してこのような作業を行うのはベターなやり方ではありません。
そこで、ボタンを一回押すだけで一括で値を反映させてみたいと思います。
デモ環境
デモ環境で実際に動作を確認できます。
https://dev-demo.cybozu.com/k/71/
ログイン情報は cybozu developer network デモ環境 で確認してください。
サンプルイメージ
今回ご紹介するJavaScriptはどんなアプリにでも対応できるのですが、ここではある会合の「合計金額」と「参加人数」を記録するアプリを想定してみましょう。下の図はその一覧画面を表示したもので、3レコード登録されています。
ここで参加者一人当たりの金額を計算で出してみたくなり、「一人当たりの金額」という計算フィールドを追加しました。もちろん計算式は「合計金額 / 参加人数」です。(フィールドのタイトルとフィールドコードを揃えています)
下の図は、「一人当たりの金額」フィールドを追加した直後の一覧画面です。
ご覧のように、計算フィールドを追加しただけでは、まだ計算結果が格納されていません。
このサンプルでは3レコードしかありませんので、一つ一つのレコードを再保存することで計算結果を反映することもできるのですが、これが数百レコードある場合は作業する気にもなりません。。
そこで今回は複数レコードを空更新することで、一括で値を反映をしたいと思います。
複数レコードに空更新を行う
あとは、このパラメーターをもとにPUTメソッドでレコードを更新すれば更新完了です。
尚、このスクリプトは「レコード番号」フィールドのフィールドコードが、既定値である「レコード番号」になっていることを前提としています。
※このままスクリプトを作成すると100レコードまでのアプリの対応となります。100レコードより多い場合は「offset の制限値を考慮したレコード一括取得について」をご参照ください。
一括で値を反映させてみよう
JavaScriptでレコード一覧画面にボタンを配置して、一括で値を反映してみましょう。
ボタンの設置の仕方はこちらの記事をご参考ください。
このボタンをクリックして空更新を行う関数を呼び出します。
以下の図のように「一人当たりの金額」フィールドに正しい計算結果が格納されていることがわかります。
とっても楽チンですね!
kintoneアプリの運用を続けているとフィールドの追加は必ず発生してくるものですが、今回ご覧いただいたような計算フィールドへの一括反映処理が必要となる場面が必ず出てくるかと思います。このスクリプトはどんなアプリにでも対応可能ですので、同様の場面に遭遇した際にぜひご活用ください。
このTipsは、2022年10月版で確認したものになります。
はじめましてKintoneを利用しはじめて2か月目のJS初心者です。
こちらを見て作成してみましたがうまく動きません、どこがおかしいのでしょうか?
お手数ですがご教授頂けますでしょうか、よろしくお願いいたします。
(function () {
"use strict";
kintone.events.on('app.record.index.show', function (event) {
if (document.getElementById ('my_index_button') != null) {
return;
}
})();
hatanoさん
cybozu.com developer network事務局です。
どのようなエラーになりますでしょうか?
hatanoさん
はじめまして。
鈴木と申します。
// ボタンクリック時の処理
myIndexButton.onclick = function() {
// 下記を追加 -----
var appId = kintone.app.getId();
// -----
kintone.api('/k/v1/records', 'GET', {app: appId}, function(resp) {
としたらどうでしょうか?
デモで使われてるコードがほしい
はじめまして
Kintone5か月、JS3か月の初心者です。
上記のサンプルと、その他のページのサンプルをつなぎ合わせて以下のコードを作りました。
一応ボタンは表示され、レコードを投げるまではできているようですが、データの更新はされていないみたいです。
(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]['レコード番号']['value'],
"record": {}
}
}
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', param, function(resp) {
// success
console.log(resp);
}, function(error) {
// error
console.log(param);
console.log(error);
});
});
}
kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);
});
})();
IEの開発者ツールを開くと、コンソールに次のようなメッセージを含んだレコードが出力されています。
messages: [
0: "更新するレコードを、「id」か「updateKey」のいずれかのパラメーターで指定する必要があります。",
length: 1
]
id: "1505999166-1853162239",
message: "入力内容が正しくありません。"
送ったレコードの書式が間違っているのでしょうか?
吉村さん
初めまして。著者の斎藤です。
本記事では1レコードずつの更新ではなく、「一括更新」を想定した空更新オブジェクトの生成を行っていますので、
APIのURIは '/k/v1/record' ではなく '/k/v1/records' にする必要があります。
(最後にsがつきます)
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', param, function(resp) {
↓
kintone.api(kintone.api.url('/k/v1/records', true), 'PUT', param, function(resp) {
いかがでしょうか?
レコードの一括更新については、下記リファレンスもご確認いただければと思います。
https://cybozudev.zendesk.com/hc/ja/articles/201941784-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B4%E6%96%B0-PUT-#step2
斎藤さん。
無事、動作しました。
ご指摘のリファレンスも見ながら作成したのですが、URIの記述の違いに気付かずに1レコード用のものをコピー&ペーストしてしまったようです。
修正したプログラムを実行して再計算ボタンを押した後、F5を押して再読み込みをしたら、計算結果が更新されました。
ありがとうございました。
吉村さん
無事動いたようで何よりです。
kintone REST APIのGET, POST, PUTでは record とrecords を間違えることがよくあるので一目でわかりました(^^;
JSを始めてまだ間もない様子ですが、JSそのもののつまづきポイントとkintoneならではのつまづきポイントがあるので
また何かありましたら投稿いただければと思います。
同じボタンを設置したいと思い、このページを参考に試してみましたが、ボタンを押しても何も起こりませんでした。
提示されているデモ環境では、ボタンを押したあと、更新かかっているような動作をしますが、各レコードを表示しても、更新されていませんでした。
最新の環境で動作するコードを提供いただければ助かります。何卒よろしくお願いします。
grezou 様
本記事に記載されているサンプルコードは、行いたい処理(レコードの空更新)の記述方法を一部抜き出したものです。
この部分の処理に関しては、現状のkintoneでも動作するものになっています。
また、デモ環境は「複数の方が同時にアクセスして動作を見る環境である」という特性上、本記事に関しましては記事通りの動作を確認いただくものの用意はできません。
このため、デモアプリでは自動計算の設定を外し、更新日時でレコードの空更新をご確認いただく内容となっております。
「サンプルコードに書き足したり、書き換えた箇所でうまく動作しない」ということでしたら、以下の記事を参考にデバッグをお試しください。
デバッグしても解決できない場合には、コミュニティ をご活用いただければと思います。
どうぞよろしくお願いいたします。
はじめまして。プログラムど素人です。
皆様の投稿を参考にしてみたのですが、どうもエラーが起きているようです。
どこが違うのか、根本的にどこを直したらいいのか教えて頂けると助かります。
(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 = '再計算';
//////// 空更新オブジェクトの生成
var param = {
"app": appId,
"records": []
};
for (var i = 0; i < resp['records'].length; i++) {
param['records'][i] = {
"id": resp['records'][i]['レコード番号']['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);
});
})();
JSEdit for kintoneで作成したのですが、最後の kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);の箇所が×になっています。
どうかお力をお貸しください。。。よろしくお願い致します。
胤森 加菜様
下記の投稿と同様の要件を実現されたいということでよろしいでしょうか。
https://developer.cybozu.io/hc/ja/articles/201883830/comments/204526203
そうであれば、上記のリンク先のコードで下記の部分を
下記のように変更いただければ動作すると思います。
提示いただいたコードでは // ボタンクリック時の処理 下の3行が不足しているようです。
本記事に記載されているサンプルコードは、行いたい処理(レコードの空更新)の記述方法を一部抜き出したものです。
こちらは記事のフィードバック欄のため、「サンプルコードに書き足したり、書き換えた箇所でうまく動作しない」ということでしたら、以下の記事を参考にデバッグをお試しください。
デバッグしても解決できない場合には、コミュニティ をご活用いただければと思います。
どうぞよろしくお願いいたします。
気になった点があります。
id にレコード番号を設定していますが、
アプリコードを指定している場合、レコードID ≠ レコード番号になるような気がします。
https://developer.cybozu.io/hc/ja/articles/202166330
こちらでもAPIを使う場合は、レコード番号でなくレコードIDを使うよう推奨されているようですし、
の方がよいのではないでしょうか?
T.H 様
お世話になっております。cybozu developer network 運営でございます。
フィードバックをいただき、ありがとうございます。
ご指摘の内容を社内にフィードバックし、修正を検討します。
今後ともよろしくお願いいたします。