<HOME <お願い事項 <Access2000 TOP <Access97 TOP <サイト内検索 | ||
Ac2002--VBAの沼 > 検索する | ||
1 2 |
さあて・・・。
皆さんの中には、「どうして主キーなんてものが必要なんだろう。主キーっているの?」と、思っている人、います?
他のページでも書いたかもわからんですが、主キーなんてもんは私たちのために作るもんじゃないのです。MS-Accessのために作ります。
例えば、「あげパン」という名前の商品が、3種類あったとします。
検索して1件だけ見つけたいと思っても、この時点でFindメソッドが見つけてくるのは、1件目の300円のあげパンだけです。
あとは、私たちが肉眼で探すしかない。
だからこそ、テーブルの中から必要なレコードを一発で検索できるように「そのテーブルの中で重複しない値を持つフィールド」が、必要になってくるんです。皆さんにとってじゃないですよ。MS-Accessにとって、です。
こうやってテーブルを開いて、眺めてみれば、どこの会社のあげパンなのかとか、値段を見ればだいたい見当がつくかもしれません。でも、それをコンピュータに要求するのは酷です。
そこで・・・もう、こうなっちゃったら、「あげパン」と名の付くものを全部ピックアップしないとならない・・・。
多分、上のテーブルの中の3つのあげパンは、ダブり入力じゃなくて、違う種類のあげパンなんだと思います。
おそらく、3種類のあげパンがこの世にはあるのです。
3つとも、値段が違います。
このテーブルから、MS-Accessに対して「お目当てのあげパン」だけを抽出するように指示できるのなら、主キーなんていりません。
でも、皆さんには探せるものでも、皆さんの探し方と同じやり方をコンピュータに指示することは、おそらく、できませんよね。
だから、こういう場合、絶対ダブりのないフィールドがひとつ、必要になるんです。
で、それを「主キー」にしておくんですよ。決して皆さんのために作るのではないので、何か自分自身にメリットがあるのかしら?と思ってると、到底理解できるもんではないと、そう思ってください。
さて、検索するための足がかりとなるフィールドがない場合は・・・。
考え方を少し変えて「テーブルのレコードを1件ずつ見て、あげパンかどうかEOFまでチェックする」というふうにしましょうか。
テーブルに何件レコードが入っててもいいように、いわゆるループ処理にするわけなんですが・・・。
「テーブルの最初から最後まで」といったループの場合は、Do
….Loop というループ処理が適してます。
Do Until で、「○○になるまで繰り返せ」という意味になります。
で、Loopと書いてある行まで処理を進め、LoopのところでDoに折り返し、処理を繰り返します。
Untilの後ろに、ループを終了させる条件を入れとくんですが(○○になるまで)、これを書き間違えると永久ループになっちゃうことがあります。
また、MoveNextというメソッドをやらないと、永久に1レコード目を読み取りつづけますので、これも注意が必要ですよ。
処理的には、こんな感じですかね↑。
Exit Do というのは、ループ処理の中に書いておくと、ここで「Do Loopを抜ける」ことになります。
これなくてもいけそうな気がしますが、いちおう今まで書いたコードをそのまま継承させて、こんな感じにしました。
ちょっと複雑になりはしましたが、主軸は今まで書いてきたコードそのままですので、じっくり観察しながら書き込んでいってください。
で、このプロシージャを実行すると・・・。
「あげパン」の数だけ、メッセージボックスが出ます。
たくさんメッセージボックスが出るのもうざい・・・という場合は・・・。
1回のメッセージボックスに詰め込んじゃいましょうか。
あらかじめ、何でも入る変数を宣言しておいて、ここに、「あげパン」が見つかるたびに商品名と値段を代入していきます。
似たような処理、前にやりましたよね。
ほら、テキストボックスに数字をどんどん足しこんでく処理・・・変数の使い方は、あれと同じですよ。
結果はこんな感じになります。
え?つなげないで途中で改行したい?
んもー・・・贅沢だなぁ。
んじゃあ、VBEのウィンドウの右上のヘルプで、「文字コード」ってキーワードで検索してみてください。
Chr関数っていう関数がありますでしょ?それ、ヘルプ見てみてください。
中に「キャリッジリターン」っていう例が載ってると思います。
これ、要するに「改行」のことです。
「改行」という文字を表すと、 Chr(13)と書くんだよ、という説明が載ってますよね。
と、こうなります。
この場合の、AAAの中身を考えてみると。。。
1回目の「あげパン」を見つけたとき、変数AAAに入るのは 「あげパン300(改行)」
2回目の「あげパン」を見つけたとき、変数AAAの中身は 「あげパン300(改行)あげパン280(改行)」
3回目の「あげパン」を見つけたとき、変数AAAの中身は 「あげパン300(改行)あげパン280(改行あげパン55600000(改行)
と、なるわけです。
ほら、こうなったでしょ。
え?
商品名と値段を離したい?300円って表示したい?
んもーーーーめんどうなことばっかりーーー
これメッセージボックスなんですから、できることにも限界ありますからねっ。
こんな風にしてみてください↑
すると、↓こうなると思います。
今度はメッセージボックスじゃなくて、イミディエイトウィンドウに結果を出してみましょうか。
こうですね↑
すると、↓こんなふうになります。
仕上げとして、いちおう用心のために・・・。
レコードセットを開いた後、一番最初のレコードにカーソルを移動させておきましょう。
MoveFirstというメソッドを使います。
多分、Openした直後は、1レコード目にカーソルが来ているもんなんだとは思いますが・・・もし万が一のことがあって、途中から検索が始まっちゃったりしたら、正しい結果が出ませんからね。
もし、プロシージャを実行した後、全然反応が返ってこない、あれ?固まっちゃったかな???と思ったら・・・。
永久ループにはまってるかもしれないですね。Do
Loopの書き方や、MoveNextの指定の仕方は正しいですか?
といっても、ループしまくってる状態じゃ確認のしようもないので、こういう場合は強制的にプロシージャを止めます。
止め方は、キーボードのCtrlキーを押しながらPauseキーです。これで、Breakさせることができます。
でも、ちゃんと終了したわけではなくて「中断」なので、決してよいことではありません(システム的におかしくなる、とかいうことじゃないですが)
こういうことが起こらないようにしっかりコードを確認してから実行するようにしてくださいね。
あとは・・・Findメソッドの後ろの条件式をいろいろ工夫すれば、いろいろできるんじゃないかなぁと思いますよ。
こうすれば↓
商品名に対する「あいまい検索」が可能になるし、
こうすれば↓
値段の高いものだけ取り出すことができますよね。
さらに、こんなふうにInputBoxを活用してみても、いいかもしれませんね。
こうしてテストを繰り返しているだけでは、なかなか実感が湧かないかもしれませんが・・・
今やっていること(Findメソッドで検索する)は、あくまでも「テーブル内にその条件を満たすものがあるかどうか」を探すことであって、フォームやレポートといったところに出力するための処理ではありません。
この辺がちょっと・・・理解しにくいところかもしれないですね・・・。