現在の作業者をユーザーフィールドに表示させる。@もみじ様

同じ題名「現在の作業者をユーザー選択フィールドに表示させる」
という投稿をして
もみじ様より下記のプログラム内容の回答をいただきましたが
返信しようと思ったのですが操作を間違い、投稿がクローズされており
もみじ様に質問できなかった為
もう一度投稿いたしました。(メンションとかも出来なくて)
この方法で質問が届くかは不明ですが投稿いたします。
<質問その1>
どうして下記のソートという動きをさせているのか教えてもらいたいです。
順番の違いは無視して比較する為と書かれてますが
その意味がわかりませんでした。順番の違いとは?
また、それぞれのオブジェクトにuser.codeは1つだけではないのでしょうか?
複数存在する事もあるのでしょうか?
よろしくお願いします。
↓↓↓
// [作業者]と[ユーザー選択]のログイン名だけ取り出してソート(順番の違いは無視して比較するため)
const assigneeCodes = processAssignee.map(user => user.code).sort();
const userSelectionCodes = userSelection.map(user => user.code).sort();

<質問その2>
作業者の情報を’GET’で取得するのは間違いでしょうか?
または、プロセス管理の情報を取得するとか?/ja/kintone/docs/rest-api/apps/settings/get-process-management-settings/
このリンクは、読んでも私は理解できなかったのですが・・・。

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

実行したコードをコピー&ペーストしましょう

(() => {
    'use strict';
  
    // レコード詳細画面が表示されたときに処理開始
    kintone.events.on('app.record.detail.show', async (event) => {
      const record = event.record;
      const processAssignee = record['作業者'].value;
      const userSelection = record['ユーザー選択'].value;
        
      // [作業者]と[ユーザー選択]のログイン名だけ取り出してソート(順番の違いは無視して比較するため)
      const assigneeCodes = processAssignee.map(user => user.code).sort();
      const userSelectionCodes = userSelection.map(user => user.code).sort();
  
      // [作業者]と[ユーザー選択]のログイン名が完全に一致しているかどうかを判定
      const isSame = assigneeCodes.length === userSelectionCodes.length &&
                     assigneeCodes.every((code, index) => code === userSelectionCodes[index]);
  
      // すでに一致している場合は、無駄な更新をしないために処理を中止
      if (isSame) {
        return event;
      }
  
      // [作業者]の情報を kintone.api での更新に使える形式に変換
      const userList = processAssignee.map(user => ({ code: user.code }));
  
      try {
        // 1件のレコードを更新する REST API を実行
        await kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
          app: kintone.app.getId(), // 現在のアプリID
          id: event.recordId, // 現在のレコードID
          record: {
            'ユーザー選択': {
              value: userList // [ユーザー選択]を[作業者]と同じ内容に更新
            }
          }
        });
  
        // リロードして、画面に[ユーザー選択]の更新を反映
        location.reload();
      } catch (error) {
        // REST API 実行後にエラーが出たらコンソールに出力
        console.error(error);
      }
  
      return event;
    });
  
  })();

@inobe のように書けばできます。

kintoneヘルプで、作業者ユーザー選択について調べれば分かります。

例えば、下図のような状況なら
ユーザー選択と作業者は Administrator と user の順番は違うが
同じ二人がいるから同値と見做すということです。

要はユーザー選択と作業者の値を順列ではなく組み合わせで比較します。

HTTPメソッドが GET の REST API は幾つもありますが
1件のレコードを取得するのことですか?

これを使ってもできるけど、記述が無駄に複雑化するうえ
リクエスト数を浪費するから、やる意味がありません。

それはプロセス管理の設定画面の設定値を取得するものであって
レコードの作業者やステータスの値とは無関係です。

もみじ様
早速回答ありがとうございます。
>書き込み欄に@もみじでメンションできるという事ですね。
>複数存在する事を理解しました。
(運用で作業者複数人のパターンをあまり使用しなかったので失念してました。)
>組み合わせで比較するという考え方も理解しました。

