はじめに。
ここ数週間、複雑なデータ構造を作成することでUser-Defined Type(UDT)の使用方法を学び、UDTの長所と短所を多かれ少なかれ知っています。あなたがそれらの記事を読んでいないなら、あなたはそれらを訪問するかもしれません。次のリンクを使用してください:
- ユーザー定義のデータ型-2
- ユーザー定義のデータ型-3
Microsoft Accessには、2種類のVBAモジュールがあります。
- 標準モジュール
- クラスモジュール
フォームでクラスモジュールを使用しました およびレポート MicrosoftAccessの。フォーム/レポートクラスモジュールプログラムは、ほとんどがイベント駆動型(ボタンクリック、更新前、フォーム/レポートの現在のイベントなど)の小さなルーチンです。
より深刻なデータ処理プログラムは、標準モジュールで記述されます。必ずしも関連しているとは限らない複数のプログラムを1つの標準モジュールに記述して、さまざまなタスクを実行できます。
クラスモジュールは異なります。これらはカスタムオブジェクトの構築に使用され、1つのクラスモジュールは1つのオブジェクトにのみ使用されます。
スタンドアロンクラスモジュールの基本。
簡単なクラスモジュールを最初から作成して、基本を学びましょう。
- Microsoft Accessを起動してデータベースを開くか、新しいデータベースを作成します。新しいデータベースの場合は、既存の信頼できる場所(フォルダー)に保存するか、新しい場所を信頼できる場所のリストに追加します。 [Officeボタン]–>[アクセスオプション]–>[セキュリティセンター]–>[セキュリティセンター設定]をクリックします。データベースフォルダをリストに追加し、[OK]をクリックします。
- VBA編集ウィンドウを開きます(Alt + F11)。
- 挿入をクリックします メニューからクラスモジュールを選択します リストから。新しいクラスモジュールが挿入されます。
注: クラス名: ClsArea オブジェクト名になります。つまり、このオブジェクトを使用する場合は常に、通常の変数宣言のようになります。 Dim xyz As ClsArea 。ユーザー定義のデータ型宣言についても同様のステートメントを作成しました。
次に、オブジェクトの3つのプロパティ(変数)を追加します(説明、長さ) および幅 )モジュールの上部、オプション比較データベースの下 およびOptionExplicit 行。クラスモジュールに次の行を入力します。
Option Compare Database Option Explicit Public p_Desc as String Public p_Length as Double Public p_Width as Double
これらの変数は、VBAカスタムクラスオブジェクトのプロパティとして識別されます。クラスモジュールを保存します。
注: クラスモジュールオブジェクトとコード行は、これほど単純ではありません。数行のコードで変更されます。変更の各段階を見失うことなく、段階的にそれらに従う準備をしておくことをお勧めします。これは単純な面積計算クラスです(面積=長さ*幅 )、その単純な。徐々に変更されるため、変更が必要になる理由がわかります。
新しいクラスモジュールをテストするために、標準モジュールで小さなプログラムを作成します。挿入メニューから標準モジュールを挿入します。次のコードを入力するか、コピーして標準モジュールに貼り付け、モジュールの既存の行を上書きすることができます。
Option Compare Database Option Explicit Public Function ClassTest1() Dim oArea As ClsArea Set oArea = New ClsArea oArea. Set oArea = Nothing End Function
薄暗い ステートメントは、Dim Desc as Stringのように、通常の変数の場合と同じように変数を宣言します。ただし、これは、クラスモジュールオブジェクト ClsAreaへの参照を設定している通常の変数ではありません。 。これはオブジェクトであるため、ローカルで定義されたオブジェクト oArea に値を格納するためのメモリスペースを割り当てないため、単純なDimensionステートメントだけでは不十分です。 プロパティ。
セット 次の行の新規のステートメント ClsAreaからオブジェクトのインスタンスを作成するにはキーワードが必要です メモリ内で、オブジェクトインスタンス名 oArea 。必要に応じて、この方法で同じクラスオブジェクトの複数のインスタンスをメモリ内で開くことができます(これらについては数週間以内に学習します)。これにより、値をプロパティ(p_Desc、p_Length、p_Width)に格納できます。 p_ 変数のプレフィックスは、変数のスコープがプライベートであることを示します。つまり、変数がキーワードPrivateで宣言されている場合、変数はクラスモジュールの外部に表示されませんが、現在はパブリックとして宣言されています。変数名は任意の有効な名前にすることができます。
注: まだプライベートとして宣言していません。私たちはその変化に向かって進んでいます。
キーワード設定の直後 ローカルオブジェクト名(適切な名前を選択できますが、通常の変数名の規則に準拠している必要があります)の後に、等号とキーワード New が続きます。 およびクラスモジュール名(ClsArea) すべてのプロパティ(変数)とともにメモリ内にclsAreaオブジェクトのインスタンスを作成します。
この2行のコードにはショートカットがあります。これらのコード行の両方のアクションは、以下に示すように1つのステートメントで実行できます:
Dim oArea As ClsArea Set oArea = New ClsArea 'the shortcut to the above two statements Dim oArea As New ClsArea
次の行を入力するとoArea ドットが続きます(。 )セパレータ次の画面が表示され、選択可能なカスタムオブジェクトプロパティのリストが表示されます。
表示されない場合は、[ツール]メニューボックスから[オプション]ダイアログに移動し、[エディター]タブの[メンバーの自動リスト]にチェックマークを付けます。
関数を終了する前に、最後のステートメントは Set oArea =Nothingである必要があります 。このステートメントは、カスタムオブジェクトのインスタンスによって占有されているメモリを明示的に解放し、他のプログラムでより多くのメモリを使用できるようにします。これは、私たちのプログラムによる責任あるクリーンアップ操作です。
インスタンス化されたカスタムオブジェクトで行うことはすべて、最初と最後のセットの間にコーディングする必要があります ステートメント。
ClsAreaクラスオブジェクトテストプログラム。
完成したクラステストプログラムコードを以下に示します。
Option Compare Database Option Explicit Public Function ClassTest1() Dim oArea As ClsArea Set oArea = New ClsArea oArea.p_Desc = "Carpet" oArea.p_Length = 25 oArea.p_Width = 15 Debug.Print "Description", "Length", "Width" Debug.Print oArea.p_Desc, oArea.p_Length, oArea.p_Width Set oArea = Nothing End Function
コードの途中をクリックして、 F5を押します。 プログラムを実行します。プログラムの実行は、参考のために以下に示されています。
Description Length Width Carpet 25 15
パブリック|オブジェクトプロパティのプライベートスコープ。
単純なクラスモジュールオブジェクトにはいくつかの欠点があり、それらを修正します。
1つ目は、すべての変数(またはプロパティ)をパブリックで宣言したことです。 範囲。そのため、それらは他のVBAプログラムに表示され、値が直接変更される可能性があります。 2番目の問題は、負の値やゼロ値など、クラスオブジェクトに適さない無効な値を受け入れることです。値を変数に受け入れる前に、いくつかの検証チェックを組み込む必要があります。
変数宣言をPublicからPrivateに変更することで、簡単に解決できる最初の問題 。これを行うときは、プライベート変数から値を格納および取得するための間接的なメソッドが必要です。それが入手の目的です としましょう オブジェクトのプロパティごとのプロパティプロシージャ。クラスモジュールでこれらの変更を行いましょう。
クラスモジュールClsAreaを開きます。 3つの変数すべてについて、Publicという単語をPrivateに変更します。
プロパティ手順の作成
手順を選択します 挿入から メニュー、「 strDesc」と入力します 名前で テキストコントロールで、プロパティを選択します タイプ オプショングループとパブリック スコープ オプショングループ。 [OK]をクリックして、 Private p_Descのプロパティプロシージャを挿入します 変数(プロパティ)。
Option Compare Database Option Explicit Private p_Desc As String Private p_Length As Double Private p_Width As Double Public Property Get strDesc() As String strDesc = p_Desc 'return the value from p_Desc End Property Public Property Let strDesc(ByVal strNewValue As String) p_Desc = strNewValue ‘store the value into p_Desc End Property
両方の取得 手順としましょう プロシージャはパブリックとして宣言されます 。両方のプロシージャ名は同じstrDescです。 デフォルトでは、返品 データ型はバリアントです 入手で プロシージャとパラメータのデータ型も、 LetにVariantとして挿入されます 手順。これらは、必要に応じて特定のタイプに変更できます。これを文字列に変更しました。 タイプ。最初の3文字str strDesc プロパティが文字列データ型の値を期待しているというヒントをユーザーに提供します。 Letを変更します プロパティプロシージャパラメータ 変数名vNewValue strNewValueへ
プロパティプロシージャを挿入すると、常に Getで挿入されます。 としましょう 変数のプロシージャペア。
ここで、 Get内に記述した式をよく見てください。 手順。 =の左側 Getプロシージャの名前に署名しますstrDesc プライベート変数p_Descからコピーされた値を返す変数として機能します 呼び出し側プログラムに。
レット 手順strDesc パラメータ変数strNewValueで文字列値を受け入れます 。入力値は、プライベート変数p_Desc。に転送されます。
ここで注意すべき点は、私たちのプライベート変数p_Descに外界に直接アクセスすることはできないということです。値の転送From/ To 変数(プロパティ) p_Desc 常にGet/ Letを介してルーティングされます プロパティ手順のみで、検証チェックの対象となります (まだ実装されていません)、プロパティに入力された値(Let Procedure)の検証チェックを後で紹介します。
Get / Let プロシージャは、VBAプログラムの式でObjectプロパティをどのように処理するかに応じて自動的に実行されます。
入手 次のように式でプロパティ名を使用すると、プロシージャが実行されます。
‘ Reads the value from p_Desc to Print Debug.Print oArea.strDesc OR ‘ Reads the value from p_Desc and assigns it to the variable X X = oArea.strDescに割り当てます。
レット プロパティ名に値を割り当てようとすると、プロパティプロシージャが実行されます。以下のテストプログラムの式の例を確認してください:
oArea.strDesc = “Carpet”
以前のBASIC言語の本では、キーワードLETの使用法を確認できます。
LET X = 25 ‘ LET is optional
オプションだったので、ステートメントはそれなしで機能し、まったく使用を停止しました。
ここで、読んでいるだけの場合 変数からの値があり、直接何も格納されていない場合は、Letプロシージャを省略して、 Getのみを使用できます。 手順。
このルールは、Letプロシージャにも適用されます。 Letのみを使用できます 手順、割り当ての場合 一部の値をプライベート変数に読み込みますが、同じ変数から何も読み戻さない場合は、Getプロシージャを省略します。
入手 としましょう 式が次のようなものである場合、プロシージャは次々に実行されます。
oArea.strDesc = oArea.strDesc & “ – King Size.”
上記の式では、取得します プライベート変数p_Descからの既存の値 説明を変更して、同じ変数に保存し直します。要するに表現 等号の右側にあるプロパティ名を使用する場合( = )入手 プロシージャが呼び出され、 Let プロシージャは、オブジェクトプロパティプロシージャ名が等しい( =)の左側に表示されたときに実行されます。 )署名します。
変数p_Lengthに2セットのプロパティプロシージャを挿入します およびp_Width。 名前でプロシージャ名を指定する場合 コントロールにdblLengthという名前を付けます およびdblWidth これらのプロパティが入力として倍精度数を期待していることをユーザーにヒントを与えるため。
プロパティプロシージャを含むClsAreaクラスオブジェクト。
dblLengthおよびdblWidthプロパティプロシージャを使用してこれまでに完成したコードを、参照およびコードの更新のために以下に示します。
Option Compare Database Option Explicit Private p_Desc As String Private p_Length As Double Private p_Width As Double Public Property Get strDesc() As String strDesc = p_Desc 'copy the value from p_Desc End Property Public Property Let strDesc(ByVal strNewValue As String) p_Desc = strNewValue End Property Public Property Get dblLength() As Double dblLength = p_Length End Property Public Property Let dblLength(ByVal dblNewValue As Double) p_Length = dblNewValue End Property Public Property Get dblWidth() As Double dblWidth = p_Width End Property Public Property Let dblWidth(ByVal dblNewValue As Double) p_Width = dblNewValue End Property
変更を加えたテストプログラム。
上記のコードを完了した場合は、ここで行った変更を反映するために、テストプログラムに変更を加えましょう。変更されたサンプルコードを以下に示します。
Option Compare Database Option Explicit Public Function ClassTest1() Dim oArea As ClsArea Set oArea = New ClsArea ‘Property Let procedures called here oArea.strDesc = "Carpet" oArea.dblLength = 25 oArea.dblWidth = 15 Debug.Print "Description", "Length", "Width" ‘Property Get Procedures called here to print Debug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidth Set oArea = Nothing End Function
オブジェクト名oArea(oArea。)の直後にドット(。)を入力すると、プロパティプロシージャ名のリストがVBA IntelliSenseによって表示され、手動で入力しなくてもリストから必要な名前を選択できます。
このクラスオブジェクトの目的は、部屋の面積、カーペット、床タイルなど、長さと幅の値を持つマテリアルの面積を計算することです。つまり、クラスオブジェクトに入力されたアイテムの長さ、幅、説明の値の面積を計算するには、パブリック関数が必要です。
ClsAreaオブジェクトメソッド:Area()
パブリック関数のコードは次のとおりです。
Public Function Area() As Double Area = Me.dblLength * Me.dblWidth End Function
この関数は挿入から挿入できます エリアを入力してメニュー 名前 コントロール、機能を選択 タイプから オプショングループ、およびパブリック スコープとして ClsAreaクラスモジュールに。真ん中に行を入力して、関数を完了します。
p_Length変数とp_Width変数を直接アドレス指定できます(関数 Area()のため) 面積を計算するための式のクラスモジュールの一部です)。ただし、適切なルートを使用しており、計算のためにGetProceduresdblLengthおよびdblWidthを呼び出しています。 私という参照に気づいたかもしれません。 フォーム/レポートクラスモジュールで記述したように、dblLength、dblWidth Getプロシージャを修飾して、メモリ内の現在のオブジェクトとそのプロパティを参照するために使用されます。前に述べたように、カスタムクラスオブジェクトは、メモリ内で同時に複数のオブジェクトインスタンスを開くことができ、私 キーワードは、Function Area()が属する現在のインスタンスを参照します。
変更を加えたテスト機能。
テスト関数ClassTest1()を変更して、以下のようにArea()関数の出力を組み込みます。
Option Compare Database Option Explicit Public Function ClassTest1() Dim oArea As ClsArea Set oArea = New ClsArea oArea.strDesc = "Carpet" oArea.dblLength = 25 oArea.dblWidth = 15 Debug.Print "Description", "Length", "Width", "Area" Debug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidth, oArea.Area Set oArea = Nothing End Function
変更は、Debug.Printステートメントにのみあります。コードを実行し、デバッグウィンドウで結果を確認します。
カスタムクラスモジュールには、次の2つのイベントプロシージャが必要です。 Class_Initialize() およびClass_Terminate() 。
自動実行メソッド。
Class_Initialize() New を使用してオブジェクトをインスタンス化すると、プログラムが自動的に実行されます。 キーワード。このプログラムを使用して、デフォルト値を変数に設定したり、メモリ内の他のオブジェクトをインスタンス化したりできます。 1つのクラスオブジェクトが他のクラスを子オブジェクトとして使用する場合があり、インスタンス化する必要があります。この側面については、さらに詳しく調べて、後でその方法を学びます。
Class_Terminate() 何もないときにオブジェクトをメモリからクリアしようとすると、プログラムが実行されます キーワードはステートメントで実行されますSet oArea =Nothing 。クラスオブジェクトを使用するプログラムが終了すると、メモリ内のオブジェクトのインスタンスはデフォルトで削除されます。ただし、 Set oArea =Nothing を使用することは良いプログラミング手法です。 オブジェクトをメモリからクリアするためのプログラムの最後の実行可能ステートメントとしてのステートメント。
上記のプログラムをクラスモジュールに追加します。クラスモジュールの最後に次のコードを追加します。
Private Sub Class_Initialize() p_Length = 0 p_Width = 0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()" End Sub Private Sub Class_Terminate() 'MsgBox "Terminate.", vbInformation, "Class_Terminate()" End Sub
これらの2つのサブルーチンをテストする場合は、コメントシンボルを削除して、MsgBoxをアクティブにします。テストプログラムをもう一度実行します。 初期化が見つかります メッセージが最初に表示され([OK]をクリックして続行します)、終了 テストプログラムの最後にメッセージが表示されます。
「2つの変数を掛け合わせるためのコードがたくさんある」など、あなたが今考えていることはわかっています。その観点からは真実ですが、同様の問題解決の問題のコードを毎回繰り返し記述し、検証チェックやその他の論理的なエラー保護のためにコードを複製している可能性があります。
ここでは、通常のプログラムを作成するのではなく、ユーザーの観点から、何度も使用できる、または他のオブジェクトの一部として、動作を気にせずに必要な場所で使用できるカスタムオブジェクトを開発しています。 Microsoft Accessには、プロパティまたはパラメータを設定して作業を完了することにより、動作を気にせずに常に使用する多くの組み込みオブジェクト/関数があります。
もう1つ注意すべき問題があります。それは、 dblNewValueに入力された値の検証チェックです。 Letのパラメータ dblLength()のプロパティプロシージャ およびdblWidth()、 有効な値がオブジェクトプロパティに割り当てられますp_Length およびp_Width 。
入力された負の値またはゼロ値は無効と見なされ、ユーザーが正しい値を入力したことを確認するための予防措置を講じる必要があります。
検証チェックの実行。
変更されたLet プロパティプロシージャコードセグメントを以下に示します。それに応じてコードを変更してください。
Public Property Let dblLength(ByVal dblNewValue As Double) Do While dblNewValue <= 0 dblNewValue = InputBox("Negative/0 Values Invalid:", "dblLength()", 0) Loop p_Length = dblNewValue End Property Public Property Let dblWidth(ByVal dblNewValue As Double) Do While dblNewValue <= 0 dblNewValue = InputBox("Negative/0 Values Invalid:", "dblwidth()", 0) Loop p_Width = dblNewValue End Property
実行中。 。 。ループ 有効な値(0より大きい)が dblNewValue に入力されるまで、繰り返し実行されます ユーザーによる
パブリックメソッドの検証チェック:Area()
Area()でもう1つの検証チェックが必要です 働き。ユーザーが最初に長さと幅の有効な値を入力せずにArea()関数を呼び出す場合は、ユーザーにそのことを通知する必要があります。面積計算の式を実行する前に、p_Length変数とp_Width変数に有効な値があるかどうかを確認します。コードは次のとおりです:
Public Function Area() As Double If (Me.dblLength > 0) And (Me.dblWidth > 0) Then Area = Me.dblLength * Me.dblWidth Else Area = 0 MsgBox "Error: Length/Width Value(s) Invalid., Program aborted." End If End Function
ClsAreaオブジェクトの完全なコード。
クラスモジュールClsAreaの完全に完成したコードを以下に示します。
Option Compare Database Option Explicit Private p_Desc As String Private p_Length As Double Private p_Width As Double Public Property Get strDesc() As String strDesc = p_Desc 'copy the value from p_Desc End Property Public Property Let strDesc(ByVal strNewValue As String) p_Desc = strNewValue End Property Public Property Get dblLength() As Double dblLength = p_Length End Property Public Property Let dblLength(ByVal dblNewValue As Double) Do While dblNewValue <= 0 dblNewValue = InputBox("Negative/0 Values Invalid:", "dblLength()", 0) Loop p_Length = dblNewValue End Property Public Property Get dblWidth() As Double dblWidth = p_Width End Property Public Property Let dblWidth(ByVal dblNewValue As Double) Do While dblNewValue <= 0 dblNewValue = InputBox("Negative/0 Values Invalid:", "dblwidth()", 0) Loop p_Width = dblNewValue End Property Public Function Area() As Double If (Me.dblLength > 0) And (Me.dblWidth > 0) Then Area = Me.dblLength * Me.dblWidth Else Area = 0 MsgBox "Error: Length/Width Value(s) Invalid., Program aborted." End If End Function Private Sub Class_Initialize() p_Length = 0 p_Width = 0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()" End Sub Private Sub Class_Terminate() 'MsgBox "Terminate.", vbInformation, "Class_Terminate()" End Sub
プロパティの手順とメソッドのテスト。
dblLength、dblWidthプロパティへの入力として負の値または0の値を入力することにより、カスタムクラスオブジェクトをテストできます。
テストプログラムで、行(oArea.dblLength=25およびoArea.dblWidth=15)をコメントアウトして、Area()関数をテストします。関数内に書き込んだエラーメッセージが表示されます。
これで、面積計算クラスモジュールが完了したと見なされ、テストして正しく機能していることがわかりました。私が見落とした論理エラーがないか、さらにテストすることができます。私が予期していなかったことに出くわした場合は、それを私と共有してください。
テストの将来計画。
1つのアイテムについてのみクラスオブジェクトをテストしました。いくつかのアイテムの面積を計算する必要があります(たとえば、5つのベッドルームや10の異なるサイズのカーペットなど。オブジェクトが開発されると、異なる値のセットを割り当てて、メモリ内でオブジェクトを数回インスタンス化できると言われています。オブジェクトの各インスタンスに挿入し、それらを操作できます。
さらに、このオブジェクトは、新しいクラスオブジェクトの一部がすでにClsAreaクラスモジュールで開発されているため、より少ないコードで開発する他のオブジェクトの一部として使用できます。
来週は、カスタムオブジェクトの配列を作成して、いくつかのアイテムの面積を計算する方法を学びます。
- MS-AccessクラスモジュールとVBA
- MS-AccessVBAクラスオブジェクト配列
- MS-Accessの基本クラスと派生オブジェクト
- VBA基本クラスと派生オブジェクト-2
- 基本クラスと派生オブジェクトのバリアント
- Ms-Accessレコードセットとクラスモジュール
- アクセスクラスモジュールとラッパークラス
- ラッパークラスの機能変換
- Ms-Accessおよびコレクションオブジェクトの基本
- Ms-Accessクラスモジュールとコレクションオブジェクト
- コレクションオブジェクトとフォームのテーブルレコード
- 辞書オブジェクトの基本
- 辞書オブジェクトの基本-2
- 辞書オブジェクトのキーとアイテムの並べ替え
- 辞書からフォームへのレコードの表示
- クラスオブジェクトをディクショナリアイテムとして追加
- フォームのクラスオブジェクトディクショナリアイテムを更新する