- ベストアンサー
Access97VBAでのFilter方法
・初歩的な質問でスミマセン。 Access97のVBAでツマヅキ、何か解決の方法はないかと思い質問させていただきます。 クエリー1を元にして作成した、開いている「フォームA」の「テキスト1」(テキストボックス)の文字列でフィルターをかけたいと思っています。 下記のコードを書き実行するのですが、フィルターがかからずクエリー1のデータがそのまま抽出されてしまいます。 Filterコマンド行の記述が間違っているのでしょうか? * クエリ1に「フォームA」の「テキスト1」ボックスを参照する抽出条件を入れてたのですが、「パラメータが少なすぎます。・・・」のエラーとなるので、この方法で行っています。 * Private Sub コマンド6_Click() Dim stTBL, stFltr As Recordset Dim stQRY As DAO.Recordset Set stQRY = CurrentDb.OpenRecordset("クエリー1") stQRY.Filter = "テキスト1='" & [Forms]![フォームA]![テキスト1] & "'" Set stFltr = stQRY.OpenRecordset stQRY.MoveFirst Do Until stQRY.EOF MsgBox stQRY.Fields("フィールド2") stQRY.MoveNext End If Loop 以上のようなんですが、どうかご指導お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#2です。混乱してしまったので、まずは整理させて下さい。 [フォーム1]と書かれていますが、質問文の[フォームA]のことでしょうか? なさりたいのは、[テキスト1]で[フォームA]を絞り込むと同時にMsgboxで[フィールド2]を表示する、つまり、#1の方のご回答と#2をあわせたものですか? 上記と仮定して続けます。 先に[フォームA]にフィルターをかければ、Msgbox表示用にはMe.RecordsetCloneをそのまま使えるようになるので、次の形でいかがでしょうか。 ------------------------------------------------------------ Private Sub コマンド6_Click() Dim stFltr As DAO.Recordset 'フォームAのレコードを絞り込む With Me .Filter = "テキスト1='" & [Forms]![フォームA]![テキスト1] & "'" .FilterOn = True End With '絞り込み後のフィールド2をメッセージ表示する Set stFltr = Me.RecordsetClone stFltr.MoveFirst Do Until stFltr.EOF MsgBox stFltr.Fields("フィールド2") stFltr.MoveNext Loop End Sub ------------------------------------------------------------ (的外れかも(^^;)。もう少し実際の形に近い説明を頂けるとありがたいです。) 別件◆解説書 私はVBから入ったのであまり使いませんが、知人にすすめる時は、1)Access添付ヘルプ、2)小技集、3)リファレンスブック、4)サンプルデータベース集、の順です。 ◇1)のヘルプを使いこなし、使用例や関連項目にも合わせて目を通すようにすれば、かなり理解が深まります。例えば「stQRY.Filter」と入力した直後に[F1]キーを押せば、#2の※印で解説した内容に行き着きます。 ◇ヘルプの使用例が物足りない時は、2)の小技集(一問一答式で例文と解説が短く記述されているもの)を。できるだけ項目数の多いものを選べば、目次でしたいことを探して例文を手に入れられます。 (ISBN4-7741-0835-9 技術評論社「Access2000 表現百科500」など) ◇ヘルプ操作が面倒な方は、3)のリファレンスブック(辞書のようなもの)を。 (ISBN4-8163-2818-1 ナツメ社「Access2000 VBAハンドブック データ操作編」など) ◇目的がはっきりしているなら、それに似た例題のある、4)のサンプル集(CD付)を探すのも良いでしょう。 (ISBN4-7741-1152-X 技術評論社「Access2000 プロが作った!お手本データベース41選」など) この他に、データベース設計の基本をおさらいしたり、SQLが書けるように、この機会に中上級者向けの論述型の書籍を一読なさるのも良いと思います。 (ISBN4-8222-0930-X 日経BP社「実践Accessデータベース上級テクニック」など)
その他の回答 (2)
- holly2001
- ベストアンサー率75% (25/33)
ご苦心の後が解ります。お手本の丸ごとコピーでなく、ご自分で調べて書かれたんですね。 なので、できるだけ原形を残しましょう。 (行番号は、「Private Sub~」から、空の行を飛ばして数えて下さい。) Line2:「stTBL」は、使われていないので削除。 「stFltr」は、フィルターをかけたRecordsetですね。ここにも「DAO.」をつけておきましょう。 Line4:クエリー1は、このプロシージャ(コマンド6_Click)の呼出元(フォームA)で使っています。 この場合は一般的に「自分自身(フォームA)のレコードソースのコピー」という意味で、 「Me.RecordsetClone」をSetします。 Line6:「stQRY」を使っていますが、5行目でフィルターがかかったのは「stFltr」です。(※) これ以降の6~9行目は全て「stFltr」に書き換えて下さい。 Line10:「If」が無いので、この行は削除。 (※)この6行目がネックです。 1つめのRecordsetオブジェクト(stQRY)のFilterプロパティを設定しても、stQRYに含まれるレコードは減りません。 「stQRYを元に開く、新しいRecordsetオブジェクトが、stQRYのうちFilter条件に合うレコードを取得する」だけ、要は「次に開くヤツにフィルターかけてね」という予約みたいなものです。 つまり、実際にフィルターがかかるのは、2つ目のRecordsetオブジェクト(stFltr)です。 さて、あえて修正後のコードは書きませんが、うまく行ったでしょうか?もし駄目なら返信して下さい。 あとは、本筋に関係無い、細かい話です。 (1) 変数名は、先頭の2~3文字に、タグと呼ばれる変数の質を表す略語をつける習慣があります。 「stQRY」なら「st」がタグにあたるようですが、これだとString(文字列型)に見えてしまうので、 Recordsetなら「rsQRY」の方が解りやすいです。 (ちなみに、本当にString型の場合は「str」をつける事が多いですが、これはお好みで。) (2) 変数名はもちろんですが、クエリ・フォーム・フィールド名など、VBA内で使う要素は、 全て英数字にした方が安全です。 2バイト文字(日本語など)を使うと、解析困難なエラーなど、思わぬトラブルの引き金になります。 同じ理由で、ユーザーアカウント・フォルダ・ファイル名も、日本語は好ましくないようです。 なお、目的が「コマンドボタンを押すと、フォームAにフィルタをかけた状態にする」なら、 #1の方の回答が簡潔で素晴らしいと思います。
お礼
・有難うございます。各行ごとの詳細な解説まで戴き、本当に感謝しています。これからご説明いただいた内容を確認していきます。この場をお借りしてはなんですが、ご回答いただいたような噛み砕いた解説書などをご存知ですか?良い書籍があったらお教えください。 取り急ぎお礼まで・・。
補足
・お教えいただいた結果で上手く絞り込みができました。関連で今ひとつ上手くいきません。 フォーム1はサブフォームで、このプロシージャはフォーム1を開くイベントに付いています。 stFltrをsetしたあとのメッセージ表示(Msgbox)などは、フィルタが有効になり、絞り込まれたレコードが抽出出来ました。(有難うございます) ただ、今開いているフォーム1はクエリー1をレコードソースとしているためか、クエリー1の全レコードが表示されています。実はこのフォーム1にはstFltrの結果を表示したいのです。 そこで、stFltrをフォーム1のレコードソースにすべく「Me.Recordsorce = stFltr」としましたが、文字列ではないので、当然エラーとなってしましました。 また、stFltrのあとに「FilterON = True」も試しましたが上手くいきません。 レコードソースを変更する方法をお教え願えませんでしょうか? #1で教えて戴いた方法を使えば絞り込まれた結果となりますが、その後処理で各々のレコードにある、別のフィールドにプローシジャで処理したテキストを 追加しようと思っています。(Do Until stFltr.EOF .... LOOP を使い)ですから、stFltrの結果を有効にしたいのです。 以上、よろしくお願い致します。
- redsky
- ベストアンサー率18% (66/360)
単純に、 Private Sub コマンド6_Click() Filter = "テキスト1='" & [Forms]![フォームA]![テキスト1] & "'" FilterOn = True end sub ではダメなんですか??
お礼
・出来ました。この感じで良いです。如何せん、コマンドの意味や機能をあまり理解しないで作っていますので、本当に必要なもの、逆に不要なものの区別が出来なくなってしました。有難うございました。
お礼
・丁寧なご回答ほんとうに有難うございます。 Set stFltr = Me.RecordsetCloneで、すでにフィルタをかけた状態のレコードセットになると解釈しました。ご紹介いただいた「本」などを見つけ、今後もコツコツ勉強していきます。