11.VBA+DAOによるテーブル操作
 変更データ指定フォーム・データ入力フォームがとりあえず完成したところで1秒でも早くフォームから入力ができるようにしたい所ですが、その前にVBAを使ってどのようにテーブルの読み書きをするのかを説明したいと思います。以下の内容を読破した上で次の章へ進んでください。ちなみに、ここの章では、まだモジュールを作ったりはしません。

 なお、Access2000をお使いの方は、ここを参考にしながら参照設定を行ってください。参照設定を行わないと、以下で説明するDatabase型やRecoedset型が使えません。
テーブルのオープン
 VBAでテーブルを使うには、まず使用するデータベースをオープンしなければなりません。早い話が、「テーブルを使わせろ!」ってAccessにお願いするのです。だから「コンピュータにお願いするのなんて死んでもイヤダ!」って人は一生テーブルを使うことができません(笑)

 オープンするには、次のような手順で行います。

'Access97、2003での手順
Dim db As Database
Dim tbl As Recordset
'データベースのオープン(データベースオブジェクトの作成)
Set db = DBEngine.Workspaces(0).Databases(0)
'テーブルのオープン(レコードセットオブジェクトの作成)
Set tbl = db.OpenRecordset("住所録テーブル", DB_OPEN_DYNASET)
 ※Access97、2003の場合

'Access2000での手順
Dim db As DAO.Database
Dim tbl As DAO.Recordset
'データベースのオープン(データベースオブジェクトの作成)
Set db = CurrentDb
'テーブルのオープン(レコードセットオブジェクトの作成)
Set tbl = db.OpenRecordset("住所録テーブル", dbOpenDynaset)
 ※Access2000の場合

 いきなり、魔法の呪文のような記述が出てきてしまいましたが、これがテーブルをオープンするためのVBAでの最低限の記述です。Setの部分が実際にオープンを行う部分で、それ以外の部分(Dim)はオープンするために必要な変数を定義しています。
 これだけだと「なんのことだ???で不親切だ!!!」って言われそうなので、簡単に説明します。


(Access97、2003用)
 Dim db As Database
(Access2000用)
 Dim db As DAO.Database

 dbという名前でデータベース型変数を定義します。Accessが作業場に使います。
 なお、Dimとは変数を定義する記述です。これについては「12.データの指定〜入力画面の表示」で詳しく説明します。


(Access97、2003用)
 Dim tbl As Recordset
(Access2000用)
 Dim tbl As DAO.Recordset

 レコードセット型変数の定義、早い話がテーブルから取得したレコードがここへ入ると覚えておけばいいでしょう。


(Access97、2003用)
 Set db = DBEngine.Workspaces(0).Databases(0)
(Access2000用)
 Set db = CurrentDb

 データベースオブジェクトの作成です。早い話が、データベースのオープンです。


(Access97、2003用)
 Set tbl = db.OpenRecordset("住所録テーブル", DB_OPEN_DYNASET)
(Access2000用)
 Set tbl = db.OpenRecordset("住所録テーブル", dbOpenDynaset)

 どのテーブルを使うかという定義です。要はテーブルのオープンです。住所録テーブルを使うのでこうしました。ちなみに、db.OpenRecordsetでは、テーブルやクエリーだけではなく、sqlを書くこともできます。sqlについては、次回のネタで使います。

 ちなみに、DB_OPEN_DYNASET(またはdbOpenDynaset)っていうのは、テーブルとクエリーの両方を扱えて、さらにローカルテーブルもリンクテーブルも使えて、追加も更新も削除もOKという、早い話が何でも来い!の指定です。
 他の記述だと制限があるため、普通はDB_OPEN_DYNASET(またはdbOpenDynaset)で良いでしょう。
 
 なお、DB_OPEN_DYNASET(またはdbOpenDynaset)の他にも次のものがあります。
 
