トップ > スキル : アプリケーション > VBA for Access > 応用編(VBA基礎知識)
VBAを記述する場合、基本的な決まりごとを覚えておく必要があります。まず、プロジェクトという大きな管理内で作成するものがモジュールです。そして、プログラム(プロシージャ)はモジュール内で作成することになります。

モジュール
VBAで作成したプログラムを管理するためのオブジェクトがモジュールです。モジュールの構造は、宣言セクションとプロシージャとなります。モジュールはプロシージャ(プログラム)を管理するための入れ物のような役割となり、そのプロシージャの約束事をモジュール内で宣言することによって、統一したプロシージャの書き方が可能となります。

図のように、1つの宣言セクションと複数のプロシージャで構成されます。宣言セクションには、モジュール全体で使用する変数や定数とそれらのデータ型を記述することで、モジュール全体を適応範囲として設定します。
モジュールには、標準モジュールとクラスモジュールの2種類があります。
◆ 標準モジュール
特定のオブジェクトに関連付けられていないオブジェクトです。データベースのどこからでも実行できるプロシージャやユーザ定義関数を作成するときに利用します。
◆ クラスモジュール
特定のフォームやレポートなどのオブジェクトに関連付けられたモジュールです。このモジュール内に作成したプロシージャは、そのフォームやレポート内だけしか使用できません。また、標準モジュール名のプロシージャを呼び出すことができます。
プロシージャ
VBAで記述されたプログラムの実行単位で、モジュールで管理されています。プロシージャは、クラスモジュールで管理するイベントプロシージャと、標準モジュールで管理する標準プロシージャの2つに大きく分けることができます。

◆ イベントプロシージャ
特定のオブジェクト(フォームやレポート)の特定のイベントが発生したときに自動的に実行されるプロシージャです。
イベントプロシージャは、Subプロシージャとして記述します。
◆ 標準プロシージャ(ジェネラルプロシージャ)
特定のオブジェクトに依存しないプロシージャで、他のプロシージャからCallステートメントで呼び出すことができる。標準プロシージャにイベントプロシージャを記述することはできません。
標準プロシージャは、Subプロシージャ、Functionプロシージャで記述します。
Subプロシージャ
「Sub…End Sub」で囲み、実行結果を呼び出し元に返さないプロシージャです。つまり、値を返さないプログラムとなります。
Sub プロシージャ名() 処理内容 End Sub
Functionプロシージャ
実行結果を呼び出し元に返すプロシージャで、ユーザ定義関数を作ることができます。Functionプロシージャが返す値を「戻り値」と呼び、記述方法は「Function…End Function」で囲みます。
Function プロシージャ名() 処理内容 End Function
ステートメント
プロシージャを構成する一単位をステートメントと呼び、命令文ともいわれます。

