Q.DAO を使いこなしたいんですけど、どうやって覚えたらいいでしょう?

* Amazon データベース アプリケーション開発関連書籍情報

いや… いまどきこれ言う人いないでしょ… でも一応、歴史として残しておきます。

Access を扱うからには、いえ mdb を扱うからには、DAO が使えなくっちゃダメですよね・・・でもわかりにくいんですよ、DAO って奴はクセが強くて・・・どっから覚えたらいいんでしょうかね?

い、いえダメってことはないですよ(^^;) ただ、Visual Basic から mdb を扱うのであれば、DAO は必須ですよね。
Visual Basic での開発に慣れている方でも、DAO はちょっといまひとつ・・・という方はいらっしゃいますね。
最近では DAO ではないけれども DAO によく似た文法を採用しているミドルウェアもありますから、(ODBCDirect やら RDO やら ADO やら、Oracle の oo4o すら DAO2.0 を元に作られているらしい)覚えておいて損はないと思います。最近は ADO のほうが主流になっちまいましたが…(-_-) 今はもう .Net ですから DAO とか言ってるやつは化石ですが…

なに、これでけっこう、馴染んでしまえば便利な可愛い奴ですよ(^^;;)

まず、DAO とは Data Access Object の略です。SQL データベースに Jet エンジンを介してアクセスする場合に用いられます。
ということは、扱うのは SQL データベースだということ。あたりまえですが、SQL の特性を理解していることが大変重要です。

SQL 文というのは、一回の命令で複数のレコードと任意の数の列を扱います。いままで COBOL や、データベースでない1件ずつ順読みしての処理しかできないデータファイルを扱ってきた方には、この「複数のレコードを一度に扱う」というイメージを理解しずらいと思います。なぼもそうでした。(-_-)

けれど、みなさんは「クエリー」というものをすでに扱っていますよね。クエリーオブジェクトとは、SQL 文を実行するためのオブジェクトです。選択クエリーを実行すれば Select 文が実行され、更新クエリーを実行すれば Update文 が実行されるのです。
すでにみなさんは、1つの命令「クエリーを開く」ことにより、複数のデータを扱っているのです。

