ReoGrid ReoGrid Web

JavaScriptスプレッドシートに「入力規則」を ― 不正なデータをセルの手前で止める

· unvell team
JavaScriptスプレッドシートに「入力規則」を ― 不正なデータをセルの手前で止める

条件付き書式の記事では、入力された値に応じてグリッド自身に色を塗らせました。今回は問題が入り込む前に止めます ― 数量は1〜100の整数だけ、ステータスはドロップダウンから選択、過去の納期には警告。すべて、タイプされた瞬間に拒否またはフラグされます。フォームフレームワークも、バリデーションのループも、「37行目を確認してください」という後始末も不要。ルールを一度宣言すれば、グリッドがセルの位置で守ってくれます。


データ検証(入力規則)とは

データ検証は、ユーザーがセルに入力できる値を制限する仕組みです。「この列は1〜100の整数のみ」というルールを付けておくと、すべての編集は書き込まれる前にチェックされます。不正な入力にはアラートが表示され、既定では入力自体が拒否されます。Excel ユーザーが長年頼ってきた「データ → データの入力規則」そのものが、ブラウザの canvas グリッドで動きます。

ReoGrid Web は v1.4.0 から、Excel のルールセットをフルにサポートします。

種類受け付けるもの
list固定の選択肢のいずれかステータスは Low / Medium / High のみ
whole / decimal比較条件を満たす数値数量は 1〜100 の between
date / time比較条件を満たす日付・時刻納期は >= TODAY()
textLength文字数が条件を満たすテキストコードは5文字以内
custom真を返す任意の数式=G2<D2(割引が単価未満)

ルールの作成setValidation)は Pro 機能です(料金)。ただし強制は Pro 限定ではありません。Pro で作成したルールも、xlsx ファイルから読み込んだルールも、無料の Lite でそのまま強制されます。詳しくは後述


いちばんシンプルなルール

setValidation で、範囲・単一セル・明示的な矩形にルールを付けます。

import { createReogrid } from '@reogrid/pro';

const { worksheet: ws } = createReogrid('#grid');

// 列全体:3択のドロップダウン
ws.range('B2:B100').setValidation({ type: 'list', options: ['Low', 'Medium', 'High'] });

// 単一セル:1〜100の整数
ws.cell('C2').setValidation({ type: 'whole', operator: 'between', value1: 1, value2: 100 });

パターンはこれだけです。あとはルールの種類と、どのくらい強く警告するかを選ぶだけ。


実例:不正な入力を弾く受注入力シート

典型的なケース ― 他人が入力するシート ― を作ってみましょう。6列に6種類のルール。命令的なバリデーションコードは1行もありません。これが完全なコードです。

import { createReogrid } from '@reogrid/pro';

const { worksheet: ws } = createReogrid('#grid');

ws.suspendRender(); // 初期構築をバッチ処理

// ── 列 ──
const HEADERS = ['Product', 'Priority', 'Qty (1–100)', 'Unit Price', 'Due Date', 'Code (≤5)'];
[120, 110, 110, 110, 120, 110].forEach((w, c) => { ws.column(c).width = w; });

HEADERS.forEach((h, c) => {
  ws.cell(0, c).setValue(h).setStyle({
    bold: true, backgroundColor: '#1e3a5f', color: '#e2e8f0', textAlign: 'center',
  });
});
ws.row(0).height = 30;

// ── H列の補助リスト ― Product ドロップダウンの参照元 ──
['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'].forEach((p, i) => {
  ws.setCellInput(i, 7, p);
});

// ── ルール1: Product ― 範囲を参照するドロップダウン ──
ws.range('A2:A13').setValidation({
  type: 'list', source: '=$H$1:$H$5',
  showInputMessage: true,
  inputTitle: 'Product', inputMessage: 'Pick a product from the dropdown.',
  errorMessage: 'Choose one of the listed products.',
});

// ── ルール2: Priority ― インライン選択肢のドロップダウン ──
ws.range('B2:B13').setValidation({ type: 'list', options: ['Low', 'Medium', 'High'] });

// ── ルール3: Qty ― 1〜100の整数 ──
ws.range('C2:C13').setValidation({
  type: 'whole', operator: 'between', value1: 1, value2: 100,
  showInputMessage: true,
  inputTitle: 'Quantity', inputMessage: 'Enter a whole number from 1 to 100.',
  errorTitle: 'Invalid quantity',
  errorMessage: 'Quantity must be a whole number between 1 and 100.',
});

