<HOME  <お願い事項  <Access2000 TOP   <Access97 TOP   <サイト内検索
  Ac2002--VBAの沼 > データベースに接続してレコードセットを開く
  



データベースに接続してレコードセットを開く

では、まいりましょう。
何かしら新規にデータベースを作成して、その中にひとつ、簡単なテーブルを作りましょう。
2〜3個フィールドがあればいいですよ。なんでもいいです。主キーとかもいらないです。練習なので。

私はこんな感じのテーブルを作ってみました。
では、このデータベースの中で、「テーブルのデータを扱うプロシージャ」をいくつか作成して練習してみましょう。



データベースに接続する

必ず・・・というわけではないのですが・・・。
テーブルのデータをVBAの中で扱う場合は、まず「データベースへ接続」という処理を通過しないとなりません。
同じMDBファイルの中のテーブルでも、外部のテーブルでも、どっちでも、です。
また、クエリもテーブルと同じような扱いをします(集計クエリとかパラメータクエリとかはちょっと別扱いかもしれませんが)。
とにかく慣れないうちは、テーブルにデータを追加したいとか、テーブルのデータを削除したいとか、いわゆる「アクションクエリ」の類と同じようなことをやりたい場合は、必ず最初に「データベースへ接続」するもんなんだと、そう思っておいてください。

今回は、Publicプロシージャを作りましょう。
テーブルのデータを扱うプロシージャなので、わざわざフォームを作ったりコマンドボタンを作ったりしてイベントを起こすきっかけをこしらえるまでもないかな・・・と思うので・・・。

モジュールを新規に作成して、rensyu1なんて感じの名前のSubプロシージャを作成してください。
え?やり方がわからない???
んもーーー!!!
データベースウィンドウからモジュールを新規作成して、VBEのウィンドウが出てきたら左上のツールボタンのリストから「プロシージャ」を選んでください。



■オブジェクト変数

どのデータベース、どのテーブル、どのクエリ・・・など、VBAで各オブジェクトを扱う場合、予め「オブジェクト変数」と呼ばれる変数に代入をしておきます。
普通の変数と同じく、Dimという言葉を使って宣言した変数ですが、中に入るのは数値とか文字とかいうタイプの「値」ではなく、データベースやテーブルそのものが入ります。
そのものが・・・というか、データベースやテーブルの「構造」が代入される、といったイメージになります。

テーブル名やデータベース名が代入されるのではないのです。
ここのところがちょっと、はまりやすいところかもしれないのですが・・・。

例えば、ですね・・・車庫があったとします。
車庫に車を入れるんですが、「カローラ」という名前を書いた紙を置くのと、「カローラ」という名前の車を止めるのとでは、一見どっちも「カローラを車庫に入れた」と言えるかもしれないですが、ぜんぜん違いますよね。
ふつうの変数の場合は、前者と同じ考え方です。つまり「カローラ」という文字列なり数値なりが変数内に入っていれば、処理ができるわけで。
でも、オブジェクト変数の場合は、実際にそのテーブルの中のデータを扱うわけなので、そのテーブルにどういうフィールドがあって、どういうプロパティの設定がされているのか、デザインや構造がわからないとなりません。
「うちのカローラのタイヤの溝の形はどんなだったかしら」と思って車庫に行って見てみると、あれ?「カローラ」って書いた紙しかないよ・・・。これじゃわからないですもんね。
でも、車そのものが入っていれば、タイヤの溝の形を知ることができます。

「そのものが入っている」という表現はちょっと適切じゃないかもしれないですが・・・。「じゃあ2GBのMDBファイルへ接続するときは、変数の中に2GBのMDBファイルが入ることになるの???どうなの???」と言われると、それはそうなんだけど、でも、変数に代入するときに2GBのメモリ容量が必要になるのかというと、そういうわけでもないのです。
少なくとも、「データベース名」や「テーブル名」を代入するための変数ではないのだ、ということだけ、頭のスミに置いておいてください。

オブジェクト変数なんですけども、変数名はわかりやすければなんでもOKです。
ただ、ヘルプとか、入門書籍などについているサンプルコードを見ると、わりかしどれも決まった変数名を使ってますね。

 ■データベースのための変数 : cn、cnn、db、d1、d2.....
 ■テーブルやクエリのための変数: rs、rst、r1、r2.....

別にこうしなくちゃいけない、というわけじゃないんですが、よくこういう名前の変数、見かけます。
なので、こういう名前を使っておくと、案外いいかもしれません。
VBAに慣れている人なら、オブジェクト変数だとすぐ見当が付くから、他の人に見てもらうときなどわかりやすい気がするし。
まあ・・・とにかく、どういう名前でもいいんです。わかりやすい名前を付けてってください。

上の例では、

  「cnという変数を宣言します。この変数は「Connection」という種類のモノを入れるための変数です」

