Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

クエリからフォームのコントロールを参照

1,304 views
Skip to first unread message

佐々木

unread,
Mar 30, 2010, 2:48:01 AM3/30/10
to
クエリーからフォームのコントロールの値を参照し、抽出条件としたいです。

クエリーの該当項目の抽出条件欄に[Forms]![フォーム名]![コントロール名]と
記述をしているのですが、ACCESSのVBAが実行されている最中だと
フォームの値が参照できていないようです。

同クエリをVBAが実行されていない状況で開くと値の参照がきちんと
行えています。

VBA実行中については、
 VBAからコントールの値を埋め込んだSQLをクエリに再設定するという
回避方法はあるかと思うのですが、
今回、旧ACCESSバージョンからのバージョンアップのため、
SQLの再設定を行うという解決方法の場合、
修正範囲が広がってしまう為、現在の実装方法のまま
回避できたらと思い質問させていただきました。


Hotことり

unread,
Mar 30, 2010, 3:56:52 AM3/30/10
to
ことりと申します。

"佐々木" <???@discussions.microsoft.com> wrote in message
news:C3B58D03-2DDD-4E86...@microsoft.com...


> クエリーの該当項目の抽出条件欄に[Forms]![フォーム名]![コントロール名]と
> 記述をしているのですが、ACCESSのVBAが実行されている最中だと
> フォームの値が参照できていないようです。

VBA が実行されている最中だからといって,フォームの値が
クエリから参照できない,ということはありません。

クエリを実行する時点でフォームが開いており,コントロールに
値が入力されていることを確認してください。

それでも問題がある場合は,具体的なコードをご紹介いただく
必要があるでしょう。

佐々木

unread,
Mar 30, 2010, 4:51:01 AM3/30/10
to
ことり様
早速の返信、ありがとうございます。

> VBA が実行されている最中だからといって,フォームの値が
> クエリから参照できない,ということはありません。

私もそのように認識しておりましたので
とても不思議に思っております。

> クエリを実行する時点でフォームが開いており,コントロールに
> 値が入力されていることを確認してください。

以下の通り確認した結果、VBA実行時に値の取得が出来ていないと判断しました。

1.該当フォームを開く。
2.そのままの状態で、ナビゲーションウィンドウから該当クエリーを開く。
  もちろん参照しているフォーム上のコントロールには値が設定されています。
3.その結果、正しい抽出結果が得られます。
  この結果、VBAが実行状態でなければ、フォームの値が取得出来ていると
  判断しました。
4.該当フォームのコマンドボタンのClickイベントプロシージャの宣言部に
  ブレイクポイントを設定
  (フォームはフォームビューで開いたまま、コードウィンドウを表示し
   ブレイクポイントを設定しました。)
5.コマンドボタンをクリックし、ブレイクしたところで
  先程のクエリーをナビゲーションウィンドウから改めて開く。
  この間、フォームのコントロールの値などは画面上からも、コード上からも
  変更しておりません。
6.上記の結果、データの抽出がおこなわれませんでした。
  試しに、クエリーに列を追加しFormのコントロールの値をフィールドとして
  定義し、レコードセットのフィールドとして表示したところNULL値に
  なっていました。
  この結果、VBAが実行状態の場合、フォームの値が取得出来ていると
  判断しました。

> それでも問題がある場合は,具体的なコードをご紹介いただく
> 必要があるでしょう。

プロシージャの宣言でブレイクポイントを設定して実行している為
コードが影響している箇所もないかと思うのですが、いかがでしょうか?

Hot Kotori

unread,
Mar 30, 2010, 8:27:34 AM3/30/10
to
ことりです。

--------------------------------------------------
From: "佐々木" <@discussions.microsoft.com>
Sent: Tuesday, March 30, 2010 5:51 PM
Newsgroups: microsoft.public.jp.access
Subject: Re: クエリからフォームのコントロールを参照


