保存実行前イベントで別アプリの値を取得し設定する方法について

お世話になります。

保存実行前イベントで3つの別アプリからデータを取得し値を書き変えようとしているのですが、変更が反映されるところと反映されないところがあります。

レコード登録時に連番を自動採番号する処理も動いていて、eventをreturnするタイミングを誤っているのだと思いますが、どのようにしたらうまく全てが反映されるのか、ご教授いただきたいです。

 

/* レコード追加画面の保存実行前のイベント */
/* レコード一覧画面のインライン編集の保存実行前イベント */
/* レコード編集画面の保存実行前のイベント */
var eventsShow2 = [‘app.record.create.submit’, ‘app.record.edit.submit’, ‘app.record.index.edit.submit’];
kintone.events.on(eventsShow2, function(event) {
var record = event.record;
var params = {
app: 15, // 別アプリA
query: ‘AAA ="’ + record[‘AAA’].value + ‘"’
};
kintone.api(‘/k/v1/records’, ‘GET’, params, function(resp) {
// 検索パラメータ
if (resp.records.length > 0) {
record[‘aaa’].value = resp.records[0][‘aaa’].value; ←これは反映される
}

// 検索パラメータ
var params2 = {
app: 22, // 別アプリB
query: ‘BBB ="’ + record[‘BBB’].value + ‘"’
};
kintone.api(‘/k/v1/records’, ‘GET’, params2, function(resp) {
if (resp.records.length > 0) {
record[‘bbb’].value = resp.records[0][‘bbb’].value; ←反映さない
}

// 検索パラメータ
var params3 = {
app: 24, // 別アプリC
query: ‘CCC ="’ + record[‘CCC’].value + ‘"’,
};
kintone.api(‘/k/v1/records’, ‘GET’, params3, function(resp) {
if (resp.records.length > 0) {
record[‘ccc’].value = resp.records[0][‘ccc’].value; ←反映さない
}

// アプリC取得エラー時
}, function(resp) {
// エラーの場合はメッセージを表示する
var errmsg = ‘エラーが発生しました。’;
// レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
if (resp.message !== undefined) {
errmsg += ‘’ + resp.message;
}
alert(errmsg);
});

// アプリB取得エラー時
}, function(resp) {
// エラーの場合はメッセージを表示する
var errmsg = ‘エラーが発生しました。’;
// レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
if (resp.message !== undefined) {
errmsg += ‘’ + resp.message;
}
alert(errmsg);
});

// アプリA取得エラー時
}, function(resp) {
// エラーの場合はメッセージを表示する
var errmsg = ‘エラーが発生しました。’;
// レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
if (resp.message !== undefined) {
errmsg += ‘’ + resp.message;
}
alert(errmsg);
});

// 連番
// クエリ文の設定
var query = {
“app”: kintone.app.getId(),
“query”: ‘年月日 = "’ + record[‘年月日’].value + ‘" order by 連番 desc limit 1’,
};
//設定された日付から最新の番号を取得する
return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, query).then(function(resp) {
var autoNo = ‘’;
var records = resp.records;

// 対象レコードがあった場合
if (records.length > 0) {
var rec = records[0];
var renban = rec[‘連番’].value;
var num = parseInt(renban, 10) + 1;
autoNo = ( ‘000’ + num ).slice( -3 );
// 対象レコードがなかった場合
} else {
autoNo = ‘001’;
}
// 連番を設定
event.record[‘連番’].value = autoNo; ←これは反映される

return event;
}).catch(function(e) {
alert("レコードの取得でエラーが発生しました getAutoNo - error: " + e.message);
return false;
});
}

return event;
});

 

よろしくお願いいたします。

古川さん

kintone.api は、非同期処理なので、各処理を連携しないと、各APIの応答が帰ってくる前にイベント処理が終了します。

このような場合は、Promise の then メソッドで連携するのが便利です。

Promise に関しては、Promise 関連 のリンクを読んでみてください。

then の連携サンプルは適当なものが見当たりませんでしたので、切り貼りしてみました。

内容は、検証してください。

各アプリの先頭行しか使わないのなら、limit 1 指定をしたほうが良いと思われます。

また各アプリの取得レコード数が0の場合の処理も検討したほうがいいと思います。

その辺は見直してください。

 

