Ext JS に関しては,新しい記事は Sunvisor Lab. ExtJS 別館 にあります。そちらもよろしくお願いいたします。
MS-Accessのレポートをページ毎にPDF化する
投稿者:sunvisor 投稿日時:2011/04/08(金) 09:48
仕事で通知書をPDFで作ってメールで配信しようと言うことになって,Access のレポートで通知書を作ることにしたのですが,ページ毎に別のPDFファイルにするのを手作業でやっているとめんどくて気が狂うので自動化を考えてみました。
外のツールを使わないでもできるように今回は Access 2010 を使いました。たぶん,2007でも動作します。
最初に考えて実行したのは次のコード
Sub makePdfFiles() Const TBL_NAME = "担当者" Const RPT_NAME = "通知書" Const PDF_PATH = "D:\hogehoge\" Dim rs As ADODB.Recordset Set rs = New ADODB.Recordset rs.Open TBL_NAME, CurrentProject.Connection, adOpenStatic, adLockReadOnly Do While Not rs.EOF pdfName = rs!部署名 & rs!担当者 DoCmd.OpenReport RPT_NAME, acViewPreview, , "ID=" & rs!ID DoCmd.OutputTo acOutputReport, RPT_NAME, acFormatPDF, PDF_PATH & rs!ID & pdfName & ".pdf" DoCmd.Close rs.MoveNext Loop End Sub
15行目でフィルタを設定してレポートをプレビューで開いてから,16行目で DoCmd.OutputTo メソッドで PDF に出力しています。出力後は,レポートを閉じます。このやり方ですと,画面上に出力されるページのプレビューが次々表示されます。動きがわかってよろしい,ということでしたらいいのですが,うるさい(あるいは遅い)と感じる場合には次のコードが
Sub makePdfFiles2() Const TBL_NAME = "担当者" Const RPT_NAME = "通知書2" Const PDF_PATH = "D:\hogehoge" Dim rs As ADODB.Recordset Set rs = New ADODB.Recordset rs.Open TBL_NAME, CurrentProject.Connection, adOpenStatic, adLockReadOnly Do While Not rs.EOF pdfName = rs!部署名 & rs!担当者 CurrentProject.Connection.Execute "UPDATE Target SET ID = " & rs!ID DoCmd.OutputTo acOutputReport, RPT_NAME, acFormatPDF, PDF_PATH & rs!ID & pdfName & ".pdf" rs.MoveNext Loop End Sub
このコードの場合は,レポートのレコードセットは,Target テーブルと次のようにINNER JOIN されているという前提です。そして Target テーブルには1件だけレコードを登録しておきます。
15行目で Target テーブルのIDを設定しています。それでレポートは1ページだけになります。その後,レポートを開くことなく OutputTo メソッドだけを実行しています。
このやり方ですと,画面には PDF出力の小さなダイアログが表示されるだけになりますので,ちょっとだけ静かになります。
PDFのファイル名をテーブルの情報に基づいて指定する
はじめまして、AccessもVBAに関しても初心者なのですが、一つ質問をさせてください。
現在会社で顧客情報を含むテーブルとリンクしたレポートがあり、そのうちの特定のレコードをPDFにエクスポートしています。その際にPDFのファイル名をテーブル内にある”顧客番号”のフィールドと同じ番号にしたいと思っています。
レコードが2、3件の時は手動でファイル名を指定しているのですが、時々100件近いレポートをエクスポートしなければならず、今はいったん全てのページをエクスポートし、PDFを編集できるソフトで全てのページをばらばらにし、後はレポートを見ながら手動で名前の変更をしています...(とても気の遠くなる作業です)
こちらのサイトにたどり着いて、このVBを見つけました。
pdfName = rs!部署名 & rs!担当者
というところが何かヒントになるのではないかと思うのですが、スクリプトに関してとても初心者なもので、「レポートをエクスポートし、テーブル内の情報に基づいてファイル名を指定する」という作業をどのようにしたら良いのかわからずに困っています。
是非教えていただけると大変助かります、よろしくお願いします。
このスクリプトでやっていることは、レポートを1ページ表示
このスクリプトでやっていることは、レポートを1ページ表示して、それをpdfに出力する。っていうのを2つのやり方でやっています。仰るとおり、顧客番号でやりたい場合でしたら、
pdfName = rs!顧客番号
みたいなことでOKです。
教えてください
はじめまして。
会社でACCESS2010を使用してある簡単なシステムを構築しています。
利用者からレポートを紙ベースではなくPDF化できないのかとの要望があり
その方法を探していたところsunvisorさんの投稿を見つけることができました。
SQLはずぶの素人なので投稿モジュールを見よう見まねでシステムへ追加し、
実行させたところエラーが発生しました。
ネットを調べてみるとrecordsetを実行するにはDAOとADOの定義方式があるとのことで、
参照の競合を避けるために、参照設定のDAO 3.6 Object Library のチェックを外し、
ActivX Data Objects 2.1 Libraryのチェックを入れることで無事回避できました。
しかし、DAOのチェックを外してADOのチェックを入れると
今度はDAOで定義していた他のモジュールがエラーを起こしてしまいました。
いろいろネットを検索して命令をDAO方式で定義し直そうと試みましたが、
基礎知識がないためうまくいかず、だんだん頭が混乱してきました。
もし可能なら、「MS-Accessのレポートをページ毎にPDF化する」ADO定義のソースをDAOで定義した場合、
ソースのどこをどう修正したらいいのかをお教えできないでしょうか?
お返事遅くなりました
DAOとADODBは両方ともチェックを入れて使うことが可能ですので、両方入れて使ってはいかがでしょうか。
その際にRecordsetは両方にあるオブジェクトになるので、どちらのRecordsetを使っているのか明示的に指定する必要があります。
何も指定しない場合は、参照設定の順番で上位のものが採用されます。
ADODBを使うのが、このモジュールだけだということであれば、このモジュールでは明示的にADODBと指定していますから、
参照設定の順番をDAOを上煮にしておけば、両方とも動作するはずです。
お返事ありがとうございます
お忙しいところ、お返事ありがとうございます。
見よう見まねでDAO表記に少しずつ換えてみたら、
なんとか動作したのでDAO方式で使おうかと思っていました。
DAOとADODBは両方ともチェックを入れて使うことが可能なんですね。
それはテストしていませんでした。
早速トライしてみたいと思います。
またわからないところが出ましたらお教えください。