> 4.該当フォームのコマンドボタンのClickイベントプロシージャの宣言部に
>   ブレイクポイントを設定
>   (フォームはフォームビューで開いたまま、コードウィンドウを表示し
>    ブレイクポイントを設定しました。)
> 5.コマンドボタンをクリックし、ブレイクしたところで
>   先程のクエリーをナビゲーションウィンドウから改めて開く。
>   この間、フォームのコントロールの値などは画面上からも、コード上からも
>   変更しておりません。
> 6.上記の結果、データの抽出がおこなわれませんでした。

手持ちの Access 2007 SP2 で確認しました。なるほど,
ブレークポイントで止めた状態ですと,クエリがフォームに
アクセスできませんね。

これは佐々木さんがおっしゃる通りで,フォーム上のVBA
コードの実行中は,そのフォームはロックされた状態に
なるため,他のオブジェクトからはアクセスできないようです。
VBAコードからであればアクセスできます。試しに,ブレーク
ポイントで止まっている状態のまま [Ctrl]+[G] キーで
イミディエイト ウィンドウを開き

? Forms![フォーム名]![コントロール名]

と入力して [Enter] キーを押すと,コントロールの値が
正しく表示されます。

対策ですが,運用上,ブレークポイントで止めた状態で
クエリを実行する,という手順が必要なのでしょうか?

たとえば,

Private Sub コマンド0_Click()
DoCmd.OpenQuery "クエリ名", acViewNormal, acEdit
End Sub

というふうにVBAコードから(止めないで)クエリを実行
すれば(SQLを「再設定」しなくとも)期待通りに実行できます
し,その方が一般的ですが,そういうやり方で回避できない
でしょうか?

佐々木

unread,
Mar 31, 2010, 2:59:01 AM3/31/10
to
ことりさん、昨日に引き続きの返信、ありがとうございます。

> 対策ですが,運用上,ブレークポイントで止めた状態で
> クエリを実行する,という手順が必要なのでしょうか?

今回のご質問のきっかけになったのが、
実はクエリーのオープンではなく、
レポートのオープンがきっかけでした。

VBAで

Docmd.OpenReport レポート名,クエリー名

を実行していまして、レポートの出力結果が正しくないことから
いろいろ調べた結果、どうやらクエリーからフォームの値が参照
できていないことが直接の原因だとなり、
クエリーからフォームのコントロールを参照ということに限定して
ご質問させていただいた次第でした。
(段階を踏んでのご質問となってしまい、申し訳ないです・・・)


さて、ことりさんからご提案のありました

> Private Sub コマンド0_Click()
> DoCmd.OpenQuery "クエリ名", acViewNormal, acEdit
> End Sub

について、試してみました。
DoCmd.OpenQueryだと、正常に動作しますね。
自分としては、この方法自体ダメだと思っていました。

前述しましたとおり、今回は、レポートのOpen時のQuery指定なので、
残念ながらご提案いただいた方法をとることができません。

レポートのOpen時のクエリー指定の場合、
ブレイクポイントを設定せずに(コードの実行を止めずに)実行した場合も
フォームのコントロールの参照が行えていないようで
「実行時エラー 3061 パラメータが少なすぎます。1を指定してください。」
となってしまいます。

もしやと思い、同クエリーをOpenRecordset(クエリー名)で開いたみたところ、
そちらも同じ結果となってしまいました。

やはり解決方法としては、SQLにコントロールの値を
埋め込むしかないのでしょうか・・・。

ちなみにことりさんの回答に

「フォーム上のVBAコードの実行中は,
そのフォームはロックされた状態になるため,
他のオブジェクトからはアクセスできないようです。」

との記述がありましたが、フォームのロック状態というのは
何かのオブジェクトのプロパティーで取得できるのでしょうか?
フォームのロック状態を解除できればコントロールの
値の取得が可能かと思うのですが、
(そもそもロックの解除をVBAから行うことなんて
できないとは思うのですが、)
解決案の糸口になればと思い質問させて頂きます。