DB_OPEN_TABLE(またはdbOpenTable
 ローカルテーブルのみ扱えます。リンクテーブルなどは使えません。
DB_OPEN_SNAPSHOT(またはdbOpenSnapshot
 DB_OPEN_TABLE(またはdbOpenTable)と基本は同じですが、更新や削除、追加が出来ません。
オープンしただけだと?
 オープンしたばかりの状態ではテーブル中の先頭レコードが使えるようになっています。つまり、先頭レコードを読み込んだ状態(※)なのです。
 あとは、ここから順読み込みで処理をするなり、目的のレコードを検索するなり目的に応じて処理を行います。

 ※レコードが0件のときは、レコードセットはカラッポです。
フィールドの使用方法
 フィールドを使用するには・・・・・・・実はとても簡単です!
 レコード中のフィールドを指定するには、

 Recordsetの変数名!フィールド名

で、行います。上記のオープンの例をもとに、漢字氏名を指定したい場合は、

 tbl!漢字氏名

という記述となり、例えば漢字氏名に「鬼瓦権蔵」をセットしたい場合は、

 tbl!漢字氏名 = "鬼瓦権蔵"

となります。
レコードの検索、検索結果の参照
 テーブルの中から条件に該当するレコードを検索するには、FindFirstメソッドを使用します。FindFirstメソッドを実行すると、条件に合う最初のレコードを読み込みます。
 VBAでの記述は、

 レコードセット変数.FindFirst "検索条件"

 です。検索条件は、フィールド名=値の形式で記述します。
 また、検索条件はAndOrを用いて複数のフィールドを参照した条件を記述することができます。以下が、その例です。

・テーブルから漢字氏名が古畑忍三郎のレコードを検索・取得する。
 tbl.FindFirst "漢字氏名 = '古畑忍三郎'"
 ※FindFirstでの文字列の検索は、(シングルクォーテーション)で囲みます。

・テーブルから、性別が1(男)で関係が2(先輩)のレコードを検索・取得する。
 tbl.FindFirst "性別 = 1 and 関係 = 2"

 また、検索結果については、NoMatchメソッドを使用します。
 レコードセットの変数名.NoMatch

 レコードが見つかった場合はFalse(偽)、レコードが見つからなかった場合はTrue(真)が設定され、通常はIf文と併用して使用します。
 以下の例は、レコードを検索し、検索結果によって何らかの処理を行う例です。

tbl.FindFirst "漢字氏名 = '鬼瓦権蔵'"

If tbl.NoMatch = False Then
  '見つかったときの処理
Else
  '見つからなかったときの処理(True)
End If

※If〜End Ifについては特に触れません。プログラムを作ったことがある人なら、多分わかるだろうから(汗)
レコードの追加
 テーブルへ新しいレコードを追加するにはAddNewメソッドとUpdateメソッドを使用します。AddNewメソッドは、テーブルへレコードを追加するための準備です。レコードを追加するときは必ず実行しなくてはなりません。AddNewメソッドだけでは、実際にはテーブルへレコードの書き込みは行われないので注意しましょう!テーブルへの書き込みはUpdateメソッド(OracleだとCommitに近い)を実行したときに行われます。

AddNewメソッドの記述
 レコードセット変数.AddNew

Updateメソッドの記述
 レコードセット変数.UpDate

 以下は、テーブルへ新しいレコード(鬼瓦権蔵のデータ)を追加する例です。

tbl.AddNew
tbl!漢字氏名 ="鬼瓦権蔵"
tbl!性別 = 1
tbl!関係 = 1
'以下のフィールドは省略
tbl.Update
レコードの書き換え
 レコードの更新は、EditメソッドとUpdateメソッドを使用します。
 更新されるレコードは、現在読み込まれているレコードです。EditメソッドもAddNewメソッドと同様に、Editメソッドのみではレコードの更新は行われません。あくまで、更新のための準備をするだけです。実際の更新は、Updateメソッドが実行されたときとなります。

Editメソッドの記述
 レコードセット変数.Edit

 以下は、レコードの更新例です。鬼瓦権蔵のレコードを検索し変更しています。

'※レコードの有無の確認は省略しています。
tbl.FindFirst "漢字氏名 = '鬼瓦権蔵'"
If tbl.NoMatch = False Then
 tbl.Edit
 tbl!漢字氏名 ="鬼瓦権三郎"
 tbl!関係 = 3
 tbl.Update
End If
レコードの削除
 レコードの削除は、Deleteメソッドを使用します。
 削除されるレコードは、現在読み込まれているレコードです。削除に関しては実行されたときにレコードがテーブルから削除されます。一度削除してしまうとレコードの復活は出来ないので十分注意が必要です。

Editメソッドの記述
 レコードセットの変数名.Delete

 以下は、レコードの削除の例です。鬼瓦権蔵のレコードを検索し削除します。

tbl.FindFirst "漢字氏名 = '鬼瓦権蔵'"
If tbl.NoMatch = False Then
 tbl.Delete
End If
レコードの順読み・逆順読み
 レコードの順読みは、MoveNextメソッドを使用します。逆順読みを行うにはMovePreviousメソッドを使用します。
 順読みとは、現在読み込まれているレコードの次のレコードを読み込むという動作で、逆順読みとは、現在読み込まれている1つ前のレコードを読み込むという動作です。記述は次の通りです。

・順読み
 レコードセット変数.MoveNext

・逆順読み
 レコードセット変数.MovePrevious

 順読みでも逆順読みでも、いつかは最終レコード(先頭レコード)に達してしまいそれ以降の読み込みはできません。そこで、順読み(逆順読み)を行った場合、レコード取得の終了を知る必要があります。
 順読み時はEOF、逆順読み時はBOFでレコードの終了を知ることが出来ます。
 参照できる内容はTrueもしくはFalseで、Trueになったときが読み込みの終了(これ以上、先がない)です。

・順読み時のレコード終了検出
 レコードセット変数.EOF

・逆順読み時のレコード終了検出
 レコードセット変数.BOF
先頭レコード、最終レコードへの移動
 無条件に先頭レコードへ移動するにはMoveFirstメソッドで、逆に無条件に最終レコードへ移動するにはMoveLastで行います。
 利用目的はいろいろ考えられますが、一番便利なのは先頭キーと最終キーを知りたい場合などでしょう。

・先頭レコードの取得
 レコードセット変数.MoveFirst

・最終レコードの取得
 レコードセット変数.MoveLast
テーブルのクローズ
 テーブルに対する処理が終了したら必ずクローズしなくてはなりません。
 オープンしたら、必ずクローズしましょう。開けたら閉める!ドアが開けっ放しだと・・・泥棒が入りますよ(笑)

・テーブルのクローズ
 レコードセット変数.Close
 データベースの変数名.Close

※レコードセットが複数ある場合(複数のテーブルをオープンした場合)は、全てのレコードセットについてクローズする必要があります。
Copyright(C) 1999-2006 結城圭介。 All rights reserved