[[20120427163339]] 『エクセルのVBAからページ数を指定してPDFを印刷し』(あや) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『エクセルのVBAからページ数を指定してPDFを印刷したい』(あや)

 XP 2003

 エクセルのVBAからページ数を指定してPDFを印刷したい について
 調べていて、
[[20060927140643]]を見つけて使わせてもらおうとしていますが
 これにページ数の指定はできるのでしょうか?

 Option Explicit

 Dim PrinterName As String
 Dim filename As String
 Dim myshell As Object

 Sub Macro1()

    PrinterName = Application.ActivePrinter
    filename = "C:\download.pdf"
    Set myshell = CreateObject("WScript.Shell")
    myshell.Run ("AcroRd32.exe /t " & filename)

 End Sub

 エクセルのシートに
 ページ数[2〜3]と入力し、
 作成したマクロを動かすと、
 該当のPDFの2〜3ページが印刷されるようにしようと思っています。

 今のところ
 変数をもたせて、ページ数を渡すことが出来れば良さそうという
 漠然としたものしか頭の中にありません…

 そして、自分で使うものですので最大ページ数以上を指定した場合は?などの
 細かい設定までは必要ないと思っています。
 出来ればきちんと作り上げようとは思っていますが、今のところはまだ…。

 myshell.Run も上のページからコピーさせてもらったものなので
 まだ理解しておりません /tの部分がなぜ tなんだろう?とか思っています。
 印刷だったら /p とかだったらなんとなくでわかるのですが…

 このあたりもわかりやすいページなどありましたら
 併せて教えて頂けると勉強できてうれしいです。

 (あや)

希望のことが出来ないとは言いませんが、コマンドにはオプションが無いようです。
http://kb2.adobe.com/jp/cps/510/510705.html

ですのでページを指定して制御する場合は Shell からコマンドを呼び出すのではなく、
OLE の制御が必要になりそうです。
OLE ってなにと言う状態だとちょっと敷居が高いかもしれませんが、一応参考ページです。

一番最後のリンクが VBA では一番参考になると思います。
(Mook)


追記:
OLE を使うには Acrobat(有償の製品版)が必要のようです。

できる機能は制限されますが、DDE(別の制御方法)でしたらReader(無償版)でも
印刷の制御はできるようです。参考リンクを追加しました。

VBA のページ指定印刷サンプルが掲載されているので、アプリケーションパスを
書き換え、ファイル受け渡しの部分だけ実装すればそのまま使えそうです。
(Mook)


 AcroPDFコントロールを使って印刷する方法は?
 いかがですか?

 ちょっと探った限りでは、ユーザーフォームなどにこのコントロールを貼り付ければ、
 印刷には、printPages メソッドなんてのがあります。

 検討してみてください

 ichinose


 ほとんどサンプルそのままですが、一例です。
 ファイル選択をダイアログにしたりすると、使いやすくなるかと思います。
 (Mook)

 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
 Sub DDE_PdfPrint()
    Const pdfFilePath = """D:\Work\Test.pdf"""

    Dim lChanNo As Long 
 '// ここは実際に使用する PC のプログラムのパスに書き換えてください。
    Shell "C:\Program Files (x86)\Adobe\Reader 9.0\Reader\AcroRd32.exe"

    lChanNo = DDEInitiate("Acroview", "Control")
    DDEExecute lChanNo, "[DocOpen(" & pdfFilePath & ")]"

 '// ダイアログを出す場合
    DDEExecute lChanNo, "[FilePrint(" & pdfFilePath & ")]"

 '// ページ指定の場合  1〜3ページの場合
 '  DDEExecute lChanNo, "[DocPrint(" & pdfFilePath & ",0,2)]"

    Sleep 2000
    DDEExecute lChanNo, "[AppExit()]"
    DDETerminate lChanNo
 End Sub


 Mookさん ichinoseさん 書き込みありがとうございます。

 とっつきやすそうなMookさんのDDEExecuteを調べてみましたが
 Readerでは使用できませんとのことでした >Д<
 ざんねん。

 取り急ぎお礼まで。

 (あや)

 DDE でも Reader では出来ない機能があるようですね。
 Acrobat の入った環境で試していたので、気がつきませんでした。

 そうなると ichinose さんが提案された AcroPDF コントロールになるでしょうか。
