Microsoft Access2003

Page 6 (2005/01)

オブジェクトとコレクション

オブジェクト (object)

「object」は「物体」という意味で、コンピュータ関連では、システムを構成する構成要素を指してこう呼ぶ。 例えばオブジェクト指向プログラミングでは、データと、そのデータ処理の双方を含んだプログラムの独立した構成要素を指してオブジェクトと呼ぶ。オブジェクト指向プログラミングでは、こうしたオブジェクトを組み合わせることで最終的なプログラムを作成する。 これ以外にも、3次元グラフィックス処理において、空間に配置される各物体をオブジェクトと呼んだり、グラフィカル・ユーザー・インターフェイスでは、ボタンやメニューなどのインターフェイスの構成要素を指してオブジェクトと呼んだりする。

オブジェクトとコレクションについては、かtなり哲学的という抽象的なので、良く理解できません。
Accessに提供されるオブジェクト・ライブラリには4種類があるそうで、以下の通りです。

Microsoft Accessのオブジェクト    Application、 Control 、Form、 Module・・・・
DAOのオブジェクト            Connection、 Container、 Database、 DBEngine ・・・
Visual Basicのオブジェクト       Debug、 Err・・・
Microsoft officeのオブジェクト     Assistant、 CommandBa、・・・r

Accessオブジェクトを例としたイメージは解説書によると、ApplicationオブジェクトのなかにはFormsコレクションが含まれ、そのなかのFormオブジェクトにはControlsコレクションが含まれ、このコレクションの中にはControlオブジェクトが含まれる・・・といった階層になっている、ということです。

このような階層構造になっているため、コレクションの中の特定のオブジェクトを参照する場合、経路を指定しなくてはならない。
コレクション名とそのなかのオブジェクト名を連結して指定するための区切り記号として ! を使います。

Forms!社員    ←Formsコレクションの中の「社員」というFormオブジェクト。Form社員 は開いている必要がある。

社員フォームのなかのコントロール「氏名」を参照するには、

Forms!社員..Controls!氏名

と書くのですが、オブジェクトは下の階層のオブジェクトのコントロールをひとつ以上含み、Formオブジェクトの場合はCotrolsコレクションが既定のコレクションであるため、コレクション名を省いて次のように指定できます。

Forms!社員!氏名
オブジェクト変数

オブジェクトを繰り返し参照する場合、通常の変数と同じように変数を使って参照しますが、通常の変数が値を受け取るのに対して、オブジェクト変数はオブジェクトへの参照を保持します。

Dim frm As Form

オブジェクト参照をオブジェクト変数に割り当てる方法は、通常の変数への値の代入と違って Set ステートメントを使います。

Set frm = Forms!社員

変数 frm は「社員」のFormオブジェクト指している、ということです。
オブジェクト変数を使うメリットは「オブジェクト変数を作成してオブジェクトを割り当てると、階層内のオブジェクトの位置に関する情報がその変数に格納されます。オブジェクト変数は、階層の中で使用するオブジェクトの上位に置かれたすべてのオブジェクトを一括して表わす簡単な手段にあたります

次のサンプルコードは、「コレクションに属するオブジェクトの列挙」、具体的に言うとテーブル「DVD」のなかのフィールドをすべてリストするものです。
Sub ListTableFields()
   Dim dbs As Database, tdf As TableDef, fld As Field  3種類のオブジェクト変数を宣言
   Set dbs = CurrentDb                      Database型オブジェクト変数にオープンしているデータべースへの参照をセット
   Set tdf = dbs.TableDefs!DVD           TableDef型オブジェクト変数に [DVD]テーブルヘの参照をセット
   For Each fld In tdf.Fields          DVDテーブルのなかのFieldsコレクションを順次チェックして、デバグ・ウィンドウにリスト表示する
      Debug.Print fld.Name
   Next fld
   Set dbs = Nothing              オブジェクト変数を開放する
End Sub

For Each ・・・Next
これはちょっと変わったループ処理で、構文は以下の通りです。オブジェクトとコレクションでしか使わないみたい。
コレクションに含まれるオブジェクトの数が分からなくても良いところが特徴です。
  For Each object In collection
     statements
  Next object

面白いのでサンプル・コードをもうひとつ紹介します。「新しいDAOオブジェクトのコレクションヘの追加」です。
新しいテーブルをコードを使って作成する簡単なパターンです。カレントデータベースに、長さ50の文字型フィールド「タイトル」を含む新しいテーブル「VHS」を作成するものです。