// ── ルール4: Unit Price ― 正の小数 ──
ws.range('D2:D13').setValidation({
  type: 'decimal', operator: 'greaterThan', value1: 0,
  errorMessage: 'Unit price must be a positive number.',
});

// ── ルール5: Due Date ― 今日以降。ただし警告のみ ──
ws.range('E2:E13').setValidation({
  type: 'date', operator: 'greaterThanOrEqual', value1: '=TODAY()',
  alertStyle: 'warning',
  errorMessage: 'The due date is in the past.',
});

// ── ルール6: Code ― 5文字以内 ──
ws.range('F2:F13').setValidation({
  type: 'textLength', operator: 'lessThanOrEqual', value1: 5,
  errorMessage: 'Code must be 5 characters or fewer.',
});

ws.resumeRender();

Qty 列に 250 と入力するとアラートとともに弾かれます。Product セルをクリックすると、案内バブルとドロップダウンの矢印が現れます。Due Date に先週の日付を入れると警告は出ますが、通ります ― このルールは助言(warning)だからです。6列に6つの宣言。動くものはデータ検証デモで試せます。

いくつかポイントを見ていきましょう。


list ― ドロップダウンの2つの作り方

list ルールはセルにドロップダウンの矢印を表示し、入力を選択肢に制限します。選択肢はインラインの options か、同一シート内の source 範囲のどちらかで与えます(両方は指定できません)。

// インライン:選択肢はルールの中に持つ
ws.range('B2:B100').setValidation({
  type: 'list',
  options: ['Draft', 'In review', 'Done'],
});

// 範囲参照:選択肢はセルに持ち、使用時に解決される
ws.range('A2:A100').setValidation({
  type: 'list',
  source: '=$H$1:$H$5',
  showDropdown: true, // ドロップダウン矢印の表示 ― 既定は true
});

選択肢そのものがデータであるなら source 形式が正解です。H1:H5 を編集すれば、ルールに手を入れることなく全ドロップダウンに反映されます。

ドロップダウンのセルタイプとの違いは? セルタイプはセルの描画と編集方法を変えるもの。list ルールはセルが受け付ける値を制約するもので、貼り付けや直接入力にも効き、xlsx を経由しても Excel ネイティブのドロップダウンとして生き残ります。


比較ルール ― whole・decimal・date・time・textLength

5つの比較タイプは共通の形をしています。type が値の種別を、operator が判定を、value1(2値の演算子では value2 も)が境界を決めます。リテラルでも数式文字列でもかまいません。

// 1〜100の整数
ws.range('C2:C100').setValidation({
  type: 'whole', operator: 'between', value1: 1, value2: 100,
});

// 正の小数
ws.range('D2:D100').setValidation({ type: 'decimal', operator: 'greaterThan', value1: 0 });

// 今日以降の日付 ― 境界に数式を使う
ws.range('E2:E100').setValidation({
  type: 'date', operator: 'greaterThanOrEqual', value1: '=TODAY()',
});

// 5文字以内のテキスト
ws.range('F2:F100').setValidation({ type: 'textLength', operator: 'lessThanOrEqual', value1: 5 });

演算子は Excel と1対1で対応します:equalnotEqualgreaterThanlessThangreaterThanOrEquallessThanOrEqualbetweennotBetween。2値の演算子(between / notBetween)は value1value2 の両方を読み、それ以外は value1 のみを使います。

=TODAY() のような数式の境界はルール実行時に再評価されるので、「過去の日付は不可」のルールは明日になっても手を入れずに正しく動き続けます。


custom ― 比較だけでは足りないとき

比較ルールが見られるのは、入力されようとしている値だけです。他のセルと突き合わせて検証する ― 割引は単価未満、終了日は開始日より後 ― には数式を書きます。真と評価される数式なら何でも合格です。数式は範囲の左上のセルを基準に書けば、ReoGrid が残りのセルへ相対参照をオフセットしてくれます。条件付き書式の expression ルールと同じ相対参照のセマンティクスです。

// 同じ行で G は D より小さいこと
ws.range('G2:G100').setValidation({
  type: 'custom',
  formula: '=G2<D2',   // G3<D3、G4<D4、… と範囲を下って評価される
  errorMessage: 'Discount must be below the unit price.',
});

数式エンジンが評価できるものなら何でも使えるので、=AND(G2>0, G2<D2*0.5) のような組み合わせも可能です。


アラートスタイル ― stop・warning・information

