Visual Basic 6.0 データベース講座 |
![]() |
Visual Basic 中学校 > VB6 データベース講座 >
第3回 レコードの移動
今回からは「自分流」のかっこいいデータベースソフトを作っていきます。題材はいままでどおりの動物データベースで、やはりAnimals.mdbを使用しますのでダウンロードしていない方は第1回の講座からダウンロードできるようにしてありますので準備を整えてください。
1.かっこいいソフトとは
前回まで作ってきたソフトはこの講座の位置づけでは「練習用」あるいは「勉強用」です。データベースアプリケーションとはどういうものかをごく簡単に体験していただきました。
今回からはちょっとしたかっこいいデータベースソフトを作って行きたいと思います。
ところが「かっこいい」の基準が人によって異なるのは問題です。たとえばこの講座の中で私がラベルやコマンドボタンの座標まで示していく方法もありますが、やはりみなさん自分のセンスでレイアウトや色・機能などをデザインしたいでしょう。
そこで、このデータベース講座では「かっこいいソフト」の作り方を説明するのではなく、「かっこよくできるソフト」の作り方を説明していきます。
…こんな具合で持論を展開していってもいいのですが、ここに来ている皆さんはこんな話よりもデータベースプログラミングがしたいと思いますので「かっこよくできるソフト」の意味の解説は当連載をもって明らかにしていきたいと思います。
1つだけいっておきますと、これからはADODCは使用しません。あれをつかっているかぎりはかっこよくできません。但し、VisibleをFalseにして使う場合はあるかもしれません。
別にかっこわるくてもいいからADODCの使い方が知りたいと思う方もいらっしゃるとおもうので、書いておきますが「ADODCが実際のプログラムに使われることはほとんどありません。」但し、ちょっとしたミニプログラムや、ごく簡単なデータベース制御しかしないプログラムには使われることもあります。
2.データベースアプリケーションの流れ
前回まではデータベースの操作にはADODCを使っていました。ほとんどの作業はADODCが自動でやってくれたのでプログラマはほとんどコードを書く必要がなかったのですが今回からはADODCをつかわないつもりなので今まで書く必要のなかったコードをプログラマが書く必要があります。
このことは「かっこよく」すること以上に重要です。実際、ADODCが使えない場合も多いので自分でコードを書けてこそ「私はデータベースプログラミングができます」と堂々といえるようになるのです。
では、ADODCを使わない簡単なデータベースプログラムのサンプルをご覧に入れましょう。
みなさんも実際にサンプルを打ち込んで(またはコピーして)試してみてください。
但し、このサンプルを実行するにはADODBというものに参照設定する必要があります。参照設定するには[プロジェクト]メニューの[参照設定]から、Microsoft ActiveX Data Objects 2.7 Libraryをチェックします。なお、2.7は単なるバージョンですのでこの部分の数字が少しくらい違っていてもかまいません。
画像1:ADOへの参照設定 この画像のようにバージョンの違うADOが複数ある場合は最新のものを選択するとよい。なお、今回からWindowsXPを使っている。
今後はこのMicrosoft ActiveX Data ObjectsのことをADOと書きますので注意してください。ADOは一般的に用いられている名称なので世間でも安心して使えます。むしろ、ADOの正式名称(Microsoft ActiveX Data Objects)の方を知らない人が多数派でしょう。
参照設定が終わったらコマンドボタンを1つはりつけて次のコードを打ち込んでください。
Private Sub Command1_Click() Dim Con As New ADODB.Connection Dim Rs As ADODB.Recordset Dim MDBFileName As String '■A データベースに接続 MDBFileName = "C:\Database\Animals.mdb" Set Rs = New ADODB.Recordset Rs.MoveFirst Rs.Close |
できたら、実行してみてください。コマンドボタンをクリックすると動物の名前が表示されることと思います。多分「イモリ」が表示されるのではないでしょうか?環境によって違うので「イモリ」以外の動物が表示された場合も失敗ではありません。
これが本当に小さいデータベースプログラミングのサンプルです。
では、内容を見て見ましょう。
まず、3つのDim文があります。上の2つは As ADODB.Connection, As ADODB.RecordSetというように見慣れない型を 使っているのがわかると思います。
これが最初に参照設定したADO(ActiveX Data Objects)が提供しているオブジェクトで、データベースの操作を担当します。
■A の部分では早速 Connectionオブジェクト(コネクション) Con を使ってデータベースに接続しています。このようにデータベースを操作する前にはまず、Connectionオブジェクトを使ってデータベースに接続する必要があります。
具体的にはConnectionオブジェクトの Openメソッドを使います。Openメソッド自体はとても簡単で、この例のように Con.Open などとするだけですが、これだけではもちろんエラーになります。「どのデータベースにどのように接続するのか」を指定していないからです。
「どのデータベースにどのように接続するのか」は、同じくConnectionオブジェクトの ConnectStringプロパティを使ってあらかじめ設定しておきます。
この例では "Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=" & MDBFileName という長い文字列を設定していますね。はっきりいってこれは「おまじない」だと思ってください。テキストファイルか何かにこれをはりつけて大事に取って置いてください。とにかく、この魔法の文字列を設定することによりデータベースに接続できるようになるのです。このようにConnectStringプロパティに設定するデータベースへの接続を表す文字列のことを「接続文字列」と言います。
一応、データベースのMDBファイルを指定する方法だけは説明しておくべきでしょうか。見ればわかるのですが接続文字列の最後に Data Source= という部分がありますね。この右側にMDBファイル名を指定すればOKです。この例ではMDBファイル名は前もってMDBFileNameという変数に代入して、接続文字列の最後につなげています。
説明が長くなるのですが、実はみなさんが接続文字列に遭遇するのはこれが初めてではありません。この講座の第1回や第2回にも接続文字列がでてきています。但しそのときはADODCのプロパティページを使って接続文字列を自動的に生成しています。このことを逆手にとって、最初はADODCを使って接続文字列を自動的に生成しておいて、それをコピーしてプログラムに貼り付けて、ADODCを削除するという技もあります。
とにかく、接続文字列はいろいろあるのでとても覚えられるものではありません。ADODCが自動的に作ってくれるのだからそれを利用してしまいましょう。「接続文字列を覚えている」ということと、「接続文字列を作成できる」ということはこの場合等価です。
次に、■B の部分でレコードセットを取得します。この作業は何かというと、データベースの中のどのテーブルを操作するのか指定するということです。前回までに説明したようにデータベースの中には複数のテーブルがあることがほとんどです。ですから、データベースに接続しただけですぐにデータを操作できるわけではありません。具体的なデータを操作するにはどのテーブルを 対象にするのか指定しなければならないのです。
というのが初心者向きの説明です。どうせ後で解説することになるので今書いてしまいますが、レコードセット=テーブルではありません。つまりレコードセットにはテーブル以外のものも指定できるのです。具体的にどのようにするかはそれがでてきたときに説明します。そういうわけで、初心者の方には紛らわしいことと思いますが、データベース用語では「レコードセット」と「テーブル」を分けて使うのです。但し、この例ではテーブルをレコードセットに指定しているので両者は同じものだと思って構いません。
なお、レコードセットは一度に1つしか指定できないわけではありません。それと同様にデータベースも一度に1つしか接続できないわけでありません。それで、レコードセットを開く(指定する)場合には、どのデータベースのレコードセットなのかを指定する必要があります。それが、Rs.Open "T1_動物マスタ", Con の部分です。一番後ろの変数Conは先ほど出てきたConnectionオブジェクトです。
これで、やっとレコードを操作する準備が整いました。今回はADODCを使わないでどのようにデータベースを操作するかという点に主眼があるので、単純に最初のレコードを表示するだけで満足しておきましょう。それが ■C の部分です。
Rs.MoveFirst
MsgBox Rs("名前")
Rs というのは先ほど開いたレコードセットを表すレコードセット型の変数ですね。Rs.MoveFirstはカーソルを最初のレコードに移動させろという命令です。「カーソル」というのもデータベース用語ですが、さしあたっては難しいことはありません。ワープロで文章を書く時にもカーソルは出てきますし、Windowsのマウスもカーソルの一つです。要するに目には見えないけどあんなようなものがレコードセットには必ず一つあるのだと思ってください。そして、レコードセットを開いたときにはカーソルは適当な位置にいますので、それを先頭に移動させるということです。
MsgBox Rs("名前") は「名前」フィールドの値を表示せよという命令ですね。しかし、T1_動物マスタにはたくさんのレコードがある(たくさんの動物が登録されている)ので、「名前」といってもどのレコードの名前フィールドなのかこれだけではわかりません。
このように「どのレコードなのか」という指定をしなかった場合はカーソルのあるレコードを指定したものとなります。そして、最初にRs.MoveFirstでカーソルを先頭に移動させましたから、ここでは一番先頭のレコードの名前フィールドの値が表示されるのです。
ところで、実のところ「どのレコードなのか」自分で指定する方法はないので、この例のように常にカーソルを移動させることによってレコードを指定することになります。そのためデータベースプログラミングではカーソルの制御は重要です。
なお、「先頭のレコード」といってもレコードに順番があるわけではないので、どれが先頭かはプログラムを実行するまでわからないし、実行するたびに違うレコードが先頭になるかもしれません。レコードセット内でレコードの順番は「指定しない限り」適当なのです。そして、今回はレコードの順番を指定していないのでレコードは適当に並んでいます。(というのがマイクロソフト社の公式資料なのですが実際には でたらめながらも毎回同じ順番で並ぶようですね)。
さて、最後の ■D の部分です。この部分は後始末を担当します。データベースに限ったことではないのですが、VBではSetで生成した変数は用が済んだら必ずNothingにしましょう。また、RecordSet(レコードセット)やConnection(コネクション)は開いたら閉じましょう。それをやっているのがこの部分です。
RecordSetとConnectionを閉じる順番に注意してください。先にConnectionを閉じるとRecordSetが閉じられなくなります。これは、先に家の鍵をかけると、あとからガスの元栓を締められないのと同じです。
3.レコードの移動
それでは、今度はレコードを移動できるようにしましょう。つまり最初のレコード以外も表示できるようにするのです。
今作ったプログラムに次のようにコントロールを追加してください。
名前 | 種類 | プロパティ | プロパティの値 |
cmdNext | CommanButton | Caption | > |
txtID | TextBox | Text | (空にしてください) |
txtName | TextBox | Text | (空にしてください) |
txtMoku | TextBox | Text | (空にしてください) |
配置はみなさんにまかせます。できるだけかっこいい配置にしてください。
そして、プログラムを次のように改造します。結構大幅な改造になっています。面倒くさい人は新しくプロジェクトを作成してもよいでしょう。
Dim Con As New ADODB.Connection Dim Rs As ADODB.Recordset Private Sub ShowData() '■C レコードの表示 txtID.Text = Rs("動物ID") txtName.Text = Rs("名前") txtMoku.Text = Rs("目名") End Sub Private Sub cmdNext_Click() '■E カーソルの移動 Rs.MoveNext 'カーソルを次のレコードに移動 Call ShowData End Sub Private Sub Form_Load() Dim MDBFileName As String '■A データベースに接続 MDBFileName = "C:\Database\Animals.mdb" Con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=" & MDBFileName Con.Open '■B レコードセットの取得 Set Rs = New ADODB.Recordset Rs.Open "Q1_動物一覧", Con, adOpenStatic Rs.MoveFirst 'カーソルを先頭に移動 Call ShowData End Sub Private Sub Form_Unload(Cancel As Integer) '■D データベースから切断 Rs.Close Con.Close Set Rs = Nothing Set Con = Nothing End Sub |
さて、一読してわかりますでしょうか。cmdNextをクリックすると次のレコードに移動できるようになっているのですが・・・。
■A、■B、■Dの部分は最初の例とほとんど一緒です。但し、■Bの部分で開くテーブルの名前が「T1_動物マスタ」ではなく「Q1_動物一覧」になっている点に注意してください。これは、画面に動物の属する「目」も表示したかったからです。
■Cの部分は全面的に変わっています。先ほどは気軽にMsgBoxで表示していただけですが、今回はフォームに表示したいのでこのようになりました。内容は難しいことはないと思います。
■Eの部分は新設です。この部分がカーソルを次のレコードに移動させている部分です。これもごくかんたんで、RecordSet(レコードセット)に対して、MoveNextメソッド(ムーブネクスト)を使用するだけです。MoveNextしたら、画面の表示が自動的に変わるわけではないのでCall ShowDataのように自分で画面の表示も更新します。
どうでしょう。カーソルを戻したりはできませんが、だいたいADODCを使って作ったアプリケーションと似てきたと思いませんが。そして、中身は自分で記述しているので好きなようにカスタマイズできます。四角いボタンがダサいと思う人は自分でかっこいいボタンを作ることもできます。ボタンの色を変えるくらいのことは誰でも簡単にできますし、表示する文字もご自由です。このようにADODCから開放されたとこによって、プログラマはより「自由」で、より「かっこよくできる」プログラムを作ることができるようになるのです。
4.レコードの終わり
次のレコードが表示できるだけで、前に戻ったり。登録を変更したりはできないのですが最初のプログラムとしてはこんなものでしょうか?しかし。気がついた方もいらっしゃるかもしれませんが重大なバグあるのです。ボタンをクリックしてどんどん次のレコードを見ていくといつかは最後のレコードが表示されるわけですよね?では、そのとき、さらにボタンをクリックして次のレコードを表示しようとしたらどうなるのでしょうか。ぜひ試してみてほしいのですが、結論を言うとやはりエラーが出ます。私のWindowsXPとVB6の環境では「BOF と EOF のいずれかが True になっているか、または現在のレコードが削除されています。要求された操作には、現在のレコードが必要です。」というメッセージが表示されました。なんとなく「もうレコードはない」という意味がわからないでもないですね。
そこで、最後の場合にはボタンをクリックしても何も起こらないか、最初のレコードを表示する(つまりぐるぐる回る)ように改造しましょう。ここでは最初のレコードに戻る例を紹介しましょう。cmdNext_Click()プロシージャの内容を次のように変更してください。
Private Sub cmdNext_Click() '■E カーソルの移動 Rs.MoveNext 'カーソルを次のレコードに移動 If Rs.EOF Then Rs.MoveFirst '<<この行を追加する。 Call ShowData End Sub |
これでためしてみるとうまくいくはずです。では、If Rs.EOF Then Rs.MoveFirst とはどういう命令かというと「もし、Rsのカーソルの位置がEOFならカーソルを最初に移動せよ」という意味です。
ここででてくる、EOFプロパティ(イーオーエフ)はデータベースを扱う上でしばしばでてくる大切な要素です。
EOFとはいうのは「最後」という意味です。(End Of File)。但しちょっと間違えやすいのですが、EOF状態のときにはすでにレコードは無効です。いうなれば「最後のレコードの次にカーソルを移動するとEOF状態になる」ということです。
ですから、MoveNextの次にEOFかどうか聞いているのです。EOF自体はエラーではありません。われわれが今見たようなエラーに対応するためにあみだされたプロパティなのです。
EOF状態のときにレコードの内容を表示しようとしたり、カーソルを次へ移動させたりするとエラーになります。先ほど試したエラーは「EOF状態のときにレコードを表示しようとした」ために発生したエラーで、EOF状態のときにカーソルを移動させようとしたためにでたエラーではありません。そこのところを間違えないようにしてください。
それから、併せて覚えておくといいのですが、一番最初のレコードより1つ前にカーソルを移動するとBOF状態になります。これはEOF状態とほぼ同じです。
5.RecordSetオブジェクト
さて、今の例でRecordSet型のオブジェクトである rs に注目します。(RecordSet型のオブジェクトとは Dim rs As RecordSet のように As RecordSetで宣言されたオブジェクトなどをさします)。
今の例には Open、 MoveFirst、 MoveNext、 EOFなどレコードセットオブジェクトでよく出てくる代表的なメソッド、プロパティのいくつかを使いました。このレコードセットオブジェクトはVBでデータベースを操作するときは必ずといっていいほど使用するオブジェクトなのでここで、他の代表的なものも含めてまとめて紹介しましょう。
メソッド/プロパティ | 読み方 | 説明 |
BOFプロパティ | ビーオーエフ | カーソルが先頭のレコードより1つ前あるときTrue。 |
EOFプロパティ | イーオーエフ | カーソルが最後のレコードより1つ後ろにあるときTrue。 |
AddNewメソッド | アドニュー | 新規登録。 |
Closeメソッド | クローズ | レコードセットを閉じる。 |
MoveFirstメソッド | ムーブファースト | カーソルを最初のレコードに移動する。 |
MoveLastメソッド | ムーブラスト | カーソルを最後のレコードに移動する。 |
MoveNextメソッド | ムーブネクスト | カーソルを次のレコードに移動する。 |
MovePreviousメソッド | ムーブプレビァウス | カーソルを前のレコードに移動する。 |
Openメソッド | オープン | レコードセットを開く。 |
Updateメソッド | アップデート | 変更を登録する。 |
6.宿題
「宿題」とは片腹痛いかもしれませんが、当講座でデータベースプログラミングを勉強している人はまぁつきあってみてください。宿題の内容は次のとおりです。
1.今回紹介したサンプルをもとにして、カーソルを前に移動する機能、先頭に移動する機能、最後に移動する機能をつけましょう。もちろん、EOFやBOFでエラーが発生しないように工夫してください。
ヒント:MovePrevious, MoveLast, BOFを新たに使うことになると思います。
2.1で作成したプログラムをかっこよくしてください。(どんな手段を使っても結構です)。
宿題の模範解答(こたえ)は次回掲載する予定です。
7.最後に
次回は、レコードの更新、新規追加、削除などをやりたいと思います。レコードを順番に並べる方法も知っておいて方がよさそうですが、これはもうちょっと後ですかね。私としてははやいとこ画像を表示できるようにしたいので。やはり画像が表示できるようになるとプログラムもぱっとします。
それでは、失礼します。