見出し画像

テーブル内の入力データ重複チェック


やりたいこと

kintoneアプリのテーブル内データの商品名や担当者名の重複をチェックして警告メッセージを表示したい。
アプリ内のテーブルに同じ内容を入力させたくないという要望です。
本当は、テーブル内で選択済みのアイテムを新しい行では選択肢に表示されない様にしたいという要望でしたが、ドロップダウンの値を条件で絞り込みするのは難しいので、テーブル内の入力データが重複しているか検査して、警告メッセージを表示するという方向で対応しました。

デモ画面

デモ画面は、テーブル内に「商品A」と「商品B」が入力されている状態で、3行目に「商品A」や「商品B」を選択すると、重複エラーメッセージを表示しています。

デモ画面

実装方法

1.フォームの設定

フォームにテーブルを設置して、重複チェック対象のフィールドをテーブル内に設置します。
Javascriptコードで参照するのは、テーブルのフィールドコード(明細)と、重複チェック対象のフィールドコード(商品名)の2点のみです。
他のフィールドは、自由に追加、削除しても影響ありません。

テーブルの設定を開いて、フィールドコードを「明細」にします。

重複チェック対象のフィールド(商品名)の設定を開き、フィールドコードを「商品名」にします。
商品名をドロップダウンリストにしたのは、入力の表記揺れを防止するのに適しているからです。重複チェック対象フィールドは、文字列1行型でも数値型でも、日付型でもOKです。

なお、文字列1行、数値、日付型フィールドには「値の重複を禁止する」というオプション設定項目があります。この設定でテーブル内も重複チェックできるのか試してみたら、アプリ設定の更新で「テーブル内のフィールドは値の重複を禁止できません」とKintoneに怒られましたw
やはり、標準機能だけでは難しい様です。

2.Javascriptサンプルコード

初期設定の SUBTABLE_CODEにサブテーブルのフィールドコードをセット、PRODUCT_NAME_FIELDに重複入力をチェックしたいフィールドコードをセットします。
初期設定が完了したら、文字コードUTF-8で保存して下さい。
アプリ設定>設定>JavaScript / CSSでカスタマイズでアップロードすれば設定完了です。

/* テーブル内の入力データ重複チェック
 * Sample Program
 * Distributor: https://note.com/appgroup
 * Copyright (c) 2024 Application Utilization Study Group
 * Licensed under the MIT License
 ------------------------------------------------------------*/
(function() {
  'use strict';

  // 初期設定
  const SUBTABLE_CODE = '明細';
  const PRODUCT_NAME_FIELD = '商品名';

  kintone.events.on([
    'app.record.create.change.' + PRODUCT_NAME_FIELD,
    'app.record.edit.change.' + PRODUCT_NAME_FIELD
  ], function(event) {

    const record = event.record;
    const subtable = record[SUBTABLE_CODE]?.value;
    if (!subtable) {
      console.log('Subtable not found or empty.');
      return event;
    }

    const changedRow = event.changes.row;
    const changedRowIndex = subtable.findIndex(row => row === changedRow); // 行のインデックスを取得
    const changedProductName = changedRow.value[PRODUCT_NAME_FIELD]?.value;

    if (!changedProductName) {
      return event;
    }

    // 重複チェック: 自身の行を除外
    const duplicates = subtable.filter((row, index) => {
      // 現在の行の商品名を取得
      const rowProductName = row.value[PRODUCT_NAME_FIELD]?.value;

      // 比較条件:
      // 1. 商品名が一致している
      // 2. 現在変更中の行のインデックスではない
      const isDuplicate = rowProductName === changedProductName;
      const isNotSelfRow = index !== changedRowIndex;
      return isDuplicate && isNotSelfRow;
    });

    if (duplicates.length > 0) {
      const message = changedProductName + ' が重複しています。別のアイテムを選択してください。';
      event.error = message;
    }

    return event;
  });
})();

カスタマイズした感想

今回のカスタマイズで少し苦労したのは、テーブル内のデータ重複チェックのロジック(一番肝心な部分!)です。
比較対象データとその他の行データの重複チェックを行う部分で、比較対象データ自身を除外することを失念しており、1件目の入力でいきなりエラーメッセージが出るというバグが発生しました(汗)

この問題を回避するために、以下の判定を追加しました。

  // 比較条件:
  // 1. 商品名が一致している
  // 2. 現在変更中の行のインデックスではない
  const isDuplicate = rowProductName === changedProductName;
  const isNotSelfRow = index !== changedRowIndex;
  return isDuplicate && isNotSelfRow;

現在変更中の行(changedRowIndexで示される行)自体をチェック対象から除外しています。

サブテーブルのデータ制御は、行(row)プロパティを考慮して行う必要があるので、普通のフィールドを操作するよりも注意が必要ですね。


カスタマイズ例その2

公開したサンプルコードでは、警告メッセージは表示しても、警告を無視して登録できてしまうという問題があります。
以下のデモ画面2は、その問題に対処したカスタマイズ例です。

デモ画面2

テーブル内の重複禁止項目に重複入力が発生すると、重複警告メッセージを(見逃さない様に)画面中央に表示します。
警告メッセージを無視して保存ボタンクリックしても、再度重複チェックを行って保存できない様に制御しています。
工夫次第でこの様なカスタマイズも可能です。

自分ではカスタマイズが難しいという方のために、デモ画面2の仕様でカスタマイズしたアプリテンプレート(有償版)を準備しました。

アプリのテンプレートのダウンロードと設定方法については、以下の有料記事に記載しています。
本アプリテンプレートは、note有料記事の購読料金だけでご利用いただけますが、以下の注意事項にご留意ください。

【ご注意事項と免責事項】

  • 本アプリテンプレートは、Javascriptでカスタマイズされていますので、利用するには「kintoneスタンダードコース」以上の契約とkintoneシステム管理者権限が必要です。

  • 本アプリテンプレートは、PCデスクトップ版でのみ動作確認済です。

  • 本アプリテンプレートは1つのドメインでのみご利用ください。

  • 本アプリテンプレート購入後のサポートは行っていませんので、予めご承知おき下さい。

  • 本アプリテンプレートの導入で生じたいかなる損害にも、当方は一切の責任を負いません。自己責任でご利用ください。


ここから先は

1,190字 / 5画像 / 1ファイル

¥ 2,000

期間限定!Amazon Payで支払うと抽選で
Amazonギフトカード5,000円分が当たる

よろしければサポートお願いします! いただいたサポートは、note記事制作の活動費に使わせていただきます!