1つのプロシージャ内に複数の命令文(ステートメント)を記述して、連続した流れの処理を行えるプログラムを作ります。
ステートメントは、オブジェクト、メソッド、プロパティ、組み込み関数や定数などを使って記述します。
オブジェクト
VBAで操作する対象のことを「オブジェクト」と呼びます。Accessでは、フォームやレポート、テーブル、コマンドボタンなどのような構成要素をオブジェクトとして扱います。
例えば、「Fメインメニュー」フォームを参照する場合は、以下のように記述します。
Forms![Fメインメニュー]
もし、レポートであれば、Reports![レポート名]となります。
また、「Fメインメニュー」内の「終了」コマンドボタンであれば、以下のように記述します。
Forms![Fメインメニュー]![終了]
オブジェクトを参照するときは、オブジェクトを種類ごとに分類して、その分類の大きいものから順に記述します。
分かりやすいように、Accessの動作を人間のしぐさに例えてみましょう。
「太郎君が歩く」という動作であれば、「太郎君」がオブジェクトなります。太郎君は人間ですので、太郎君の前に人間というオブジェクトを入れて、次のように記述します。
人間![太郎君]
人間というのは、複数存在しています。Accessでは、このような大きな分類を「コレクション」と呼びます。「太郎君」は「たくさんいる人間」の中に存在するので、太郎君を限定するために「人間![太郎君]」とします。さらに、厳密にいうとオブジェクトの先頭(一番大きな分類)は、Accessそのものを表すApplicationオブジェクトが存在します。しかし、どのオブジェクトも、Accessのオブジェクトというのは分かりきっているので、一般的には省略して記述します。
太郎君の場合も、動物!人間![太郎君]なのですが、太郎君は動物であることがはっきりしているので、動物!というオブジェクトは省くことができます。
[Application!][コレクション名!][コントロールを配置したフォーム名やレポート名!][コントロール名]
VBAでは、これらの分類の間に「!(エクスクラメーション)」を区切りとして記述します。また、オブジェクト名は[ ](ブランケット)で囲みます。オブジェクト名に空白や記号が含まれていない場合はこのブランケットを省略することができます。
メソッド
オブジェクトの動作を表すのが「メソッド」です。「車を動かす」であれば。「動かす」がメソッドに該当します。
メソッドの書式は次のようになります。
オブジェクト.メソッド 引数
オブジェクトとメソッドの間は「.」(ドット)で区切ります。また、メソッドには引数が必要なものと省略できるものがあります。メソッドと引数の間は半角スペースで区切ります。
例えば、「F新規入力」フォームを開く場合は次のように記述します。
DoCmd.OpenForm "F新規入力"
(DoCmdオブジェクトのOpenFormメソッドで、フォーム「F新規入力」を開く)
引数はメソッドによって、異なります。また、引数が要らないものもあります。引数は、動作を具体的に指定するものです。例えば、「車を動かす」という「動かす」というメソッドでも、前に動かすのか、後ろに動かすのかを指定する必要があります。車を前進させたいのであれば、「前に」という要素が必要となりますので、書式どおりにすると「車.動かす 前へ」というイメージになります。最後の「前へ」が引数になります。
プロパティ
プロパティは属性のことで、オブジェクトの状態(性質)や設定項目で、Accessのプロパティシートで見ることができます。
プロパティの書式は次のようになります。
オブジェクト.プロパティ = 値
オブジェクトとプロパティの間は「.」(ドット)で区切ります。また、プロパティには「値」が存在しますので、「=」で値を指定します。
例えば、「Fメインメニュー」フォームのタイトルを「システムメニュー」とするには、次のように記述します。
Forms![Fメインメニュー].Caption = "システムメニュー"
(フォーム「Fメインメニュー」オブジェクトの標題(Caption)を「システムメニュー」に指定)
プロパティは、Accessのフォームなどで扱ったプロパティとなりますが、VBAでは英語表記となります。
「名前」プロパティであれば「Name」プロパティ、「背景色」プロパティであれば「BackColor」プロパティとなります。
「車のボディー色をグレーにする」で例えれば、「ボディー色」がプロパティになります。書式どおりに記述すると「車.ボディー色 = グレー」となります。
イベント(Event)
イベントプロシージャは、フォームやレポート内で操作を行ったきっかけで動作する処理を認識します。フォーム、レポートのイベントプロパティとVBAのイベントの対応表は以下の通りになります。
※イベントで認識できるのは、フォーム、レポート、そしてフォーム上のコントロールで、オブジェクトごとに認識できるイベントは決まっています。
分類 | イベント | イベントプロパティ | 説明 |
---|---|---|---|
マウス | Click | クリック時 | マウスの左ボタンを押した時 |
Dbclick | ダブルクリック時 | マウスの左ボタンを2回連続で押した時 | |
MouseDown | マウスボタンクリック時 | マウスボタンを押した瞬間 | |
MouseMove | マウスボタン移動時 | マウスを移動したとき | |
MouseUp | マウスボタン開放時 | マウスボタンを離した時 | |
ウィンドウ | Close | 閉じる時 | フォームまたはレポートを閉じて画面が消える時 |
Load | 読み込み時 | フォームを開いた後レコードが表示される時 | |
Open | 開く時 | フォームを開いて最初のレコードが表示される前、またはレポートを開いて印刷される前 | |
Resize | サイズ変更時 | フォームのサイズを変更された時 | |
Unload | 読み込み開放時 | フォームを閉じる時、画面が消える前 | |
フォーカス | Activate | アクティブ時 | フォームまたはレポートがアクティブになった時 |
Deactive | 非アクティブ時 | 他のAccessウィンドウがアクティブになった時 | |
Enter | フォーカス取得時 | コントロールがフォーカスを受け取る時 | |
Exit | フォーカス喪失時 | 他のコントロールにフォーカスが移動する直前 | |
データ | AfterDelConfirm | 削除後確認 | 削除確認後実際にレコードが削除された後、または削除がキャンセルされた時 |
AfterInsert | 挿入後処理 | 新規レコードが追加された後 | |
AfterUpdate | 更新後処理 | 変更されたデータが更新された後 | |
BeforeDelConfirm | 削除前確認 | レコードを削除した後で削除確認のダイアログボックスが表示される前 | |
BeforeInsert | 挿入前処理 | 新規レコードで最初の文字を入力した時 | |
BeforeUpdate | 更新前処理 | 変更されたデータが更新される前 | |
Change | 変更時 | テキストボックスの値が変化した時、またはタブコントロール内でページを移動した時 | |
Current | レコード移動時 | フォーカスが他のレコードに移動し、そのレコードがカレントレコードになった時 | |
Delete | レコード削除時 | 削除確認後に実際にレコードが削除される時 | |
Dirty | ダーティ時 | フォームまたはコンボボックスのテキスト部分が変更された時 | |
NotinList | リスト外入力時 | コンボボックスのリストが存在しない値を入力した時 | |
Update | 更新時 | OLEオブジェクトのデータが変更された時 | |
キーボード | KeyDown | キークリック時 | キーボードを押した時 |
KeyPress | キー入力時 | キーボードを押して離した時 | |
KeyUp | キー開放時 | キーボードを離した時 | |
エラー | Error | エラー時 | フォームまたはレポートで実行エラーが発生した時 |
タイミング | Timer | タイマー時 | タイマー間隔プロパティに指定した時間が経過した時 |
フィルタ | ApplyFilter | フィルタ実行時 | フィルタを実行した時 |
Filter | フィルタ設定時 | フォームフィルタを実行した時 | |
印刷 | Format | フォーマット時 | レポートセクションに表示されるデータが決定した時 |
NoData | 空データ時 | データのないレポートがフォーマットされた後で印刷される前 | |
Page | ページフォーマット時 | フォーマット後でページが印刷される前 | |
印刷時 | フォーマット後でセクションが印刷される前 | ||
Retreat | 戻り時 | フォーマット中に前にフォーマットしたレポートセクションに戻った時 |
イベントの発生する順序
フォームを開いてから閉じるまでの間、いろいろな操作を行いますが、その間のイベントには発生する順序があります。Access内で操作する際にイベントが行われる順序をあらかじめ知っておくことが必要です。
◆ フォームとコントロールの扱い
フォーカスを取得できるコントロールを含むフォームを開いて閉じる時
Open→Load→Resize→Activate→Current→Unload→Deactivate→Close
コントロールのフォーカス
Enter→GetFocus→Exit→LostFocus
◆ データの扱い
テキストボックス、コンボボックスのテキスト変更
KeyDown→KeyPress→Change→KeyUp
Changeイベントはコントロールの内容が変更されるたびに発生する。テキストボックスに文字を入力していくと、キーストロークごとに上のイベントが同じ順序で発生します。
テキストボックス、コンボボックスのテキスト更新
データを変更した後、同じフォームに配置されている別のコントロールに移動すると、コントロールのデータが更新され、この時BeforeUpdateイベントとAfterUpdateイベントが発生します。BeforeUpdateは、データが更新される直前に発生し、AfterUpdateイベントはデータが更新された直後に発生します。
例)「txtA」テキストボックスの文字を削除して、「txtB」テキストボックスをクリックして「txtA」のデータを更新します。
KeyDown→KeyPress→Change→KeyUp→BeforeUpdate→AfterUpdate
→Exit(txtA)→LostFocus(txtA)→Enter(txtB)→GotFocus(txtB)
◆ レコードの扱い
レコードの挿入
フォームを使って新規レコードにデータを入力する場合、そのレコードに最初のデータが入力された時にBeforeInsertイベントが発生し、そのレコードが保存された時にAfterInsertイベントが発生します。
例)フォームに新規レコードを表示して、「txtA」テキストボックスに文字を入力します。
KeyDown(txtA)→KeyPress(txtA)→BeforeInsert(txtA)→Change(txtA)→KeyUp(txtA)
レコードの削除
フォームでレコードを選択して削除します。
Delete→Current→BeforeDelConfirm→AfterDelConfirm