<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--リストボックスで複数選択
  1 → 2 → 3



クエリって、いろいろできますでしょう。

MS-Accessみたいな感じの、リレーショナルデータベースって呼ばれる種類のデータベースでは、クエリ(ビューとか論理ファイルとかLFとかいうこともあるね)みたいな感じのオブジェクトをいかに駆使するか・・・そこにすべてがかかっていると言っても過言ではありませんのです(少し過言です)。

さて、今回はそんなクエリの中の、超上級技につてお話を・・・する・・・つもりでいます。
たとえば、フォームにこんな感じのリストボックスがあって、ここからいくつか複数選択して、

リストボックスで選んだ値を含むレコードを抽出するクエリを作りたい・・・と思ったら、みなさんならどんな抽出条件を作ります?
抽出条件欄に、どういうふうに書けば、リストボックスの中のすべての値を参照することができるんでしょう。

Forms!フォームB!リストボックス

・・・これだと多分、”えだまめ”しか認識しないと思うんです。他に”さといも”と”じゃがいも”を選んでますけど、このふたつのことは無視されてしまうんじゃないでしょうか。
あるいは、”えだまめ”も認識してくれないかな・・・。あ、認識してくれないみたいですね。ありゃー。
とにかく、これ、できないんですよ(はやくいえ)

んじゃどうするか、ってことになるんですけど、


 あきらめる

 VBAコードとSQLを駆使する


のどちらかになります。

やめましょう(爆)

いや、まじで・・・あまりにも労力がかかりすぎて、わけもわからず作るよりはあきらめた方が何百倍も安全な場合もありますよ。
どこまでがんばるか、どこであきらめて運用などでカバーするようにするか、その辺の見極めも、データベース作りのひとつの技術です。技術がなければ、この見極めはできないですよね。VBAのコードぶん回すのが上級者じゃないと、わたしは思いますよ。

といってもこれで話が終わりではあまりにもなんですので、ひととおりやってみます。
はっきりいって「これのどこがクエリなの???」って思っちゃうくらいめんどくさいです。
でも、できないことはないですよ。
「クエリの作り方」とか「フォームやリストボックスの作り方」など細かいことは省いてますので・・・そっちの方は、別のコーナーを参考にしてくださいね。


事前準備です。

まず、こんな感じのテーブルがあったとします。名前は「テーブルA」。5つのフィールドがあります。
で、これと構造はまったく同じなんですけど、「素材」というフィールドで絞り込んだ結果をゲットしたいと思っています。


絞込みに、こんな感じのフォームを使います。



フォームはひ連結の無地のフォームをひとつ作ってください。レコードソース欄が空っぽの、基になるクエリやテーブルがない、ただのフォームを作ります。
フォームの色、大きさ、標題などはお任せします。わたしのは、「フォームB」という名前です。


で、このフォームの中に、リストボックスを作ります。リストボックスの中身は、「テーブルB」の「素材」フィールドの中の値が、重複しない(固有の値のみ表示)状態で出てくるようにします。あるいは、値リストということで、えだまめ;えんどうまめ;・・・と、各素材を半角のセミコロンで区切って入力してやります。めんどうですけど、まあ、これでもリストボックスの中身は表示されるでしょう。

あと、コマンドボタンもひとつ作っておいてください。標題はお任せします。
わたしのは、リストボックスが「リスト0」、コマンドボタンは「コマンド2」という名前になりました。

既にご存知のことも多いと思いますので、そういうとこは読み飛ばしちゃってくださいね。



 1)リストボックスで複数選択

リストボックスの「その他」のプロパティを見ましょう。「複数選択」というプロパティがあると思います。
通常は「しない」になってるんで、リストボックスの中をどっかクリックすると、1箇所だけ黒く反転するようになってるんです。
ここを「標準」にすると、いっぱい選べるようになります。


選べます???




 2)ItemSelected

んでは再びデザインビューに戻って、この「複数選択」というプロパティのヘルプを追っかけてみましょう。F1を押します。

下のほうの解説のところに「ListIndex プロパティを使うと、選択した項目のインデックスを取得できます。"MultiSelect/複数選択" プロパティに [Extended/拡張] または [Simple/標準] を設定すると、リスト ボックスの Selected プロパティまたは ItemsSelected コレクションを使って、選択された項目を判断できます。」ってあると思います。このItemsSelectedっていうのがポイントなんですよ。
複数選択した場合、これを使って選択した値を全部ゲットするんですけど、さてそのやり方は・・・。