ところが、DAO のプログラミングの必要が発生するということは、抽出したレコードを1件読み、複雑な条件判断するなどしてから更新処理なり表示処理なりをしたい。そういうことですよね。
DAO とは、選択クエリーで抽出した結果をプログラム内で1件づつ順番に処理するためにある、と言っても大袈裟ではないでしょう。
…いやまぁ、実際はソレだけじゃないんだけども、やっぱ最初に DAO を使う必要性に迫られるのがソレでしょってことで…(^^;;

DAO というのは、オブジェクト・コレクションの集まりです。Micr○So○t が言うところの「オブジェクト指向」の考え方に基づいた文法で構成されています。(ふ、古い…)
簡単に言うと、オブジェクトの中にオブジェクトがあり、またその中にオブジェクトがあり、とオブジェクトがネストした形になっている上に、プロパティメソッドまでからんできますから初めて見ると混乱してしまい、Helpすら引けずに終わってしまうってこともあるかと思います。
WorkSpace オブジェクトの中に DatabaseS コレクション、Database オブジェクトがあり、その中にRecordsetS コレクション、Recordset オブジェクトがあり、おのおののオブジェクトにはプロパティメソッドがあり・・・と、どれだけ DAO プログラミングに慣れたとしても、Help を見ずにコーディングなどできません。

まず、下の説明を読む前に、各オブジェクトがどのようなオブジェクトを含んでいるか、どのようなプロパティやメソッドがあるのかを Help でひととおり見てください。
Access97 をお使いでしたら、Help のトピックの検索で「workspace」と入力し、「workspace オブジェクト」コンテンツ内の「workspace オブジェクト(DAO)」から見ていくことをお勧めします。ここからたどっていけば、DAO で必要なコレクションとオブジェクトの構成がよくわかります。どのオブジェクトがどのコレクション・どのオブジェクトを含んでいるのかを理解しないと、DAO,ADO でのプログラミングはできません。
最終的に「Recordset オブジェクト」の項まで見ていければいいでしょう。

では、DAO を使ってのプログラミングの手順を説明しましょう。

1. レコードセットを作る

れ、レコードセットって何・・・?レコードセットとは、簡単に言えば「選択クエリーの実行結果」です。
選択クエリーによってテーブルを結合したり条件をつけて絞り込んだり必要な項目だけを表示したり並び替えたり。こんなことはみなさんすでにやっていますね。
このクエリーの結果をプログラムで扱うために、ひとまず「レコードセット」という受け皿にデータを格納します。
選択クエリーをデータシートビューで開いた様子をイメージしてください。まさに、あのままの様子でデータはレコードセットというオブジェクトに入っています。このデータを、上から1件ずつ順番にとりだしてプログラム内で参照するために、レコードセットはあるのです。

2.  いきなりデータの中身が見える!

レコードセットでは、できあがると自動的に先頭のレコードの内容を参照することができます。テキストファイルを扱うときのように、open だの read だの行う必要はありません。できあがったレコードセットは、「読み込む」という動作をしなくても、自動的にある位置のレコードを表示しています。

表示してくれるレコードの順番は、レコードセットを作る時に指定した並び順によって決まります。レコードセットを作るときに並び順を指定していないと、どのデータが先頭に来るかは実行するたびに変わる可能性もあるので注意しましょう。プログラミングでは、データを処理する順番に意味があることが大変に多いですよね。
実際のデータ内容は、レコードセットオブジェクトに従属する項目の中に格納されています。項目名は、元になるクエリーをデータシートビューで開いたときに表示される項目名と同じです。別名をつければその別名が項目名として使われます。

3.  次のレコードに移動する

いままで参照していたレコードの処理が終わったら、次のレコードの処理がしたいですよね。当然そのままではいつまでたっても最初のレコードしかみることができないので、次のレコードへ移動するメソッドを使い、レコードを進めていきます。
これを、レコードセットの最後のレコードの処理が終わるまで繰り返すことになります。

具体的にどう書くかというと、

Dim MyJet As Workspace  
  ↑WorkSpace オブジェクト Access の VBA ではあまり使わないが VisualBasic では必要
Dim MyDB As Database
  ↑Database オブジェクト DAO では自 MDB 以外の MDB も開けるため、どの MDB に対する処理なのか指定する必要がある
Dim MyRS As Recordset
  ↑RecordSet オブジェクト ここに抽出したデータが格納される

Set MyJet = CreateWorkspace(“”, “admin”, “”, dbUseJet)
  ↑まず WorkSpace オブジェクトを作らないと何も進まない(VisualBasic の場合)
Set MyDB = MyJet.OpenDatabase(“なぼ.mdb”)
  ↑それから Database オブジェクトを作る(VisualBasic の場合)
  (Set MyDB = CurrentDB ←Accessの場合はこう書きましょう いっこで済んで便利)
Set MyRS = MyDB.OpenRecordset(“Select 商品コード,商品名 from 商品マスタ where 商品コード like ‘A*'”, dbOpenDynaset)
  ↑ここでいよいよレコードセットの作成

Do while not Myrs.EOF
  ↑MyRS レコードセットの最後のレコードに到達するまで繰り返す

Debug.Print MyRS![商品コード]
Debug.Print MyRS![商品名]

MyRS.MoveNext
  ↑次のレコードへ移動

Loop

ざっと書くとこのようなイメージです。
ここで見てもらいたいのは、赤い字のところ「作ったレコードセットの中に入っているデータの参照のしかた」です。
さきほど、「レコードセットオブジェクトに従属する項目の中に格納されています。」などと訳のわからないことを言いましたが、コーディングしてしまうと赤い字のようになるのです。

ここで作ったレコードセットは、SQL 文を直接与えて作ったダイナセット型レコードセットです。Select 文を実行した結果返される列名で、レコードセットオブジェクト内自動的に項目が作られます
あらかじめ定義などしなくても、MyRS の中に「商品コード」「商品名」という名で項目(Recordset オブジェクトに従属する fields コレクション field オブジェクトです)が作られ、レコードセット名!項目名 の文法でその内容を参照できるのです。
この場合注意してほしいのが、Select 文で指定した列名と MyRS の項目名として参照した名前は、もし一致していなくてもコンパイルエラーにはならないことです。実際にSQL 文を実行してはじめて作られるオブジェクトですので、コンパイルでチェックすることができないのです。

ここでは Recordset オブジェクトに対してフィールドの内容を参照しデバッグ表示することしかしていませんが、AddNew メソッドで新しいレコードを追加したり、Update メソッドでレコード内容を変更したりということもできます。詳しい文法は Help を見てください。
SQL 文では一度に複数のレコードを扱いますが、DAO では一度に複数データを抽出し、多くの場合1レコードづつ順に処理をしていきます。Update メソッドや AddNew メソッドで扱えるのも1度に1レコードだけです。

他に、作成したレコードセットに対しさらに絞り込みをかけるFind 系メソッドもありますが、なぼはお勧めしません。なにしろ遅いし、さらに絞り込むのなら最初に作ったレコードセットの立場がない(^^;)と思うからです。2度も検索処理するような真似はせず、最初っから全部の条件でレコードセットを作った方が効率的だし速度も段違いに速いです。

また、DAO には更新系の SQL 文を実行するExecute メソッドがあります。SQL 文をそのまま実行するので、Delete、Update といった複数レコードを一度に更新できる SQL 命令を実行することができます。
なぼは、Recordset に対して Update メソッドや Delete メソッドは使わず、Execute を使って実行することが多いです。その方が早いんですよね・・・
ただ、Execute メソッドで行った更新結果は、すでに作ったレコードセットには反映されません。(あたりまえ?)
そのレコードセット内に自分の行った更新処理が反映されている必要がある場合、レコードセットを作り直さなければなりませんので気をつけましょう。

この説明はほんとうにまだまだ不十分で、ある一部についてのみ説明しているためによけい混乱する方もいらっしゃるでしょう。ここで述べたことはあくまでも「イメージ」ととらえてください。
DAO や ADO に限った話じゃないんですが、プログラミングって奴は大変に奥が深く、設計・開発する際には Help から離れることはできません。が、まずイメージがわかなくては Help をひくこともできませんよね。

そのためにはまず概要をつかみ、Help に載っている例を真似するなどして実行してみる。それから、詳しいことを調べていくようにするといいかと思います。

プロパティやメソッドなど、最初っから全部覚えておく必要はないんですよ。そのオブジェクトのもつ性質を理解していれば、「このオブジェクトでこんなことできるかも、そういうメソッドないかな」と Help で探すことができますから。