すべてのルールが強制拒否に値するわけではありません。alertStyle でルールの「強さ」を選びます。

スタイルメッセージ表示値をブロック
'stop'(既定)
'warning'
'information'

実際に入力を拒否するのは 'stop' だけです。'warning''information' はメッセージを表示しつつ値を通します ― 実例の「過去の納期」チェックのように、先週の受注を後から入力する正当なケースがあり得る「本当によろしいですか?」系のルールに適しています。


入力時メッセージ ― タイプされる前に案内する

エラーアラートはミスの後に発火しますが、入力時メッセージはミスを未然に防ぎます。showInputMessage: true を付けると、セルを選択した時点で案内バブルが表示されます。

ws.range('C2:C100').setValidation({
  type: 'whole', operator: 'between', value1: 1, value2: 100,
  showInputMessage: true,
  inputTitle: 'Quantity',
  inputMessage: 'Enter a whole number from 1 to 100.',
  errorTitle: 'Invalid quantity',
  errorMessage: 'Quantity must be a whole number between 1 and 100.',
});

1つのルールが、フォーカス時には自らを説明し、エラー時には自らを守るようになりました。制限なしでヒントだけ出したい場合は、{ type: 'any' } に入力時メッセージを付けます。

挙動を仕上げる基本オプションが2つ。ignoreBlank(既定 true)は空の入力を通すので、検証付きの列が入力途中の行と衝突しません。showErrorMessage(既定 true)をオフにすると、メッセージなしで静かに拒否します。


コードからルールを読む・検証する

ルールはキー入力のためだけのものではありません。ルールを列挙し、既存のデータをプログラムから監査できます ― ワークブックを読み込んだ後や、サーバーへ送信する前などに。

ws.getValidations();          // シート上の全ルール: ValidationEntry[]
ws.getValidationAt(row, col); // セルをカバーするルール(なければ null)
ws.validate();                // 現在の値をルールに照らしてチェック

ルールを外すには ws.range('C2:C100').removeValidation()ws.removeValidation(r1, c1, r2, c2)、シート全体なら ws.clearValidations()

この読み取り・検証系の3つは Lite で動きます ― ここでティアの境界線の話になります。


Lite はどこまで、Pro はどこから

操作Lite(無料)Pro
xlsx インポート、結合、罫線、表示形式
ルールの強制(入力チェック・ドロップダウン表示)
ルールの読み取り(getValidationsgetValidationAtvalidate
ルールの作成setValidation
組み込み関数(SUMCOUNTIF など)
xlsx エクスポート(saveAsXlsx

この分担に注目してください。無料ティアは検証付きワークブックをただ表示するのではなく、中のルールを強制します。Excel や Pro で作った xlsx テンプレートを配布して Lite で開けば、ドロップダウンも案内も拒否も、そのままユーザーに届きます。Pro が必要になるのは、コードから新しいルールを書くときです。


xlsx ラウンドトリップ

ルールは標準の <dataValidations> 要素としてシリアライズされるので、双方向の往復に耐えます。グリッドでルールを作って saveAsXlsx でエクスポートすれば、Excel の「データ → データの入力規則」に同じドロップダウン・境界・案内・アラートが現れます。同僚が Excel で作ったワークブックをインポートすれば、そのルールがブラウザで強制されます。ReoGrid JSON 経由でも同様なので、検証付きテンプレートは自前のストレージ層も生き残ります。


まとめ

データ検証は、「〜だけ入力してください」というコメントを、グリッドが強制するルールに変えます。ドロップダウンの list、数値・日付・文字数の5つの比較タイプ、セル間ロジックの custom 数式 ― それぞれに入力時の案内、3段階のアラート、そして完全な Excel ラウンドトリップが付きます。強制は無料ティアでも動くので、検証付きテンプレートはどこで開かれてもデータを守ります。

データ検証デモで試してみてください ― どの列も違うものを弾きます。API 全体はデータ検証のドキュメントへ。入力された後の値に応じてセルをスタイリングする話は条件付き書式の記事、セルのに操作 UI を置く話はセルタイプの記事へ。

ReoGrid Web を試してみる

React/Vue 向けの Canvas ベース Excel 互換スプレッドシートコンポーネント。 Lite は無料 — npm install 一発で始められます。

関連記事

ニュースレター

開発の最新情報をお届けします

新しいリリース・機能追加・お知らせをいち早く受け取るには、
メーリングリストにご登録ください。