http://pdf-file.nnn2.com/?p=76
 に簡単な手順はありましたけれど、動作は未確認ですがご紹介だけ。
 (Mook)

 Mookさん ご丁寧に何度もありがとうございます。

 AcroPDF コントロールを
 探りながら試している状態です。

 また教えてください。

 (あや)

 ファイル名はシートかテキストボックスから取得すると便利とは思いますが、
 とりあえず決めうちなら、 CommandButton と AcroPDF コントロールだけのユーザフォームを作成し、

 Private Sub CommandButton1_Click() 
    AcroPDF1.LoadFile "C:\download.pdf"
    AcroPDF1.printPages 1, 2 
 End Sub

 とすると、ボタンを押すと指定ファイルの 1〜2ページが印刷されます。
 (Mook)

 Mookさん ありがとうございます。
 上記4行のマクロで印刷はページ指定で出来るようになりました^^

 ただ、ファイルを開くタイミングで
 Adobe Readerのメッセージボックスが出ました。

 『警告!スクリプトでAcrobatファイルの印刷が要求されました。
 文書全体が印刷される可能性があります。
 印刷を実行しますか?』

 □以後、このメッセージを表示しない

                      はい いいえ

 と出て、以後、このメッセージを表示しないにチェックをつけて
 はい をしました。

 その後もう一度実行したところ、
 メッセージボックスは出なくなりましたが、
 印刷までも出なくなってしまいました -Д-;

 Adobe Reader側の設定になるのか?もしれないので
 もしかしたら、ここに質問するのはお門違でしたら
 申し訳ありません。

 (あや)

 警告のメッセージは出すように戻しました。

 (方法) Adobe Readerの 編集 - 環境設定 - 一般 の中の
     すべての警告をリセット

 以下が、いま現在のコードです。

 Private Sub CommandButton1_Click()

    AcroPDF1.LoadFile "C:\download.pdf"

    AcroPDF1.printPages 1, 2
    AcroPDF1.printPages 15, 16        

 End Sub

 1・2ページを出力し、次に15・16も出力するようにしています。
 (最終はページ数を変数にし、
 Do Untilを使ってぐるぐるまわすことを考えております。)

 これでいま困っていることを整理してみます。

 ☆現象1

 コマンドボタン
   ↓
 警告メッセージ
   ↓
 □以後、メッセージを表示しない にチェック
   ↓
 はい を押す

 1・2ページは印刷されます。

 15・16ページが印刷されません。

 ☆現象2

 コマンドボタン
   ↓
 警告メッセージ
   ↓
 □以後、メッセージを表示しない にチェックをしない
   ↓
 はい を押す

 1・2ページは印刷されます。

   ↓
 再び警告メッセージが出ます
 (数百枚となると、毎回はいを押さなければいけない)

 15・16ページが印刷されます。

 VBA側から制御できる問題ではないのであれば
 一旦ここを閉めて、
 PDFの質問出来るところを探して質問してみようと思っています。

 お知恵いただければ幸いです。

 (あや)


 解決方法ではなく状況の報告だけですが、こちらでも最初に警告は出ましたが、
 チェックボックスるをオンにして表示しないようにしても、次回以降は警告なしで
 印刷できました( こちらで使用したのは Reader のバージョンは 10.1.3 になります。)

 検索で原因を探しては見ましたが、今のところこれといったものが 見つかっていません。
 下記のようなサイトもありましたが、チェックにより印刷は出来ているようです。
 http://mrxray.on.coocan.jp/Delphi/plSamples/720_Acrobat.htm

 EXCEL の掲示板ですので、これ以上の部分はAdobe の関連サイトのほうが情報が
 集まるかもしれませんね。

 一応、下記のサイトも Q&A はあるようです。
 (ほとんど管理者が回答している状態のようですが。)
 http://pdf-file.nnn2.com/

 コメントだけですみませんが。
 (Mook)

 Readerのバージョンは? こちらでは 9.2.0、Adobe Reader 9で試した限りでは、

 Sub tes()
    With UserForm1.AcroPDF1
       .LoadFile CreateObject("wscript.shell").SpecialFolders("DESKTOP") & "\aaa.PDF"
        .printPages 1, 2 ', False
       .printPages 15, 16 ', False
    End With
 End Sub

 こんなコードで最初だけ例の

 警告!スクリプトでAcrobatファイルの印刷が要求されました。
 文書全体が印刷される可能性があります。
 印刷を実行しますか?

 これが表示されますが、

 メッセージを表示しないにチェックをつけて
 はい をしました。

 で正常に印刷されましたけどねえ!!

 因みに Excel2002 です

 ichinose

 Reader 7.0 7.0.0 です。
 会社の環境なのでアップデートできず^^;

 Mookさん
 なんどもすいません。
 検証・お調べいただきほんと助かります。

 ichinoseさん
 ありがとうございます。
 上記7行のマクロを試しても、
 こちらでは前と同じ動きになってしまいます。

 プリンタ側の問題なのか?もしれないので
 (別プリンタ2台で試しましたが、同じでしたけど…)

 もうしばらくプリンタの設定を触ってみます。

 なにかわかれば書き込みにきます。

 (あや)

 印刷の警告は Adobe 側の処理なので、プリンタの影響はあまりなさそうな気がします。
 できれば Reader をバージョンアップして確認してみたいですが、会社での環境制限だと
 難しそうですね。

 Reader のバージョンでいろいろと修正や機能拡張が行われていますので、同じ機能であって
 もバージョンで挙動が異なる可能性はあります。