んじゃ、ItemsSelectedのとこをクリックして、もっと細かい解説を見ましょう。

ItemsSelectedの「使用例」のとこ見ると、なんかサンプルが載ってますよね。いわゆる「VBAで書いたプロシージャの例」です。
これを土台にして考えていきますね。

Sub BoundData()
 Dim frm As Form, ctl As Control
 Dim varItm As Variant

 Set frm = Forms!担当者
 Set ctl = frm!氏名
 For Each varItm In ctl.ItemsSelected
  Debug.Print ctl.ItemData(varItm)
 Next varItm
End Sub

こっちの方。

frmとかCtlとかは、便宜上設定している変数ってやつなので、今回はあんまり気にしなくていいです。
frmというのが、「担当者」というフォーム名のことで、ctlというのが、「担当者」フォームの中の「氏名」という名前のリストボックスのことみたいですね。
どの行のことをお話してるか確認できますか???
ちょっとずつやっていきますけど、どのあたりを書き換えていけばいいか、だいたいの見当をつけておいてください。

ポイントは、For Each varItm In ctl.ItemsSelectedとNext varItmのとこです。
この2行を繰り返すことで、

リストボックス↑の中の、黒く反転しているところを、1行ずつ見ていく、ってイメージになります。

For EachとNextというのは、いわゆるVBAの決り文句です。

For Each おおおお
 へのへの
Next おおおお

という感じで書きます。おおおおのとき、へのへのをやって、つぎのおおおおに移動、という感じでしょうか。わかりにくい?いいえ、きっとわかってらっしゃいます。

Debug.Printというのは、VBAのエディタに用意されているデバッグモードという機能を使って、ほんとにうまいこと選択されてるか確認するための命令文なので、今日は他の方法を使って確認していきますね。


じゃ、ちょっとばかし実験を・・・。コマンドボタンのクリック時のイベントを作ります。


上のコードを参考にして、ほんとにリストボックスの中の選択項目を認識できてるか、まずはそこを確認します。
とりあえず、Ctlという変数に、フォーム内のリストボックスの名前(わたしのはリスト0)を代入して使おうと思うので、1行目で宣言しておきます。

2行目で、AAAという変数に文字を入れて使いたいのでよろしく、と言っておきます。
3行目のsql・・・というのはまだ使いませんけど、一応同じように書いといてください。

リストボックス名(わたしのはリスト0ってなってました。ゼロはなぜか半角の数字だったけど)以外は、全部半角英数字ですので、注意して入力してくださいね。
ドットとかビックリマークとかイコールとかカッコとか、全角で入力しちゃダメですよ。大文字小文字は、どっちでもオッケーです。自動的に調節されます。

で、リスト0の中身を繰り返し見て、AAAという変数の中につぎつぎ書き加えていってくれ、という命令を、For Each ….Nextの間に書きます。

なんで

AAA = AAA & ctl.ItemData(varItm) ってなってるか、わかりますよね。

AAA = ctl.ItemData(varItm) とはちょっと違いますよ。

リストボックスで

 えだまめ
 えんどうまめ
 じゃがいも

って選んでたとしたら、For Each ….Nextの一回目でAAAに”えだまめ”という文字がはいって、2回目で”えだまめえんどうまめ”ってなってほしいんです。
AAA = ctl.ItemData(varItm) だけだと、2回目のとき、1回目に代入した”えだまめ”の上に”えんどうまめ”を上書きしちゃいますよね。

ぜんぜん意味がわからない・・・という方も、今日のところは同じように書いてみてください。
こういうのは慣れですから、今回は書き間違いのないよう慎重に入力していただくとして、ぼちぼち慣れていくとしましょう。

で、AAAの中身をMsgBoxに出します。



では実行してみましょう。VisualBasicEditorのウィンドウは出したままでいいですから、フォームを上書き保存してフォームビューに切り替えてテストしてみましょう。
メッセージボックス、出ました???

この値をそのまま、クエリの抽出条件に使えるといいんですけどねぇ。なかなかそうはいかないみたいです。
でも、とりあえずAAAという変数の中に、今選んでる値をすべて書き込むことができるようになりましたよね。まずは第一関門クリアです。