(function() {
"use strict";

/* レコード追加画面の保存実行前のイベント */
/* レコード一覧画面のインライン編集の保存実行前イベント */
/* レコード編集画面の保存実行前のイベント */
var eventsShow2 = ['app.record.create.submit', 'app.record.edit.submit', 'app.record.index.edit.submit'];
kintone.events.on(eventsShow2, function(event) {
var record = event.record;

// 検索パラメータ
var params = {
app: 15, // 別アプリA
query: 'AAA ="' + record['AAA'].value + '"'
};
var appName = "別アプリA";
return kintone.api('/k/v1/records', 'GET', params).then(function(resp) {
if (resp.records.length > 0) {
record['aaa'].value = resp.records[0]['aaa'].value;
}

// 検索パラメータ
var params2 = {
app: 22, // 別アプリB
query: 'BBB ="' + record['BBB'].value + '"'
};
appName = "別アプリB";
return kintone.api('/k/v1/records', 'GET', params2);
}).then(function(resp){
if (resp.records.length > 0) {
record['bbb'].value = resp.records[0]['bbb'].value;
}

// 検索パラメータ
var params3 = {
app: 24, // 別アプリC
query: 'CCC ="' + record['CCC'].value + '"',
};
appName = "別アプリC";
return kintone.api('/k/v1/records', 'GET', params3);
}).then(function(resp){
if (resp.records.length > 0) {
record['ccc'].value = resp.records[0]['ccc'].value;
}

// 枝番
// クエリ文の設定
var query = {
"app": kintone.app.getId(),
"query": '年月日 = "' + record['年月日'].value + '" order by 連番 desc limit 1',
};
appName = "getAutoNo - error";
//設定された日付から最新の番号を取得する
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', query);
}).then(function(resp){
var autoNo = '';
var records = resp.records;
// 対象レコードがあった場合
if (records.length > 0) {
var rec = records[0];
var renban = rec['連番'].value;
var num = parseInt(renban, 10) + 1;
autoNo = ('000' + num).slice(-3);
// 対象レコードがなかった場合
} else {
autoNo = '001';
}
// 連番を設定
record['連番'].value = autoNo;
return event;
}).catch(function(e) {
event.error = "レコードの取得でエラーが発生しました " + appName + ": " + e.message;
return event;
});
});

})();

rex0220さん

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

どうもありがとうございました。上手くいきました!

非同期である辺りが関係しているのかな?とは思ってpromiseも利用してみたりもしたのですが、上手くいかなかったので・・・。

きっと書き方が悪かったのだと思います・・。

あと、追加ですいません。

サブテーブル値も同様に実装したのですが、1レコード目しか反映されませんでした。

ループの中でreturnしているからだと思うのですが、良い方法はあるのでしょうか?

 (function() {
“use strict”;

/* レコード追加画面の保存実行前のイベント */
/* レコード一覧画面のインライン編集の保存実行前イベント */
/* レコード編集画面の保存実行前のイベント */
var eventsShow2 = [‘app.record.create.submit’, ‘app.record.edit.submit’, ‘app.record.index.edit.submit’];
kintone.events.on(eventsShow2, function(event) {
var record = event.record;

  var length = record[‘サブテーブル’].value.length;
for (var i = 0; i < length; i++) {
var tblVal = record[‘サブテーブル’].value[i].value;

// 検索パラメータ
var params = {
app: 15, // 別アプリA
query: ‘AAA ="’ + tblVal[‘AAA’].value + ‘"’
};
var appName = “別アプリA”;
return kintone.api(‘/k/v1/records’, ‘GET’, params).then(function(resp) {
if (resp.records.length > 0) {
tblVal[‘aaa’].value = resp.records[0][‘aaa’].value;
}

// 検索パラメータ
var params2 = {
app: 22, // 別アプリB
query: ‘BBB ="’ + tblVal[‘BBB’].value + ‘"’
};
appName = “別アプリB”;
return kintone.api(‘/k/v1/records’, ‘GET’, params2);
}).then(function(resp){
if (resp.records.length > 0) {
tblVal[‘bbb’].value = resp.records[0][‘bbb’].value;
}

// 検索パラメータ
var params3 = {
app: 24, // 別アプリC
query: ‘CCC ="’ + tblVal[‘CCC’].value + ‘"’,
};
appName = “別アプリC”;
return kintone.api(‘/k/v1/records’, ‘GET’, params3);
}).then(function(resp){
if (resp.records.length > 0) {
tblVal[‘ccc’].value = resp.records[0][‘ccc’].value;
}

// 連番
// クエリ文の設定
var query = {
“app”: kintone.app.getId(),
“query”: ‘年月日 = "’ + tblVal[‘年月日’].value + ‘" order by 連番 desc limit 1’,
};
appName = “getAutoNo - error”;
//設定された日付から最新の番号を取得する
return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, query);
}).then(function(resp){
var autoNo = ‘’;
var records = resp.records;
// 対象レコードがあった場合
if (records.length > 0) {
var rec = records[0];
var renban = rec[‘連番’].value;
var num = parseInt(renban, 10) + 1;
autoNo = (‘000’ + num).slice(-3);
// 対象レコードがなかった場合
} else {
autoNo = ‘001’;
}
// 連番を設定
tblVal[‘連番’].value = autoNo;
  event.error = "レコードの取得でエラーが発生しました " + appName + ": " + e.message;
return event;
});
}
return event;
});

})();

  

よろしくお願いいたします。

 

>サブテーブル値も同様に実装したのですが、1レコード目しか反映されませんでした。
>ループの中でreturnしているからだと思うのですが、良い方法はあるのでしょうか?

このような場合は、ループではなく再帰呼び出しを行いましょう。

ただし、処理内容からすると、サブテーブル内にルックアップを複数配置して、
レコード更新時に、「ルックアップの取得を自動で行う」と同様な気がします。

アプリ構成を再検討されてはいかがでしょうか?

rex0220さん

お世話になります。

ルックアップにしてみると上手くいきました。

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