http://internet.watch.impress.co.jp/cda/news/2006/11/29/14080.html

 のような記事もあり、少なくとも Reader の7から8へのバージョンアップで acroPDF.dll
 に手が入っていることは間違いなさそうです。

 次善の策としてはダイアログが表示されたときに、Sendkeys を使って自動で OK を
 押すような処理を検討してみてはどうでしょうか。
 (Mook)

 Mookさんに教えて頂いた
 Sendkeysを使う方向で考えてみました。

 1行デバッグして
   AcroPDF1.printPages 1, 2
 が走った直後、ダイアログは
 □以後、このメッセージを表示しない
 が、破線で囲われて(選択されて)いました。

 キーボードからは
 TABを押してから、Enterを押すことで
 印刷ができましたので

 Sendkeysを使って

   AcroPDF1.printPages 1, 2
   SendKeys "{TAB}"
   SendKeys "{ENTER}"

 こんな風に書いて走らせてみたところ
 ダイアログ画面で
  □以後、このメッセージを表示しない
 が選択されて止まってしまう状態になりました。

 また謎になってしまったのですが…
 Sendkeysの使い方は間違ってないでしょうか?

(あや)


 SendKeys の前後に適当な時間の Sleep を挟んでみてはどうでしょうか。
 Dialog が表示されていないときにキーが送られてしまってうまく動作していないのでは
 ないでしょうか。

 VBA(標準モジュールで) の先頭に下記を書き
    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

 各SendKeys の前に下記を書いてみてください。
     Sleep 2000

 うまくいくようなら、これは2秒に相当するので、もう少し縮めればよいかと思います。
 ダメなようなら別原因ですので、再度コメントしてください。
 (Mook)


 Mookさんに教えて頂いた
 Sleep 2000を元に書いてみました。

   AcroPDF1.LoadFile "C:\download.pdf"

   AcroPDF1.printPages 1, 2
   Sleep 10000
   SendKeys "{TAB}"
   SendKeys "{ENTER}"

 --- 現在の動き ---

  コマンドボタンを押したあと、
  しばらく間をおいて(Sleep10000の後でしょうか)
  警告ダイアログが出ます。

  ダイアログにフォーカスがあり
  □以後、このメッセージを表示しない が選択されている状態です。

  見たところ…SendKeysの動きが反映されてないように思います^^;

 (あや)

 SendKeysを先に記述してから、PrintPagesしてみたら?
 試してない。

 (通りすがり)

 通りすがりさん ありがとうございます。

    AcroPDF1.LoadFile "C:\download.pdf"

    SendKeys "{TAB}"
    SendKeys "{ENTER}"
    AcroPDF1.printPages 1, 2

 としてみましたが、ダイヤログが出ました。

 上記と同じく
 ダイアログにフォーカスがあり
  □以後、このメッセージを表示しない が選択されている状態です。

 こまった…

 (あや)


 通りすがりさんからコメントありましたが、ダイアログが出るのは PrintPage ですから
    AcroPDF1.LoadFile "C:\download.pdf"
    AcroPDF1.printPages 1, 2
    Sleep 3000
    SendKeys "{TAB}"
    Sleep 200
    SendKeys "{ENTER}"
 のようにしたらダメでしょうか。
 (Mook)

 Mookさんと通りすがりさんに教えていただいた

    AcroPDF1.LoadFile "C:\download.pdf"
    AcroPDF1.printPages 1, 2
    Sleep 3000
    SendKeys "{TAB}"
    Sleep 200
    SendKeys "{ENTER}"

 を試したところ。

 コマンドボタン(コマンドボタンがへこんだまま)
  ↓
 しばらく待つ
   ↓
 (コマンドボタンのへこみが戻る)
 PDF表示と同時に ダイヤログが出る

 こんな感じです。

 (あや)

 改定案を取り下げです。
 ダイアログを再表示にするのに手間取って(Reder の10 ではレジストリ変更が必要)
 いたので、検証が遅れましたがダイアログが出ている間、VBA はモーダルのように
 制御が出来ないんですね。

 これでは、Sleep も意味が無いですし、通りすがりさんが言ったように先行して
 送っておいてダメなら、これまでの案では実現できないことになります。

 追記:
 以下、かなり無理やりな方法ですが、一応こちらでは動作しました。

 あらかじめメモ帳で下記を作成しておいて、
 C:\skey.vbs
 ――――――――――――――――――――――――――――
 Set WshShell = WScript.CreateObject("WScript.Shell")
 WScript.Sleep 3000
 WshShell.SendKeys "{TAB}"
 WScript.Sleep 200
 WshShell.SendKeys "{ENTER}"
 ――――――――――――――――――――――――――――

 EXCEL 側は下記を実行してどうでしょうか。
 (Mook)

 AcroPDF1.LoadFile "C:\download.pdf"
 Shell "CScript ""C:\skey.vbs""", 0
 AcroPDF1.printPages 1, 2

 1・2ページの印刷は出来ました^^
 ダイアログが出たあと、
 自動で「はい」にカーソルが動き
 Enterが押せています。

 次に
 5・6ページも同じように追加してみました。

    AcroPDF1.LoadFile "C:\download.pdf"
    Shell "CScript ""C:\skey.vbs""", 0
    AcroPDF1.printPages 1, 2

    Shell "CScript ""C:\skey.vbs""", 0
    AcroPDF1.printPages 5, 6

 上記にすると、印刷物1ページも出てきません。
 動きとしては、ダイアログが出た直後に -------☆
 「いいえ」にカーソルが動いて、   
 「いいえ」でEnterを押されて、
 またダイヤログが出ます。

 同じように試しているのですが

 2回目のダイアログで止まるときもありますし、
 6回目のダイアログで止まるときもあります。
 ダイアログで固まって止まっているときもあります。

 反応があるダイアログで止まっているときは、