重ね重ねになりますが、なにかヒントでも結構ですので
情報がありましたら、ご開示いただけたら幸いです。

Hot Kotori

unread,
Mar 31, 2010, 6:20:52 AM3/31/10
to
ことりです。

"佐々木" <@discussions.microsoft.com> wrote in message
news:C1B7FAA2-4CE9-493B...@microsoft.com...


> レポートのOpen時のクエリー指定の場合、
> ブレイクポイントを設定せずに(コードの実行を止めずに)実行した場合も
> フォームのコントロールの参照が行えていないようで
> 「実行時エラー 3061 パラメータが少なすぎます。1を指定してください。」
> となってしまいます。

ふむ・・ レポートを作成し,イベント「開く時」に

Private Sub Report_Open(Cancel As Integer)
DoCmd.OpenQuery "クエリ1", acViewNormal, acEdit
End Sub

と記述してみました(クエリ1 はフォームのコントロールの値を
参照するパラメータクエリです)。

フォームを開き,コントロールに値を入力した後,フォームを
そのままにしてレポートを開いてみます。

すると,レポートとクエリの両方が開き,クエリの方には,期待
した通りフォームのコントロールの値によって条件抽出された
レコードが表示されました。

問題はないように見えるのですが?

> ちなみにことりさんの回答に
>
> 「フォーム上のVBAコードの実行中は,
> そのフォームはロックされた状態になるため,
> 他のオブジェクトからはアクセスできないようです。」
>
> との記述がありましたが、フォームのロック状態というのは
> 何かのオブジェクトのプロパティーで取得できるのでしょうか?

申し上げた「ロックされた状態」とは,正確な表現ではなく,
VBAコードによって占有された状態を表現したものです。
これは Access の内部動作なので明示的に解除することは
できません。コードの実行が終了すれば自動的に解除され
ます。

> 重ね重ねになりますが、なにかヒントでも結構ですので
> 情報がありましたら、ご開示いただけたら幸いです。

やはり現物を拝見しないと難しいようですが,

1. そのレポートには,フィルタや並べ替えは設定されていま
せんか?

2. なぜ,レポートを開く時にパラメータクエリを実行する必要が
あるのですか?

また,差支えがなければ <hotk...@hotmail.com> 宛に
現物をお送りくださってかまいません。秘密は厳守しますが
データ類は最小限のサンプルを残して削除し,最適化して
圧縮していただけると幸いです。

佐々木

unread,
Mar 31, 2010, 9:29:02 AM3/31/10
to
佐々木です。

ことりさん、いつもありがとうございます。

> > レポートのOpen時のクエリー指定の場合、

すみません。書き方が悪く、正しく伝えられていませんでした。

実際のコードは

フォーム上のコマンドボタンのClickイベントで

Docmd.OpenReport ”レポート名”, acNormal ,”クエリ名”

と記述しています。
「レポートのOpen時」といえば、普通ReportのOpenイベントとのことですよね。
紛らわしい記述の仕方をしてしまい、申し訳ありませんでした。


上記のクエリ名に指定しているのが問題のクエリになります。
実行時エラー 3061はDocmd.OpenReportの時点で発生しています。

試しに、OpenReportの直前でDocmd.OpenQueryに該当クエリを指定して
実行した場合、クエリは正常に実行され、データシートビューが表示されます。
しかし、set rst = CurrentDb.OpenRecordset(クエリ名)を実行すると
OpenReportと同様に実行時エラー 3061が発生します。
(OpenQueryもOpenRecordsetも、本来、機能としては必要ないものなのですが、
 原因の絞り込みを行う為に、試しにやってみたものです。)

ちなみに、OpenReportの際のエラーはReportのOpenイベント発生前に
起きているようです。
Private Sub Report_Openにブレイクポイントを設定して実行した場合、
ブレイクする前にエラーが発生しています。