という意味になります。Connectionというのが、データベースへの接続を表す言葉になりますね。
これはもう、決り文句だと思ってください。「なぜConnectionと言うのか・・・」とか言い出すときりがなくなっちゃうので、VBAではこういう言い方をする、と思っておいてください。
多分、VBAをやろう!とお思いになっている皆さんなら、「ADO」って単語を目にしたことがあるんじゃないかと思いますが・・・。ADODB.Connectionで、「ADOというやり方で、Connectionをする」という意味合いになります。
じゃあADOって何なの?というお話になるところですが・・・とりあえず今回は、「ADOというやり方がある」と思っておいてください。
これについてはまた別の機会にお話ができればなぁと思います。



で、次に、この変数に「データベースへの接続」なるものを代入します。
これも、とりあえず今回は覚えてしまってください。

  Set cn = Application.←ここまで入力した後は、こんなふうに↓半角のドットを打つたびにお助けポップアップが出ますから

(変数の宣言の仕方が間違ってなければ)、スペルミスなどの心配はないと思います。
お助け一覧表示から該当のものを見つけて(あるいは直接入力しちゃって)、Tabキーを入力し・・・を繰り返してってみてください。

これで、いつでもデータベースへの接続が可能となります。
正確には、「このMDBファイルの中に作ってあるオブジェクトを扱うことができるようになる」わけなんですね。
  CurrentProject
   ↑Current、というのが「現行」という意味の単語にあたるので、「今使ってるこのMDBファイルへつなぐ」という意味合いになります。
なんかまわりくどいですよねー。同じファイルの中にあるのにさ。
多分、この「まわりくどい感じ」に慣れるまでは、何かに付けて「わかりにくいなー」と思ってしまうかもわからないですね・・・。

もし、外部のデータベースに接続をする場合(他のMDBファイルとか、MS-Access以外のデータベースとか)は、またちょっと書き方が変わってきます。MS-Accessのデータベースなのか、それ以外のデータベースなのか、によっても書き方が変わりますし、それらのデータベースが「どこにあるのか」をきっちり書かないといけないので・・・。ここではお話できないです。今回は「同じデータベースの中のテーブル」をターゲットにした処理、ということで、お話を進めてまいります。



レコードセットの用意

次に、お目当てのテーブルを指定しないとなりません。
これも、テーブル名ではなくてテーブルそのものを変数に入れないとならないので、オブジェクト変数を宣言しておきます。
で、この変数に、「このテーブルを使うよ」と、テーブルを指示しておかないとならないんですが、ここで「レコードセット」という言葉が登場します。この言葉、もしかしたら既にご存知の方も多いかもわからないですが・・・。

「マイクロソフト単語帳」で調べてみると、

【レコード セット】
結果セットの格納に使用される ADO オブジェクトのことである。レコードセットのカーソル動作は、アプリケーションで設定されているレコードセットのプロパティによって決まる。ADO レコードセットは、OLE DB 行セットに対応している。

しくしく・・・。難しい・・・。

この単語、とても解釈の難しいものなんですが・・・
大まかな意味合いとしては、「プログラムの中で扱えるような状態にした、データの集まり」ということになります。
指定したテーブルの中に入力されているデータを、プロシージャの中で扱えるような状態にしてあるオブジェクト、という感じでしょうか・・・。

こんな感じですかね。
これで、「このMDB内に接続して、rensyu1というプロシージャ内で使用するテーブルだかクエリだかを扱うためのrsという新しいレコードセットの準備が整った」という、まあ、そんな感じのコードが書けたことになります。

見易さとしては、DimはDim、SetはSetでまとめて↑おいた方がいいかもしれませんね。

さて、変数の準備が整ったら、実際に「商品テーブル」というテーブルを開きます。
開くといっても、データシートビューの状態で開くのとかとはちょっと違うんですけどね。
rsというレコードセットを、Openメソッドを使って開く、という感じになります。
で、そのときに、「商品テーブル」を扱うんだよ、と書き添えてやります。

こんな感じ。↑左端から順番におっかけてみると・・・

  rsレコードセット: さきほど宣言したオブジェクト変数ですよね。
  Openメソッド: レコードセットを開く、という動作を表す命令語。
  "商品テーブル": テーブル名。そのまんま書いてもVBAでは理解してもらえないので、ダブルコーテーションで囲んでおく。
  cn:データベースへの接続の状態が入っているオブジェクト変数ですよね、これ。
  adOpenKeyset: カーソルタイプの指定。これで「読み取りも書き込みもできる状態で開く」という意味になる。
  adLockOptimistic: ロックの状態の指定。 これで、「レコード単位で共有ロック」状態で開くという意味になる。

最後のふたつは、どういう状態でレコードセットを開くか・・・を表す引数です。
この後、このレコードセットに対してどういう処理をするつもりなのか・・・によって、書き方が変わってきます。
データベースに携わったことのない人から見るとちょっととっつきにくい単語かもしれません。
ちょっとだけまとめますね。でも、今回は上記のふたつをそのまま書けばなんとかなる、と思ってください。
もちろん、正しく指定しないと、余計な処理が発生してレスポンスが遅くなったり、余分なメモリを使ってしまってハングアップする要因になったりしてしまいますから、正しい知識を身につけなければならないところではありますけれど・・・。