Sub AddTable()
  Dim dbs As Database, tdf As TableDef, fld As Field  3種類のオブジェクト変数を宣言
  Set dbs = CurrentDb                      カレントデータべスをデータベース変数にセット
  Set tdf = dbs.CreateTableDef("VHS")           テーブル変数に「VHS」という名前の新しいテーブルをセット
  Set fld = tdf.CreateField("タイトル", dbText, 50)     そのテーブルになかの「タイトル」と言う名の文字型フィールをフィールと変数にセットド
  tdf.Fields.Append fld                      フィールド変数をテーブル変数に追加
  dbs.TableDefs.Append tdf                   テーブル変数をデータベース変数に追加
  dbs.TableDefs.Refresh                     データベース変数を更新
  Set dbs = Nothing
End Sub

オブジェクト変数を使うと細かい処理が可能になる、ということで、サンプルコードを応用したものを frmDVD に組み込んでみました。
テーブルに連結されたフォームでは誤操作で表示データが修正消去される恐れがありますから、通常はコントロールを編集不可の状態にしておいて、編集するときに編集ボタンをクリックしてロックされたコントロールをアンロックします。
ロックする部分はフォームのOnCurrentイベントで同じパターンのコードを使っています。「cmd編集」ボタンではロックを解除してコントロールの背景色を黄色にして編集可能であることを明示します。

Private Sub cmdデータ編集_Click()
  'コントロールの背景色を黄色にしてフォームを編集可能にする
  Dim ctl As Control
  For Each ctl In Me.Controls
    Select Case ctl.ControlType       '処理するコントロールのタイプを限定します
      Case acTextBox, acComboBox
        Select Case ctl.Name       'コントロールの名前で特定のコントロールを除外します
          Case "cboタイトル検索", "cbo監督名検索", "cbo出演者検索"
          Case Else
            ctl.BackColor = vbYellow
            ctl.Locked = False
        End Select
    End Select
  Next ctl
End Sub

プロパティとメソッド
property

 「property」は「特性」の意。コンピュータ関連では、オブジェクトの特性(属性)を意味する。たとえばオブジェクト指向プログラミングでは、独立して機能できるひとまとまりのコードをオブジェクトとし、このコードの振る舞いなどをプロパティとして設定する。また一般にGUI環境では、画面上に表示されるデスクトップメタファー(ごみ箱やフォルダなど)の属性をプロパティと呼び、これをユーザーが変更することで、見掛けや挙動を変更できるようにしている。

method

 オブジェクト指向プログラミング(OOP)で、オブジェクトが備えるルーチン。SmallTalkでメソッドと呼ばれるが、C++やJavaではメンバ関数と呼ばれる。ActiveXコントロールでは、コントロールを制御するために、外部に公開しているルーチンをメソッドと呼んでいる。

さまざまなオブジェクトに膨大な数のプロパティがあるのですが、なかにはオブジェクトの属性を決めるのではなく、ほかのオブジェクトの参照を返すものがあります。例えば ActiveControl プロパティはフォーカスを取得しているControlオブジェクト、ActiveFormはフォーカスを取得しているFormオブジェクトといった具合です。そのなかで頻繁に使われるのが Meプロパティ です。
Meプロパティは実行中のFormオブジェクトまたはReportオブジェクトへの参照を返します。つまり、コードが実行されているフォームを示します。

次のコードは標準モジュールのなかに置きます。Formオブジェクト変数でフォームへの参照を受け取り、そのフォームの詳細セクションの背景色をランダムな色に変更します。

Sub ChangeDetailColor(frm As Form)
   'フォームの詳細セクションの背景色をランダムに変更する
   frm.Section(acDetail).BackColor = RGB(Rnd * 256, Rnd * 256, Rnd * 256)
End Sub

以下の二行は上のプロシージャを呼び出す部分。FormのCurrentイベントのなかに置いて、レコードを移動してデータ表示を書き換えるたびに背景色が変化させます。
ChangeDetailColor Me
Me.Caption = Me!タイトル.Value
フォームのプロパティCaptionは「.」ドットで区切りますが、フォームのコントロールを参照するのには「!」演算子で区切ります。
「メソッドは、オブジェクトに対して実行できる組み込みの機能です。メソッドには二つの種類があります。関数と同じように値またはオブジェクトを返すメソッドと、ステートメントと同じように特定の機能を実行するメソッドです」
多くのメソッドは引数をとるのですが、メソッドが値やオブジェクトを返す場合は引数のリストをカッコで囲み、返さない場合は囲む必要はない。
下のサンプルコードで青い文字の部分がメソッドです。

Sub FindDvd()
   Dim dbs As Database, rst As Recordset
   Set dbs = CurrentDb
   Set rst = dbs.OpenRecordset("DVD", dbOpenDynaset) オブジェクトを返すのでカッコで囲む
   rst.FindFirst "データソース=1"                検索の条件を引数で渡す。カッコは要らない
   Debug.Print rst!タイトル                     これも同じ
   rst.Close                              これは引数の要らないメソッド
   Set dbs = Nothing
End Sub


Page Topへ戻る