さらに質問ですが
// [作業者]の情報を kintone.api での更新に使える形式に変換
const userList = processAssignee.map(user => ({ code: user.code }));
の(user => ({ code: user.code }))は、変換するのはこういう書き方だという風に
公式のように丸覚えする方がいいですか?
record[‘ユーザー選択’].value[0]=に代入するのではダメなのでしょうか?
コンソールで見ると作業者はキーと値の組み合わせで
value:Array(1)
0:{cord:‘000333’,name:‘tuki’}となってますが
その「cord:‘000333’」の000333部分にuser.codeが入ると考えて
nameに関しては何も指示してませんが
cordに紐づいてる値がname:'tuki’のtuki部分に自動で割り当てられるという事でしょうか?
チンプンカンプンの事を聞いているかもしれませんが
オブジェクトの値の操作がいまいち理解出来てません。

違います。私へのメンションなら @Maple になります。

作業者の人数は不定だから、その書き方だと添字を何番まで書けばいいのかが不明です。
作業者が何人だろうと対応できる map() を使うべきです。

値を登録、または更新するときで、ユーザー選択の所を見れば分かりますが
指定する必要があるのは code だけで、name は不要です。

もみじ様
教えていただいたプログラムで
前半の作業者とユーザー選択の比較の部分を一旦なしにして
単純に作業者の情報を取得して
ユーザー選択フィールドに書き込むだけの動きをさせる場合
作業者情報を取得してPUTする部分だけを使うと
PUT情報が正しくなく
API呼び出しに失敗します。
前半部分の作業者とユーザー選択の比較は無駄な作業をしない為の
一工夫だと思っていたのですが、そうではなく、必須になってくるのでしょうか?
以下前半部分を省略してエラーがでたプログラムです。
ユーザー選択フィールドに書き込む為の「作業者コード」は
正常に動くプログラムと変わらない値が入っています。
jsを始めたばかりで試行錯誤しており、立て続けに質問ばかりですみません。

(() => {
    'use strict';
  
    const Event = [
      'app.record.detail.show',
    ];  
    kintone.events.on(Event, async (event) => {
      const record = event.record;
      const operation = record['作業者'].value;
      const user = record['ユーザー選択'].value;

      console.log(record);
      console.log('作業者',operation);
      console.log('ユーザー選択',user); 
      
  
        // 作業者情報の取得
        const userlist = operation.map(user => ({cord:user.code}));
        console.log('作業者コード',userlist);
        try {
            // 1件のレコードを更新する REST API を実行
            await kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
              app: kintone.app.getId(), // 現在のアプリID
              id: event.recordId, // 現在のレコードID
              record: {
                'ユーザー選択': {
                  value: userlist // [ユーザー選択]を[作業者]と同じ内容に更新
                }
              }
            }); 
            // リロードして、画面に[ユーザー選択]の更新を反映
            location.reload();
    
        }catch(error){
          console.error('API呼び出しに失敗しました:', error);
        }
        return event;

          });
 
  })();

単に此処で codecord と書いてるのが駄目なだけです。

無駄な更新をしないための条件分岐は必須です。
location.reload() でリロードすると、また app.record.detail.show イベントが発火し
同じ処理が再実行されるため、条件分岐が無ければ無限ループを起こします。

コードを正しく貼れてないので以下を参照してください。

1 Like

もみじ様

回答ありがとうございます。
確かに、無限ループになります。
かといってリロードが無ければ
編集保存するたびにエラーメッセージが出ます。
イベントが詳細画面っていうのが、
やっかいなのかなぁと感じました。
教えていただいたプログラムは
起りうる事象(リクエスト数や無限ループ・無駄な処理)
を考慮してこれで1つの作品
のように完成してるんですね。
今回一つ一つひも解いて解説していただき
ありがとうございました。

1 Like

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。