★カーソルタイプの指定:
カーソルとは、レコードの移動、データの更新、別のユーザーによるデータベース変更の参照可能範囲を制御するデータベースの要素のことです。この後の処理がレコードセットを読むだけなのか、書きこむのかによって、カーソルをどう動かすか、を決めます。
検索とかレコード件数の確認とかなら、読み込むだけでできることなので、そういう開き方をします。

   adOpenForwardOnly: (デフォルト値)前方スクロールタイプカーソル。
   adOpenDynamic: 動的カーソル。
   adOpenKeyset: キーセットカーソル。
   adOpenStatic:静的カーソル。
   adOpenUnspecified:カーソル タイプを指定しません。

★ロックの種類:
レコードに適用されるロックの種類を表します。ロックとは、「レコードロック」のことで、一般的な解釈ですと「レコードロックとは他のユーザーがレコードの値を編集できないようにすること」です。
ほら、テーブルをデータシートビューで開いて、データの書き換えとかしていると、左端のレコードセレクタ部分にエンピツマークが出ますでしょ?あの時って、皆さんがそのレコード(その一行)をロックしているっていうことになるんですよ。ああいうのを、VBA使ってテーブルを開くときもやるかどうかを、ここで指定します。

   adLockUnspecified  ロックの種類を指定しない
   adLockReadOnly  読取専用(既定値)読み取り専用.データの変更はできません
   adLockPessimistic  レコード単位で排他的ロック。
   adLockOptimistic  レコード単位で共有的ロック。
   adLockBatchOptimistic  共有的バッチ更新。

「動的」とか「静的」とか「他のユーザー」とか「排他」とか、状況を想像しにくい単語が出てきてますね。
プロシージャを作るってことは、たとえ自分のPCのハードディスクの中に作ったMDBで、他の人と共有して使うとかいうことがあってもなくても、いちおうこうしたパラメータは正しく設定しておかないとならないんです。
これを今お話しするとちょっとややこしくなってしまいそうなので・・・また、機会がありましたら、詳しくお話していきます。

で、今回はこんな感じのコードの書き方になります。
これで、「接続先のデータベース(Currentデータベース)の中商品テーブルというテーブルを、rsというレコードセットとして開いた」ということになります。

メソッド、という言葉が、これまた耳慣れない言葉ではないかと思うんですけれど、英単語method(方法とか方式とか秩序とかいう意味)に由来するキーワードです。
rsというレコードセット(この場合は、商品テーブルというテーブルがこの変数に入ってます)に対して、何をするか、何かをする場合に、rsのうしろに何かしら「メソッド」と呼ばれる類のキーワードがきます。今回は、レコードセットをオープンする、という作業をしないとならないので、Openというメソッドを使ってこんな感じで書きます。


なんか、こういうのを理解するのって、ほんとに難しいと思います。
書き方というより、ひとつひとつの要素を日本語で理解してくのって、難しいと思う(かといって英語のが詳しいって訳じゃないんですけど)。
日本語って、言い回しがあいまいなところが多少ありますもんね。
「Openメソッドを使って」とか言ったって、はっきりいって「なんじゃそりゃ」って感じがします。
めちゃくちゃ書いちゃいけませんが・・・・。でも、あんまり細かいところばかり見てると、全体の処理の流れが見えなくなっちゃいそうなので・・・。
細部にあまりこだわりを持たず、キーワード単位ではなくて一行単位で理解していくようなつもりで、取り組んでいかれるといいと思いますよ。




で、最後に・・・。
Openしたら、必ずCloseします。
変数は、プロシージャ抜けたらたいてい空っぽにしてくれるんですが、オブジェクト変数はきちんとCloseしておくようにしましょう。

これがだいたい、テーブルやクエリのデータをVBAで扱う際の、必要最低限の段取りになります。

   ・必要なオブジェクト変数を宣言し(Dim)
   ・各オブジェクト変数にオブジェクトを代入し(Set)
   ・各オブジェクト変数を使って、レコードセットとしてOpenする
        なんかしら処理をして
   ・最後に、各オブジェクト変数をCloseする

と、こういう段取りになります。
どういうオブジェクト変数が必要になるのか、どうやってOpenするのか、は・・・状況によって変わってきますし、書き方も一遍ではありません。
なので、VBAの入門書などのいろんなサンプルコードなどを見て、複数のやり方を理解していくのが理想かもしれませんね。
おっと、忘れてはいけないのが「ヘルプ」です。けっこう「使用例」が出てますから、お金を出して本を買う余裕がない・・・という人は、ヘルプをフル活用しましょう。

さて、これで準備が整いました。
んでは、具体的にテーブルを扱った処理を作ってみましょう。

モジュールは保存しておいたほうがいいですね。
VBEのウィンドウの左上のツールボタン「上書き保存」をクリックして、モジュール自体に名前を付けて保存しておきましょう。
Module1でよいですよ。モジュール自体はプロシージャの「入れ物」に過ぎませんから、とりあえず名前は何でもOKです。