> これは Access の内部動作なので明示的に解除することは
> できません。コードの実行が終了すれば自動的に解除され
> ます。

そうですよね。了解です。


> やはり現物を拝見しないと難しいようですが,
>
> 1. そのレポートには,フィルタや並べ替えは設定されていま
> せんか?

レポートのフィルタープロパティに対しての設定は行っていません。
前述の通りDocmd.OpenReportの第三引数FilterNameの指定は行っていますが、
こちらはフィルターというより、レポートのレコードソースを指定するニュアンスに近いような気がします。

並び替えは指定しています。

OpenReportの第三引数FilterNameを使用しているのは、
ある条件により出力元となるクエリを切り替える必要があるためです。


> 2. なぜ,レポートを開く時にパラメータクエリを実行する必要が
> あるのですか?

こちらの質問に関しては、前述の記述が不適切だったため、誤解を招いてしまい、
すみませんでした。
出力対象がクエリということであり、Docmd.OpenQueryなどで、
クエリを個別に実行する必要はありません。


今一度、やっている内容を整理させていただきます。

1)Form上のテキストボックスを抽出条件にしていているクエリがあります。
  クエリの抽出条件欄には[Forms]![フォーム名]![コントロール名]の様に記述しています。

2)そのクエリはDocmd.OpenQueryの第三引数FilterNameに指定しています。
  Docmd.OpenReport レポート名,acNormal,"クエリ名"

3)1のテキストボックスが配置されているFormにあるコマンドボタンで、2のステートメントが
  実行されます。

4)2のステートメントが実行されると、実行時エラー3061が発生します。

実機能上、該当クエリをDocmd.OpenQueryで開く必要はありません。
Queryに指定されている内容に誤りがないことを確認するために
(テキストボックス名がフォームに実在しない名前になっていないか等)
実行しています。


> また,差支えがなければ <hotk...@hotmail.com> 宛に
> 現物をお送りくださってかまいません。秘密は厳守しますが
> データ類は最小限のサンプルを残して削除し,最適化して
> 圧縮していただけると幸いです。

ありがとうございます。
送付させていただくのにあたり、若干整理させていただきたいと思いますので
準備ができましたら改めて、メールにて送付させていただきたいと思います。

本件に関して、いろいろご助力いただきありがとうございます。
お手数をおかけいたしますが、よろしくお願いいたします。

Hot Kotori

unread,
Mar 31, 2010, 11:49:50 PM3/31/10
to
ことりです。

"佐々木" <@discussions.microsoft.com> wrote in message

news:3CB59FB1-4E99-400C...@microsoft.com...


> 今一度、やっている内容を整理させていただきます。
>
> 1)Form上のテキストボックスを抽出条件にしていているクエリがあります。
>   クエリの抽出条件欄には[Forms]![フォーム名]![コントロール名]の様に記述しています。
>
> 2)そのクエリはDocmd.OpenQueryの第三引数FilterNameに指定しています。
>   Docmd.OpenReport レポート名,acNormal,"クエリ名"
>
> 3)1のテキストボックスが配置されているFormにあるコマンドボタンで、2のステートメントが
>   実行されます。
>
> 4)2のステートメントが実行されると、実行時エラー3061が発生します。

最小構成で確認してみましたが,再現しませんね。期待通り,レポートには
抽出されたレコードが表示されました。

> 送付させていただくのにあたり、若干整理させていただきたいと思いますので
> 準備ができましたら改めて、メールにて送付させていただきたいと思います。

了解しました。

以後,解決までの間,本件に関してニュースグループへの投稿は控えます。

Hot Kotori

unread,
Apr 21, 2010, 12:37:02 AM4/21/10
to
ことりです。

本件について佐々木様と直接やりとりした結果,現象の原因は
別にあることがわかりましたので,ご報告申し上げます。

0 new messages