JavaScriptカスタマイズを行うことによってkintoneの標準機能ではできないことを実現することができます。しかし、初心者の方にとっては少しハードルが高いですよね。複数のアプリが関わってくるとAPIや非同期処理が絡んできて、他の人が作成したコードを見てもその内容を理解できないことが多いと思います。
今回は、kintoneの標準機能では行うことのできない「別アプリのテーブル情報を取得する」機能を実現することを念頭に、一緒にアプリを作成していきましょう。
本記事はこのような方におすすめ!
- プログラミング初心者
- kintoneの初歩的なJavaScriptカスタマイズを行ったことがある
- APIや非同期処理を含んだカスタマイズに挑戦したい
アプリの概要
活動記録とプロジェクト管理という2つのアプリを作成します。今回カスタマイズを実装する活動記録の機能は、「活動内容・プロジェクト名などmtgに関するデータを入力し、その記録を一覧で表示する」ということになります。活動記録のアプリでレコードを作成する際、プロジェクト名を入力した際に、プロジェクト管理のアプリを参照して、共有先メンバーを自動的に追加できるようカスタマイズを行います。

2つのアプリのフィールドの詳細は以下のようになります。

活動記録のアプリを作成する際に、プロジェクト名に応じたメンバー情報をテーブル(共有先)にコピーするように設定できれば良いのですが、冒頭でも述べたようにkintoneの標準機能では別アプリのテーブルをコピーすることができません。

