いつも大変お世話になっております。
ルックアップの紐付けフィールド、また、ルックアップよりコピーしたフィールドに値の変更がある場合、一覧画面・詳細画面表示時に最新の情報を取得して表示したいと思います。
https://developers.cybozu.com/ja/kintone-api/apprec-createjsapi.html#i-8
こちらのサンプルを参考にしましたが、以下の記述で再取得できませんでした。
・詳細画面表示時
record[‘ルックアップフィールド’][‘lookup’] = true
(record[‘ルックアップフィールド’][‘value’]値は、取得できています)
・一覧画面表示時
records[i].ルックアップフィールド.lookup = true;
(取得したレコード件数分、Loopさせて処理しています。
records[i].ルックアップフィールド.valueの値は、取得できています)
詳細編集画面を開いた時の「取得」ボタン押下時と同じ処理を、一覧画面・詳細画面表示前に行うには、「lookup = true」だけではできないのでしょうか?
hiroko5572 様
ラジカルブリッジの斎藤です。
記載いただいた「ルックアップの取得を自動で行う」
https://developers.cybozu.com/ja/kintone-api/apprec-createjsapi.html#i-8
は、レコード追加イベントまたはレコード編集イベントでのみ利用可能な機能となります。
上記ページには明確に記載されていませんが、確認してみたところ、
・レコード追加画面が表示された時のイベント
・レコード編集画面が表示された時のイベント
でのみ「lookup = true」が利用可能なようです。
(レコード編集画面の保存実行前イベント、レコード編集画面の保存実行前イベントでは効かなかった)
ですので、一覧画面・詳細画面表示時のルックアップ再取得は現状ではできないと思われます。
尚、JSからREST APIを使えば、無理くりできなくはないような気がしますが、未確認です。
斎藤 様
いつもお世話になっております。
ルックアップで取得する項目(コピーして取得する項目も含め)を更新する処理をREST APIで試しております。
よくkintoneのサンプルで出てくる、詳細画面で緯度と経度を更新するJSを参考にしましたが、ルックアップからコピーする項目でない項目は更新されていましたが、ルックアップからコピーする項目は更新されませんでした。
REST APIを使っても、ルックアップからコピーする項目の更新は、行えない仕様なのでしょうか?
また、一覧画面にて、REST APIにて更新が成功した場合に、1行毎ではなく、全行の更新が終わったタイミングで画面をリロードする方法がわかりませんでした。
一覧画面表示時の最後にlocation.reload(true)とすると、何度もリロードされてループしてしまいました。
hiroko5572 様
REST APIのドキュメント「レコード更新」の制限事項
https://developers.cybozu.com/ja/kintone-api/apprec-updateapi.html#i-3
を見ますと、
・ルックアップフィールドによって値が入力されるフィールド
は更新できないようです。
尚、更新時に「ルックアップで取得する項目」だけを設定して更新した場合、ルックアップでコピーされる項目には、ルックアップで取得する項目に紐付いたコピー元の値は自動的に入らないのでしょうか?(自分では試せてません)
また、一覧画面にて、REST APIにて更新が成功した場合に、1行毎ではなく、
全行の更新が終わったタイミングで画面をリロードする方法がわかりませんでした。
こちらをご参照ください。
https://cybozudev.zendesk.com/hc/communities/public/questions/201106790-kintone-api-k-v1-record-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
一覧画面表示時の最後にlocation.reload(true)とすると、何度もリロードされてループしてしまいました。
app.record.index.showイベントの最後で毎回location.reload(true)すると無限ループになってしまいますよね。
上記URLを参考に、全ての処理が確実に完了した後にリロードをかけるようにしてみてください。
斉藤様
いつもありがとうございます。
「更新時に「ルックアップで取得する項目」だけを設定して更新した場合、ルックアップでコピーされる項目には、ルックアップで取得する項目に紐付いたコピー元の値は自動的に入らないのでしょうか?(自分では試せてません)」
→こちらについては、ルックアップで取得する項目だけの更新で、紐付いた値も同時に更新されました。
(リロード処理が上手くいかないので、詳細画面を開いて更新されていることを確認しました)
https://cybozudev.zendesk.com/hc/communities/public/questions/201106790-kintone-api-k-v1-record-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
「上記URLを参考に、全ての処理が確実に完了した後にリロードをかけるようにしてみてください。
→すみません。ご指定のURLのどの部分がリロードの記述が分かりませんでした。教えてください。
hiroko5572 様
説明がわかりづらかったかもしれません。
REST APIにて更新が成功した場合に、1行毎ではなく、
全行の更新が終わったタイミングで
と書かれていましたが、「kintoneのサンプルで出てくる、詳細画面で緯度と経度を更新するJSを参考にしました」とのことですので、恐らく
https://developers.cybozu.com/ja/tutorial/sample10.html
のサンプルの114行目からの
// レコードを更新します
kintone.api(‘/k/v1/record’, ‘PUT’, objParam, function(resp){
// 成功時は画面をリロードします
location.reload(true);
}, function(resp) {
// エラー時はメッセージを表示して、処理を中断します
alert(‘error->’ + resp);
return;
});
を参考にされたのではないかと思いますが、
https://cybozudev.zendesk.com/hc/communities/public/questions/201106790-kintone-api-k-v1-record-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
に書かれている通り、kintone.api()は非同期メソッドです。ですので、これを使って1件1件更新するようなループを回しても、全件更新完了のタイミングはきちんと把握できません。
上記URLに書かれている通り、1件1件の登録ではなく、一括更新を行ってみてはいかがでしょうか?(一括更新は上限100件までなので注意が必要ですが)
もしくは、やはり上記URLに書かれている通り、XMLHttpRequestによる同期処理を使えば、1件1件ループで回しても全件更新完了を把握できます。
また、私も存じ上げていなかったのですが、上記URLで門屋 亮さんが書かれている通り、kintone.api()の非同期メソッドでも、jQuery.Deferredを使えば順番に処理を行うことができるようです。
いろいろなやり方がありますが、全件更新完了を把握するというのがまず大事で、その後リロード処理を行ってみてください。
斎藤 様
毎回ご指導ありがとうございます。
XMLHttpRequestによる同期処理でレコードの更新を行おうと思います。
https://cybozudev.zendesk.com/hc/communities/public/questions/200907434-JavaScript%E3%81%A7%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E8%A1%8C%E8%BF%BD%E5%8A%A0
こちらの記述を参考にさせていただいたのですが、どうしてもエラーが戻ってきます。
エラー内容、
statusText:520
responseText:不正なリクエストです。
このようなコードを記述しています。
var valAppUrl = kintone.api.url(‘/k/v1/records’);
var token = kintone.getRequestToken();
var objParam = {};
objParam[" REQUEST_TOKEN"] = token;
objParam[‘app’] = valAppId;
objParam[‘id’] = valRecordId;
objParam[‘record’] = {};
objParam[‘record’][‘lookup_field’] = {};
objParam[‘record’][‘lookup_field’][‘value’] = “更新テスト”;
xmlHttp = new XMLHttpRequest();
xmlHttp.open(‘POST’, valAppUrl, false);
xmlHttp.setRequestHeader(‘Content-Type’, ‘application/json’);
xmlHttp.setRequestHeader(‘X-Requested-With’, ‘XMLHttpRequest’);
xmlHttp.send(JSON.stringify(objParam));
デバッグすると、JSONの文字列はこのように展開されていました。
{
" REQUEST_TOKEN":“3b250515-4d55-4d71-a68e-09b6a3b207c6”,
“app”:“123”,
“id”:“456”,
“record”:
{“lookup_field”:
{“value”:“更新テスト”}
}
}
アプリID「app」、レコードID「id」は、
は、置き換えていますが正しい値が入っています。
知識不足でご迷惑をお掛けしておりますが、よろしくお願いいたします。
xmlHttp.open(‘POST’, valAppUrl, false);
↓
xmlHttp.open(‘PUT’, valAppUrl, false);
ですよね。
参考として書かせていただいたURLに掲載しているコードは、「登録」の文脈で書いたものですので、"POST"になっています。「更新」の場合は"PUT"と読み替えて下さい。
REST APIのドキュメントは読まれていますでしょうか?
■レコード登録
https://developers.cybozu.com/ja/kintone-api/apprec-createapi.html
■レコード更新
https://developers.cybozu.com/ja/kintone-api/apprec-updateapi.html
これらを見ると、登録が"POST"で更新が"PUT"であることがわかります。
また、「不正なリクエストです。」というエラーが出るようですが、1件更新しようとしていますか?それとも複数件一括更新しようとしていますか?
JSONでidを指定しているので1件ずつ処理されようとしていると思いますが、1件の場合は、掲載いただいたコードの内、
var valAppUrl = kintone.api.url(‘/k/v1/records’);
の部分は
var valAppUrl = kintone.api.url(‘/k/v1/record’);
となりまして、最後のrecordsは単数形のrecordになります。
逆に一括更新の場合は、上記のrecordsはそのままで、JSONの作り方が変わります。
更新のドキュメントの一括更新の部分を見ていただくと、以下のようになっています。
{
“app”: (アプリのID),
“records”: [
{ // 1件目のデータ
“id”: (更新するレコードのID),
“revision”: (更新するレコードのリビジョン),// 不要の場合は記載しない
“record”: {
“(フィールドコード)”: {
“value”: (フィールド値)
},
“(フィールドコード)”: {
“value”: (フィールド値)
},
:
}
},
{ // 2件目のデータ
“id”: (更新するレコードのID),
“revision”: (更新するレコードのリビジョン),// 不要の場合は記載しない
“record”: {
“(フィールドコード)”: {
“value”: (フィールド値)
},
“(フィールドコード)”: {
“value”: (フィールド値)
},
:
}
},
:
:
{ // n件目のデータ
:
}
]
}
いかがでしょうか?
ドキュメントもいろいろと横断的に見ないとわかりづらいと思いますし、単数形や複数形など微妙な違いに気づきにくいとは思いますが、サンプルコードと違うことをやる際は、まずはドキュメントを参照してみることをオススメいたします。
斎藤 様
ご丁寧にありがとうございます。
ご指摘の通り、エラーの原因は、1件更新であるのに、
var valAppUrl = kintone.api.url(‘/k/v1/records’);
としていたためです。
大変助かりました。
今回、ルックアップ先のアプリは、会社マスタの様な位置付けになります。
ルックアップフィールドそのものは、会社名で、コピーフィールドとして、住所や電話番号を取得して表示しています。
会社マスタに変更があった場合に、紐付いているアプリ側で表示する会社名・住所・電話番号を常に最新の状態で表示したいと思います。
そのため、紐付いているアプリの一覧表示のタイミングで、ルックアップの再取得を行おうと思いましたが、
毎回、一覧表示の度に処理が実行されてしてしまうので、会社マスタの更新があった場合のみ、紐付いているアプリのルックアップフィールドを更新するように変えました。
そこで、会社マスタ保存時のイベントで、
紐付いているアプリのルックアップフィールド(レコード番号をコピーフィールドで取得)が、
変更のあった会社マスタのレコード番号と、等しいレコードを複数件取得し、ループで回しながら、ルックアップフィールドの更新を1件ずつしようと考えました。
更新は成功しましたが、新たな問題が発生しました。
会社名変更前「AAA」
会社名変更後「BBB」
の保存ボタン押下時の処理(‘app.record.edit.submit’)で、
紐付いているアプリのルックアップフィールドを「BBB」に更新しようとすると、
「検索条件に一致するレコードはありません。」というエラーが発生します。
これは、会社マスタ側では、まだタイミング的に「AAA」なので、「BBB」という会社名は存在しない、という意味のエラーのような気がします。
この問題を解決する方法はございますでしょうか?
app.record.edit.submit 時は、まだ会社マスタの会社名がAAAのままですのでそのようなエラーが出てしまうのですよね。
保存後に表示される詳細画面表示時 app.record.detail.show のタイミングで実行してみてはいかがでしょうか?
その場合、詳細画面を表示する度に(変更が無くても)毎回更新されてしまいますので、事前に変更があるかどうかをチェックした上で必要に応じて更新を行うといったやり方があるかと思います。
斎藤 様
レコード更新のタイミングを詳細画面表示時に行うことで、ルックアップフィールド・コピーフィールドの情報を最新にすることができました。
変更がなくても詳細画面表示時に毎回更新されてしまうので、他アプリで表示する全項目に対して、変更があったかどうかを判断する必要が出てきますね。
お忙しいところ、どうもありがとうございました。