Excel のユーザーフォームをデータベースのインターフェースとして使用する際の注意点などを述べます.ユーザーフォームにはデータを入力するためのコントロール,選択肢から選択させるためのコントロール,動作を記述するためのコントロールなどを配置します.それぞれの特徴を把握し,ユーザーにとって使いやすくかつ堅牢なシステムを構築する手助けとなれば幸いです.
- 選択肢としてのオプションボタン,チェックボックス,リストボックスおよびコンボボックス
- テキストボックス
- コマンドボタン
- パスワード入力
1. 選択肢としてのオプションボタン,チェックボックス,リストボックス及びコンボボックス
1.1 コントロールを決める際の制約条件
ユーザーフォーム上に選択肢を示す場合にどのコントロールを用いるかは状況に応じて決める必要があります.選択肢が一択なのか複数選択なのかが最も重要な制約条件です.次に選択肢を提示する面積が確保されているか否か,最後に選択肢をユーザー自身が追加する必要があるか否か,逆に言えば管理者が選択肢を定義しておく必要があるか否かでどのコントロールを用いるかが決まります.
1.2 選択肢は一択か複数か
選択肢が一択である場合はオプションボタンをフレーム内に配置するか,コンボボックスを配置するかします.複数選択が必要であればチェックボックスをフレーム内に配置するか,リストボックスを配置するかします.ここで注意が必要ですが,複数選択を許可するということは値が一意に決まらないということであり,データベースのレコードを特定するためのキーの候補とはなり得ないということでもあります.もっと言えば,原子値ではなく配列ですので第一正規形を満たしません.EXCEL でそこまで考慮する必要があるかは分かりませんが,一応知っておく必要はあると思います.
1.3 配置するための面積は十分か
選択肢を全て提示するのに必要な面積が十分に確保されていればフレーム内にオプションボタンを配置するか,チェックボックスを配置します.逆に面積が十分に確保できない場合はリストボックスまたはコンボボックスを配置します.複数選択が必要なのに十分な面積が確保できない場合は,他のコントロールとの配置のバランスを変更するか,ユーザーフォームの面積を拡張する必要があります.
1.4 選択項目は運用中に増加するか
選択項目をユーザー自身に追加させる必要があるというのは,データベースの管理上問題があります.それはマスターテーブルにない項目をトランザクションテーブルに追加することに他ならず,参照整合性制約に違反します.少なくとも別のフォームでマスターテーブルに項目を追加する仕様とし,コンボボックスから新たに項目を追加するのを禁じた方がよいと思います.とはいえ実装ではなかなかそうも行かないのが現状です.
コントロール | 複数選択 | 一択 | 面積に制約 | アイテム追加必要 |
オプションボタン | ✔ | |||
チェックボックス | ✔ | |||
リストボックス | ✔ | ✔ | ✔ | ✔ |
コンボボックス | ✔ | ✔ | ✔ |
2. テキストボックス
テキストボックスには様々なデータを入力できます.自由であるかゆえに最も扱いの難しいコントロールでもあります.考えられる入力値として代表的なものは以下の様なものではないでしょうか.
- 人名
- 生年月日
- 性別
- 組織名・部署名
- 郵便番号
- 住所
- ある属性の有無
これらの入力値はデータ型として以下のように分類できます.
2.1 文字列型
人名,組織名・部署名,郵便番号,住所などのテキストデータ.郵便番号を数値型に含めるのは間違いです.先頭に 0 があった場合,数値型では削られてしまいます.同様に電話番号も数値型としてはいけません.これらは数値を使ってはいますが,文字列型として扱うべきであり,また文字数が決まっているため入力値のチェックの際には必ず文字数をチェックすべきです.
2.2 日付型
生年月日や入社年月日などの日付のデータ.Excel では 1900 年 1 月 1 日以降の日付型を扱えます.DATEDIFF 関数などに多少のバグはあるのですが,通常の使用で問題になることはあまりないでしょう.
2.3 数値型
数値型として扱うのは給与や財務など計算の必要なデータ,実験の測定値,長さや質量などの物理量などです.さらに細かく分類すると整数型や小数型,通貨型などいろいろあります.特に小数型は必要な精度に応じて適切なデータ型を選択する必要があります.
2.4 ブール型
ある疾病の有無や既往の有無,喫煙や飲酒の有無など Yes か No で答えられるものについてはブール型で記述します.しかしブール型はテキストボックスよりもチェックボックスで使用した方が良いように思います.
3. コマンドボタン
コマンドボタンにはクリックイベントにより意図する動作をプロシージャとして記述します.意図する動作とはデータベースからレコードを検索して表示すること,データベースに存在するレコードを修正すること,データベースにないレコードを新規に登録すること,データベースのレコードを削除することです.それぞれ SELECT, UPDATE, INSERT, DELETE に該当します.
- レコードを検索する
- レコードを修正する
- レコードを登録する
- 入力値のチェック
- レコードを削除する
3.1 レコードを検索する
データベースに存在するレコードを検索して表示するには検索条件を指定する必要があります.名前,生年月日,年齢,性別など検索に必要な条件をテキストボックスなりリストボックスなりに入力させ,オートフィルターや Find メソッドを使用して検索し,得られた結果を表示するコードを記述し,コマンドボタンのクリックイベントに登録します.結果を表示するコントロールはリストボックスが良いでしょう.おそらく複数の結果が得られる筈ですから.検索方法には全文一致,前方一致,後方一致,中間一致があり,状況に応じて選択します.結果が得られない場合はエラーが発生するため,エラーをキャッチして適切なアラートを表示させたほうが良いでしょう.
3.2 レコードを修正する
データベースに存在するレコードを修正するには,前述の方法で得られたレコードをテキストボックスやオプションボタン,リストボックスなど編集可能なコントロールに移す必要があります.そのためのコマンドボタンを用意したほうが良いでしょう.必要な項目を訂正したらレコードをデータベースに書き戻す処理が必要になります.修正ボタンを配置し,コードを記述してクリックイベントに登録します.
3.3 レコードを登録する
検索結果が存在しない場合とは,レコードを新規に登録する必要があるということです.ID, 名前など所定の項目をコントロールに入力させ,データベースに登録するコードを記述しますが,この際様々なチェックが必要になります.そのチェックに合格した場合にのみレコードを登録するコードを記述し,登録ボタンのクリックイベントに登録します.チェックに引っかかった部分をユーザーにフィードバックする機能があれば尚親切かもしれません.
3.4 入力値のチェック
チェックの具体的な内容として,入力漏れがないか,適切なデータ型かなどの形式的なチェックと,さらに日付の前後関係や数値の大小関係といったセマンティックな要素も可能な限りチェックを行います.一旦誤ったデータがデータベースに登録されると簡単には見つけられません.ユーザーフォーム上で入力値のチェックを行うのが鉄則です.必要なら正規表現を使用して下さい.この部分の作り込みが使いやすいシステムになるか否かの分岐点になります.よく考えてコーディングして下さい.よくあるのが計算の必要な項目に全角数字を入力してしまったというものです.テキストボックスに半角数値のみの入力を受け付けるよう指定し,さらに入力モードを半角英数字に指定しておくなどの措置をプログラム上で行なっておけば済んだ話です.
Excel VBAでユーザーフォームのテキストボックスの値の形式的検証を行う
EXCEL VBA でユーザーフォーム上のコントロールの未入力を検証する
3.5 レコードを削除する
データベースからレコードを削除する必要がある場合もあります.Excel のワークシートをデータベースにしている場合はフィルターを使ってレコードを指定し,Delete メソッドを使用して削除するコードをコマンドボタンに記述するのがよいでしょう.先述のレコードを検索して表示されたリストボックスから削除するレコードを選択させるのが安全な方法でしょう.削除ボタンは他のボタンと距離を離し,押し間違いを防ぐために一旦メッセージボックスで確認をとるなどの安全策を講じたほうが良いでしょう.
4. パスワード入力
メンテナンスのために管理者としてアプリケーションを開く必要がある場合,パスワードを要求するのが普通です.パスワードの入力には Input メソッドを使用する方法とパスワード入力用のユーザーフォームを自作する方法があります.それぞれメリットとデメリットがありますが,個人的には自作する方をお勧めします.
Input メソッドは Excel で既に用意された機能ですので実装が容易です.戻り値に Variant 型を指定しておけばユーザーの行動を完全に把握出来ます.しかし唯一かつ致命的な欠点は入力値をマスクできないことです.この点で自作フォームをお勧めします.
自作フォームではコーディングの手間がかかるデメリットがありますが,入力値をマスクできるメリットのほうが大きいと思います.ユーザーフォームにテキストボックスとコマンドボタンを配置し,テキストボックスのプロパティを設定するだけで入力値をマスク出来ます.