饂飩コーディング

iOSアプリやら、Unityやら、Cocos2dやらごにょごにょ書いております

VBAでPDFファイルを同期印刷する!

サイトが引っ越しました。→https://scombu.com

約1秒後に自動的にリダイレクトします。切り替わらない場合はリンクをクリックしてください。

VBAでPDFファイルを印刷する!で検索すると確かに情報は沢山でてきます。
しかし今回やりたいのは「同期印刷」

複数のPDFがフォルダに入っていてそれをFSOでなんとかしながら
ループで各PDFファイルを印刷処理するとループががぁ~っと流れてしまい、
適切なSleep処理を入れておかないと思ったように印刷してくれません。

この段階で印刷中の画面をぼーっと眺めていると、Acrobat ReaderDCのウィンドウにPDFファイルが順によみこまれて
複数のPDFファイルが一つのAcrobatReaderDCのウィンドウに横展開され印刷が終わってもこのウィンドウが終了してくれません。
この段階で自分は「あぁ、これじゃ同期処理できねぇ~アプリケーション終了しなきゃ同期できない。」と半ばあきらめてました。

まぁ、取り合えずはSleepでタイミングを上手にいれてけば問題なないかな?なぁ~んて軽く考えていたのですが
以下の二点でやっぱり同期させたい!同期させたい!(大事なので二回言います!)

①一枚目の印刷が終わったら間髪入れずに二枚目の印刷処理して大量印刷の場合に時間を節約する。
➁一枚目の印刷が終わったら印刷元ファイルをリネームして印刷済みとわかるようにしたい。

しかぁ~し、なかなかVBAで同期印刷するサンプルが見つからない見つからない。

あきらめずに調べてるとこんな情報が!!!
AcroRd32.exeのプロセスが二つ表示されるとか、/nオプションで新規でインスタンス化するとか・・・

どうも空のAcroRd32.exeを一つ起動しておき、印刷はそれぞれ追加でAcroRd32.exeをインスタンス化させながら印刷処理すればそれぞれのインスタンス化された実態が印刷終了後に終了してくれるという情報があって「これでできるのかな?」なんて期待をしてみました。

久しぶりにGoogle先生からの丸パクリはできないパターンだったんで以下の方針で実装してみます。
方針1 印刷コマンドを発行前にAcroRd32.exeを一つだけ空インスタンス化しておく。
方針2  shellObj.Run (exeStm), True, True オプションTrue True(二つ目のTrueで同期実行) させる。
方針3 AcroRd32.exe /n /t のオプション指定で印刷する

Private Sub ぼたん_Click()

  'プリンタ設定
  Dim prtDefault As Printer
  '現在のプリンタ設定を退避
  Set prtDefault = Application.Printer 'これがデフォルトプリンタ
  
  '印刷するぞ
  
  'Shell Objestの作成
    Dim shellObj As Object
    Set shellObj = CreateObject("WScript.shell")
    
    Dim exeStm As String
    'Acrobat Readerの一つ目インスタンスを起動
    shellObj.Run "AcroRd32.exe"
    '起動するまで長めに待機
    Sleep 5000 'Sleep APIは別途Declearしておく
    'Acrobat Readerでプリントアウトするコマンドを三つ作っておく。
    '/n インスタンスを新規で作成するオプション
    '/t 印刷オプション
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test2.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
        exeStm = "AcroRd32.exe /n /t" & " " & "C:\Users\xxx\Desktop\test3.pdf" & " " & Application.Printer.DeviceName
        shellObj.Run (exeStm), True, True '同期処理で印刷
        
  Set prtDefault = Nothing
  Set shellObj = Nothing
  
End Sub

同期処理できてる!!!!


せっかくなんでVBScriptバージョンはこちら。
適当な名前.vbs 
で保存してPDFファイルが入ったフォルダに突っ込んで
ダブルクリックすると印刷されますw

Option Explicit

	Dim f, gf, so, ws
	dim cmdString
	Set so = CreateObject("Scripting.FileSystemObject")
	Set gf = so.GetFolder(".")
	Set ws =CreateObject("WScript.Shell")

	Dim sapi
	Set sapi = CreateObject("SAPI.SpVoice")
	
	

	'AcroRd32.exe一つ起動しておく。
	ws.Run "AcroRd32.exe"
	WScript.Sleep 5000

	'フォルダ内のPDFファイルをそれぞれ/n/tで印刷をループさせる。
	For Each f In gf.Files
		If LCase(so.GetExtensionName(f.Name)) = "pdf" Then
		
		'上手く印刷が終わるまで同期してくれる。
		cmdString = "AcroRd32.exe /n /t " & """" & f.path & """"
		ws.Run cmdString,true,true
		sapi.Speak "ichimai owattayo"
		End If
	Next
	sapi.Speak "zenbu owattayo"
	Set gf = Nothing
	Set so = Nothing
	Set ws = Nothing
	Set sapi = Nothing

	
	'MsgBox("Finished Printing")