お世話になります。
Private Sub Report_NoData(Cancel As Integer)
Cancel = True
End Sub
上記のようなイベントを持つレポート(レポート名はR_Reportとします)を、
フォームに配置したボタンのクリック時イベントで開くと実行時エラーが出ます。
Private Sub btn_1_Click()
DoCmd.OpenReport "R_Report", acViewPreview
End Sub
ボタンを押し、レポートが空ならメッセージもエラーも出さずに開かないようにしたいのですが、空データ時イベントやクリック時イベントにどのようなコードを記述するのがいいのでしょうか。
DoCmd.OpenReport でレポートを開くのに失敗するので実行時エラーが発生します。そういう仕様です。
エラー処理を追加しましょう。
メッセージも何も出さないのなら、
ボタンにこのコードを書く場合、レポートの空データ時イベントは不要ですか?
また、複数のレポートを開く場合、レポートの数だけこのエラー処理を書く必要がありますか?下記のような書き方をする必要がありますか?
必要です。ないと、空のレポートが開きます。
複数レポートの場合は、On Error Resume Next は最初に一つだけでもOKです。
ただ、いまさらですが、
On Error Resume Next にしてしまうと、どんなエラーでも無視してしまうので、
空データ以外のエラーが発生した場合、気がつかないので推奨しません。
コード例
hiroton的にはそもそもエラーを出さないほうが好きですね
先にレポートに表示されるレコードの件数を調べて0ならレポートを開かなければいいので。VBAのエラー処理に悩まされるよりはよっぽど楽だと思います
わたしもできればそうしたいです。
使うのはDcountでしょうか?
もっとも単純な例であれば、レポートのレコードソースに指定しているクエリ(テーブル)から
Dcount
でレコード数を取得すればいいですね※レポートのレコードソースに「Q出力」を指定している場合
レポートのレコードソースの作り方によっては
DAO
でレコードソースを生成するなどの手法が必要になるかもしれませんありがとうございます。
レポートのレコードソースはクエリビルダーで作成されているのですが、この場合はDAOというものを使う必要があるということでしょうか?
また、このパターンだと、レポートの空データ時イベントは不要になりますか?
エラーがでないように事前チェックするか、
エラー処理で対処するか、
どちらがいいかはその時次第でしょうね。
プログラマーの考え方にもよりますが。
空データ時でキャンセルした場合は、実行時エラー2501が出るいう仕様にMSがしたのなら、それをありがたく利用させもらうというのも選択肢の一つです。
レポートのレコードソースプロパティにSQLを設定している場合、DCountでは簡単に件数を取得できないので、
DAOで、SQLからレコードセットを生成してデータ有無を調べるという面倒なことになるので、エラー処理にするほうがシンプルでしょう。
私としては、
事前に件数を取得するためにレコードセットを開き(DCountにしろDAOにしろ)、その後、レポートでレコードセットを開くというのが2度手間という気がするので、空データ時でキャンセルするのを使うことが多いですね。
とりあえず回答例を載せておきます
※レポートの空データ時イベントは不要です
ここまでやるとなかなかめんどくさいですね。エラー処理がどういうものかきちんと理解できてるのであれば、空データ時イベント+エラー処理でもいいと思います
レポートのレコードソースをレポートとフォームのモジュール(VBA)2か所に記述することになると修正のときに困るので、結局レポートを一度開いてしまうことにしました
一度開いてしまうとレポートの表示が入るので最初は非表示で開いてから、データをチェックして表示するように
いろいろ考えてみると、いろいろ細かいことが多くてどこまで反映させるか悩みどころですね。「細かいこと」はバッサリカットです
お二方、ありがとうございました。
レコードソース用のクエリを作成し、Dcountでレコードがあるのか判定するのが最もシンプルに書けると思いましたので、こちらを採用しました。