では、ここから以下の流れに沿ってJavaScriptのカスタマイズを作成していきましょう。
- 活動記録のテーブル[共有先]に入れる値の種類に応じて、配列変数を用意
- kintone REST API を使用して、プロジェクト管理のテーブル[メンバー]の値を取得し、それぞれの配列変数に要素を追加(get_shareData関数の定義)
- 各配列に全ての要素が入ったら、活動記録のテーブル[共有先]の値を更新(make_result関数の定義/Promiseで処理順序の制御)
1.活動記録のテーブル[共有先]に入れる値の種類に応じて、配列変数を用意
kintone.events.on([
'app.record.create.change.開始日時', 'app.record.edit.change.開始日時'], (event) => {
const shareMem = [];
const shareDep = [];
const shareMail = [];
const sharePart = [];
まず、kintone.events.on() メソッドを使用して、「プロジェクト開始日時」フィールドの値が変更されたときに実行される関数を定義します※。次に氏名・部署・メールアドレス・役割に分けて4つの配列変数を用意します。
※ イベントタイプについて
プロジェクト名が変更された際に共有先テーブルに情報を格納したいので、「レコードの作成・編集時にプロジェクト名が変更された時[‘app.record.create.change.プロジェクト名’, ‘app.record.edit.change.プロジェクト名’]」を指定したくなります。しかし、ルックアップのフィールドはフィールド値変更時イベントで指定できません。そのため、今回はプロジェクト名をルックアップで取得した際にコピーされる別のフィールド”プロジェクト開始日時”を設置し、”プロジェクト開始日時”の値の変更をトリガーにすることにしました。
2.kintone REST API を使用して、プロジェクト管理のテーブル[メンバー]の値を取得し、それぞれの配列変数に要素を追加(get_shareData関数の定義)
get_shareData関数の中で、プロジェクト管理からデータを取得することにします。そのような機能を果たすためにはkintone REST APIを利用することになります。kintone REST APIの基本形は以下のようになります。
kintone.api(pathOrUrl, method, params, successCallback, failureCallback)
各パラメータに何を入れるかは、利用するkintone REST APIに応じて変化します。差し当たって私たち初心者は、methodのパラメータにGET(取得), POST(登録), PUT(更新), DELETE(削除) を指定できることを覚えておきましょう。何ができるのかを理解しておけば、cybozu developer networkのページから基本的な形を参照することができます。
レコードの取得(GET)/レコードの登録(POST)/レコードの更新(PUT)/レコードの削除(DELETE)
const record = event.record;
const proName = record.プロジェクト名.value;
const body = {
'app': ”アプリID”,
'query': 'プロジェクト名 = "' + proName + '"',
'fields': ['メンバー']
};
function get_shareData() {
kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body,
function(resp) {
resp.records.forEach(function(record) {
const memTable = record.メンバー.value;
for (var t = 0; t < memTable.length; t++) {
shareMem.push(memTable[t].value.氏名.value);
shareDep.push(memTable[t].value.部署.value);
shareMail.push(memTable[t].value.メールアドレス.value);
sharePart.push(memTable[t].value.役割.value);
}
});
});
}
今回は特定のアプリのレコードを条件付けて取得(GET)したいので、レコードの一括取得APIを参考に進めます。基本的には掲載されている形のまま利用できますが、自分でbodyを宣言し、取得したい情報を指定する必要があります。今回はプロジェクト管理において、”プロジェクト名”フィールドに入力したプロジェクトのレコードの、フィールドコードが”メンバー”である部分を指定しています。レコード取得が成功した場合には、1.で用意した配列変数に、得られたテーブルの各要素を追加します。
ちなみにテーブルの値を指定するのがややこしいですが、以下の画像をイメージするとわかりやすいと思います。この例では、フィールドコードが”共有先”のテーブルの3行目、中居さんの役割部分を指定していることになります。

3.共有先テーブルの値を更新
・make_result関数の定義
function make_result() {
const record = kintone.app.record.get().record;
const shareTable = record.共有先.value;
while (shareTable.length > 0) {
shareTable.splice(0, 1);
}
for (var i = 0; i <= shareMem.length - 1; i++) {
shareTable.push({
value: {
"共有者": {
value: shareMem[i],
type: "SINGLE_LINE_TEXT"
},
"部署": {
value: shareDep[i],
type: "DROP_DOWN"
},
"メールアドレス": {
value: shareMail[i],
type: "LINK"
},
"役割": {
value: sharePart[i],
type: "SINGLE_LINE_TEXT"
},
"連絡確認": {
value: [],
type: "CHECK_BOX"
}
}
});
}
kintone.app.record.set({
record: record
});
}
make_result関数では、一旦活動記録のテーブル[共有先]の初期化を行った後、2.で完成した各配列の要素を追加する処理を行なっています。テーブルに要素の追加を行う処理ですが、ここで一つ注意点があります。テーブルに行の追加を行う際は、値だけでなく、必ずフィールドタイプの指定が必要です。文字列(1行)ならSINGLE_LINE_TEXT、数値ならNUMBERのように各々指定する必要があります。この指定を行わないと、エラーが発生するので注意しましょう。
フィールド形式の詳細についてはこちらをご覧ください。
・Promiseで処理順序の制御
REST APIは非同期処理のため、APIの実行が完了する前に後続のコードが走ってしまうことになります。そのため、処理順序を制御することが必要になります。今回は、get_shareData関数の処理が完了してから、make_result関数の処理を実行するようにコードを書く必要があります。
非同期処理を上手に利用することは難しいですが、Promiseの基本的な活用方法を紹介するので、イメージを掴んで頂ければと思います。Promiseオブジェクトは、第一引数にresolve,第二引数にrejectを設定し、resolveした場合にはthenの処理が、rejectした場合にはcatchの処理が走ることになります。第二引数のrejectの設定は任意になります。今回はresolveのみ記述しています。
get_shareData関数内で、各配列変数への要素追加の処理が完了したらresolveとします。2.のコードに以下のようにPromiseの処理を追加します。
function get_shareData() {
return new Promise(function(resolve) {
kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body,
function(resp) {
resp.records.forEach(function(record) {
const memTable = record.メンバー.value;
for (var t = 0; t < memTable.length; t++) {
shareMem.push(memTable[t].value.氏名.value);
shareDep.push(memTable[t].value.部署.value);
shareMail.push(memTable[t].value.メールアドレス.value);
sharePart.push(memTable[t].value.役割.value);
}
resolve();
});
});
});
}
そして、thenの処理にmake_result関数を入れます。これで、各々の配列に取得した要素が追加された後に共有先テーブルのデータを更新できるようになります。
get_shareData().then(function() {
make_result();
});
実装したコード全文は以下になります。
(() => {
'use strict';
kintone.events.on([ 'app.record.create.change.開始日時', 'app.record.edit.change.開始日時'], (event) => {
const shareMem = [];
const shareDep = [];
const shareMail = [];
const sharePart = [];
const record = event.record;
const proName = record.プロジェクト名.value;
const body = {
'app': ”アプリID”,
'query': 'プロジェクト名 = "' + proName + '"',
'fields': ['メンバー']
};
function get_shareData() {
return new Promise(function (resolve) {
kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body, function (resp) {
resp.records.forEach(function (record) {
const memTable = record.メンバー.value;
for (var t = 0; t < memTable.length; t++) {
shareMem.push(memTable[t].value.氏名.value);
shareDep.push(memTable[t].value.部署.value);
shareMail.push(memTable[t].value.メールアドレス.value);
sharePart.push(memTable[t].value.役割.value);
}
resolve();
});
});
});
}
function make_result() {
const record = kintone.app.record.get().record;
const shareTable = record.共有先.value;
while (shareTable.length > 0) {
shareTable.splice(0, 1);
}
for (var i = 0; i <= shareMem.length - 1; i++) {
shareTable.push({
value: {
"共有者": {
value: shareMem[i],
type: "SINGLE_LINE_TEXT"
},
"部署": {
value: shareDep[i],
type: "DROP_DOWN"
},
"メールアドレス": {
value: shareMail[i],
type: "LINK"
},
"役割": {
value: sharePart[i],
type: "SINGLE_LINE_TEXT"
},
"連絡確認": {
value: [],
type: "CHECK_BOX"
}
}
});
}
kintone.app.record.set({
record: record
});
}
get_shareData().then(function () {
make_result();
});
return event;
});
})();
まとめ
以上、Java Scriptを用いて別アプリからデータを取得する方法を紹介しました。
非同期処理に関する制御とREST APIに関する知識を深めて、複雑なカスタマイズにも挑戦してみましょう!!