「いいえ」を押すと、もう一度ダイアログを出して
 勝手に「いいえ」「Enter」と進んで、
 また繰り返したり、
 ユーザーフォームに戻ってきて終わる状態もあります。

 Sleep 10000にして確認してみたところ
 ☆のところで「はい」にフォーカスがあるので
 WshShell.SendKeys "{ENTER}"
 を送るよう変更してみたところ、
 1・2ページの印刷は出ましたが
 あとの印刷物は出ずに、
 ダイアログが出て閉じての繰り返しです。

 はっきりとした動きが見えず
 まだ検証中ではありますが、
 報告とさせていただきますm(_ _)m

 (あや)


 PagePrint も VBS も処理の終了待ちをしていないので、それぞれの間で印刷が
 終わっている(少なくともスプーリングが完了している)ことを確認する必要が
 ありそうです。

 なかなかこれ、といった良い方法が無いですね。
 チェックボックスにチェックをして、印刷がでれば問題ないので、バージョンアップは難しくても
http://www.adobe.com/jp/support/security/bulletins/apsb06-20.html
 の更新もダメでしょうか。

 これによって、ダイアログを非表示で印刷ができれば、一番簡単なのですが。
 (Mook)


 個々のパソコンだけバージョンアップと言うと
 今以上に非常にめんどくさい人になってしまう上に
 却下されるため 更新も出来ない環境です。
 バージョンアップ出来ればこんな悩まなくてよいし
 お時間取ってもらわなくてよいのは
 過去の経験からも身にしみています…

 VBAから印刷したい範囲のPDF印刷ができれば
 別作業に入れて効率的なんですが…
 環境的なものにより断念するしかないかぁ >д<

 とはいいつつまだあきらめてはないのですが…
 一緒に悩んでくださりありがとうございましたm(_ _)m

 (あや)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.