こんにちは!Accessでのフォーム開発、日々お疲れ様です。
「新しいデータを入力するために、フォーム上のすべての入力欄をキレイに空っぽにしたい」
「ボタン一つでテキストボックスやコンボボックスを初期状態に戻したい」
実務のシステムを作っていると、こうした「一括クリア処理」は避けて通れない基本中の基本ですよね。
もし、これをマクロの記録や、一つひとつのコントロールを指定する力技(`Me.Text1 = “”`, `Me.Text2 = “”`……)で書いていたら要注意。後からコントロールが追加されるたびにコードを書き直すハメになり、メンテナンス地獄が待っています。
今回は、どんなにフォームが巨大化してもビクともしない、「コントロールの型を見極めて安全に一括クリアする汎用モジュール」の作り方を、プロの知見を交えて優しく解説していきます。
ここをクリアすれば、Access VBAのオブジェクトモデルの基本はバッチリですよ!一緒にマスターしていきましょう。
—
なぜ「一つひとつ消すコード」は悪手なのか?
初学者の頃やりがちなのが、次のようなコードです。
‘ ❌ やってはいけない個別指定の例
Me.txt氏名 = “”
Me.txt住所 = “”
Me.cbo都道府県 = Null
‘ コントロールが増えるたびにここを修正…?そんなの面倒すぎますよね!
Accessのフォームには、`Controls`コレクションという「フォームに配置されているすべての部品が入った箱」が存在します。
この箱を`For Each`ステートメントでグルっと巡回(ループ)させれば、コントロールが10個あろうが100個あろうが一網打尽に処理できます。
しかし、ここで一つ大きな問題が立ちはだかります。
「テキストボックスには `””`(長さ0の文字列)を入れるのが正解だけど、コンボボックスや数値型のテキストボックスに `””` を入れると、型不一致エラー(実行エラー 13)が爆誕する」という罠です。
この罠を華麗にかわし、どんな部品でも安全に初期化できる「大人のコード」を見ていきましょう。
—
実装:保守性抜群の汎用クリアプロシージャ
標準モジュール、またはフォームのコードモジュールに、以下のプロシージャを貼り付けてください。今回は、どのフォームからでも呼び出せるように、標準モジュールに書くスタイルをおすすめします。
‘ =================================指定フォームの全コントロールを初期化する=================================
‘ 引数: targetForm – 初期化したいフォームオブジェクト (Me を渡します)
‘ ==========================================================================================================
Public Sub ClearFormControls(ByRef targetForm As Access.Form)
Dim ctl As Access.Control
‘ フォーム上の全コントロールを巡回
For Each ctl In targetForm.Controls
‘ コントロールの種類(ControlType)によって処理を分岐
Select Case ctl.ControlType
Case acTextBox
‘ テキストボックスは空文字にリセット
‘ ※ロックされている項目はエラーになるため、EnabledかつLockedでないものに限定するのが実務的ですが、
‘ 今回はシンプルにクリアできるもの対象とします
If ctl.Enabled And Not ctl.Locked Then
ctl.Value = vbNullString
End If
Case acComboBox, acListBox
‘ コンボボックスやリストボックスは選択を解除(Nullを代入)
If ctl.Enabled And Not ctl.Locked Then
ctl.Value = Null
End If
Case acCheckBox, acOptionButton, acToggleButton
‘ チェックボックスなどのON/OFF系は False(オフ)にリセット
If ctl.Enabled And Not ctl.Locked Then
ctl.Value = False
End If
‘ 必要に応じて acOptionGroup (オプション グループ) などの処理を追加可能
End Select
Next ctl
‘ メモリ解放(VBAのお作法)
Set ctl = Nothing
End Sub
使い方
フォームに配置した「クリアボタン」のクリックイベントなどで、次のように呼び出すだけです。
Private Sub btnClear_Click()
‘ 自分自身のフォームを渡して一発クリア!
ClearFormControls Me
‘ ついでにフォーカスを最初のテキストボックスに戻す親切設計
Me.txt氏名.SetFocus
MsgBox “入力内容をクリアしました。”, vbInformation, “完了”
End Sub
これだけで、フォーム上のテキストボックス、コンボボックス、チェックボックスがそれぞれの作法に従って一瞬で初期化されます。新しくコントロールを追加しても、コードを書き換える必要は一切ありません!
—
コードの重要ポイントと「知っておくべき極意」
ここで、プロのエンジニアがこだわった3つのポイントを解説します。
1. `ControlType` による確実な型制御
Accessのコントロールは見た目は似ていても、内部のデータ型やプロパティが異なります。`Select Case ctl.ControlType` を使うことで、「テキストボックスにはこれ」「コンボボックスにはこれ」と、それぞれの仕様に合わせた正しい値を代入しています。これがエラーを防ぐ最大の防壁です。
2. `Enabled` と `Locked` のチェック
実務のフォームでは、「自動採番されるID」や「変更不可のマスター情報」など、触ってほしくない(編集不可な)コントロールが必ず存在します。
`If ctl.Enabled And Not ctl.Locked Then` という条件を入れることで、「入力可能なアクティブなコントロールだけ」を狙い撃ちしてクリアしています。ここをサボると、読み取り専用の項目をクリアしようとしてVBAが怒り出し、エラーで止まってしまいます。
3. `vbNullString` と `Null` の使い分け
- テキストボックス = `vbNullString`(または `””`)
- コンボボックス・リストボックス = `Null`
- チェックボックス = `False`
Accessのデータベースの性質上、コンボボックスや数値・日付を扱うコントロールに `””` を入れると、データ型のエラーや意図しない「長さ0の文字列」データとして保存されてしまい、後々の集計やSQLでの抽出時にバグの原因になります。「適切なコントロールには適切な空っぽをあてがう」、これがAccess VBAにおける美学です。
—
陥りやすいエラーと対処法
罠:サブフォームがある場合にエラーになる
もし、メインフォームの中に「サブフォーム」がある場合、上記のコードをそのまま実行すると、サブフォーム内のコントロールの種類(サブフォームコントロール自体)で想定外の挙動をしたり、意図しないクリア漏れが起きたりします。
対策:
もしサブフォームも含めて一括クリアしたい場合は、`Case acSubform` を追加し、サブフォームの `Form.Controls` に対して再帰的に同じプロシージャを呼び出す仕組みを作ると完璧です。まずは今回紹介した単票フォーム/連続フォームの基本形を確実にモノにしましょう。
—
まとめ
いかがでしたか?
今回は、フォームのコントロール値を美しく、そして安全に一括クリアする汎用プロシージャについて解説しました。
- コントロールの箱(`Controls`コレクション)をループさせる
- `Select Case ctl.ControlType` でコントロールの種類を判定する
- `Enabled` や `Locked` を考慮してエラーを未然に防ぐ
この3つさえ押さえておけば、マクロの記録のレベルから一気に脱却し、メンテナンス性の高い「プロの設計」に近づくことができます。
ここをクリアできれば、Access VBAのフォーム操作の基礎はもうバッチリです!ぜひ、あなたの開発するシステムにも取り入れて、快適なVBAライフを送ってくださいね。それでは、次のステップでお会いしましょう!
