スポンサードリンク

仕事でファイルの一覧があるリストを作成して
それを見て各々がそのリストを見てリストにあるファイル名の
紙の書類を印刷をいままでしていたのです。
かなりめんどくさいだろうなと思っていました。
この度、紙の書類をスキャンしてPDFファイルを
保存するようして、書類も大分揃いましたので
VBAを使って自動で印刷できるようにしました。
スポンサードリンク
自動印刷のためにAcrobat Readerを使う

まずはPDFで印刷するために
無料で便利なAcrobat Readerをインストールします。
ほぼどこの場所でも使われていると思われるPDF閲覧用ソフト。
VBAを使ってこちらのソフトをShell機能で操作して印刷をします。
shell機能を使うための事前準備

Shell機能を使うため、
[VBE]-[ツール]-[参照設定]を開きます。

「Windows Script Host Object Model」にチェックを入れて下さい。
これでshell機能を使うことができます。
スポンサードリンク
エクセルシートにあるA列から下に順にファイル名があるリストの自動印刷機能の実装
Sub ListPrint() '図面印刷VBA 'Shell実行用の変数設定 Dim wshShellObj As IWshRuntimeLibrary.WshShell 'Shellオブジェクト Set wshShellObj = New IWshRuntimeLibrary.WshShell Dim strShellCommand As String 'Shellコマンド Const folderPath = "D:\●●●●●●\□□□□□□\" 'フォルダパス(定数) Dim printFolderPath As String 'フォルダパス Dim printFileName As String 'ファイル名 Dim printFilePath As String 'ファイルパス Dim activePrinter As String '通常使うプリンターを取得 Dim printerName As String 'プリンタ名 Dim listname As String '印刷リスト Dim listFolder As String '印刷リストフォルダ名 Dim intPoint1 As Long 'プリンタ名を切り出す為の文字数 Dim i As Integer '印刷行カウンター '通常使うプリンターを取得 activePrinter = Application.activePrinter '取得できなかった時の処理 If activePrinter = "" Then MsgBox "プリンター情報が取得できませんでした" & Chr(13) & "プリンターが接続されていることを確認してください" End Exit Sub End If 'ファイル名(" on"の前まで)とポート名("on "の後から最後まで)を切り出す intPoint1 = InStr(activePrinter, "on") - 2 'プリンター名を指定 printerName = Left(activePrinter, intPoint1) 'ポートを除いたプリンタ名 'カウンターをセット A列1行目から i = 1 '行 '表紙の最初の図番を取得 listname = Cells(i, 1).Value Do While listname <> "" 'PDFファイルパスを設定 printFolderPath = folderPath & listFolder & listname '印刷するPDFフォルダパス 'PDFファイル名を取得(拡張子などをワイルドカードで検索して変数へ取込む) printFileName = Dir(printFolderPath & "*") 'ファイルがあるかを判定 If printFileName <> "" Then 'ファイルパスを指定 printFilePath = folderPath & listFolder & printFileName 'Shellコマンドを設定 'strShellCommand = "AcroRd32.exe /p " & printFilePath & " " & printerName '設定画面を表示 32ビット版 strShellCommand = "Acrobat.exe /p " & printFilePath & " " & printerName '設定画面を表示 64ビット版 'Shellコマンドを実行 wshShellObj.Run (strShellCommand) '文字を赤色に変更 Cells(i, 1).Font.Color = RGB(255, 0, 0) Else '文字に取り消し線を設定 Cells(i, 1).Font.Strikethrough = True End If '1行下がる i = i + 1 '次のリストを取得 listname = Cells(i, 1).Value Loop 'オブジェクトを強制開放 Set wshShellObj = Nothing End Sub
VBAでshellオブジェクトを作成し、Runメソッドを実行して印刷します。
この機能の内容としては
アクティブシートにA1から下にファイル名があり
そのリストを順に1行ずつ順に読み込んでフォルダにファイルがあるかを確認して
ファイルがあれば印刷してエクセルにあるファイル名を赤字に変更
ファイルがなければエクセルにあるファイル名に取り消し線を入れる。
リストが空白になったらVBA終了です。
エクセルシートにあるA列から下に順にファイル名があるリストの自動印刷機能の解説
'通常使うプリンターを取得 activePrinter = Application.activePrinter '取得できなかった時の処理 If activePrinter = "" Then MsgBox "プリンター情報が取得できませんでした" & Chr(13) & "プリンターが接続されていることを確認してください" End Exit Sub End If 'ファイル名(" on"の前まで)とポート名("on "の後から最後まで)を切り出す intPoint1 = InStr(activePrinter, "on") - 2 'プリンター名を指定 printerName = Left(activePrinter, intPoint1) 'ポートを除いたプリンタ名
まず、通常使うプリンターを取得します。
開発環境と使う場所のプリンターが違うので
使う人がわざわざプリンターの設定をしないといけないのは
面倒くさいため、
VBAで通常使うプリンターを取得して変数にセットします。
VBAではApplication.activePrinterで通常使うプリンタを取得できるようで
形式は「プリンタ名 on ポート名:」です。
「プリンタ名」以外は不要なので、プリンタ名だけに切り分ける処理をしています。
'カウンターをセット A列1行目から i = 1 '行 '表紙の最初の図番を取得 listname = Cells(i, 1).Value
ここで印刷したいファイルリストの【A1】のセルの値を読み込みます。
Do While listname <> "" 'PDFファイルパスを設定 printFolderPath = folderPath & listFolder & listname '印刷するPDFフォルダパス 'PDFファイル名を取得(拡張子などをワイルドカードで検索して変数へ取込む) printFileName = Dir(printFolderPath & "*") 'ファイルがあるかを判定 If printFileName <> "" Then 'ファイルパスを指定 printFilePath = folderPath & listFolder & printFileName 'Shellコマンドを設定 strShellCommand = "AcroRd32.exe /p " & printFilePath & " " & printerName '設定画面を表示 'Shellコマンドを実行 wshShellObj.Run (strShellCommand) '文字を赤色に変更 Cells(i, r).Font.Color = RGB(255, 0, 0) Else '文字に取り消し線を設定 Cells(i, r).Font.Strikethrough = True End If '1行下がる i = i + 1 '次のリストを取得 listname = Cells(i, 1).Value Loop
次に、PDFがあるフォルダのファイルパスを作成します。(41行目)
そして【A1】セルにあるファイル名のファイルがDirコマンドで確認します。
その際、拡張子やファイルの後ろに日付などあるかもしれないので
ワイルドカードを使って確認します。(43行目)
取得したファイル名が実在すれば印刷を実行します。
実在するファイル名を使ってファイルパスを作成して
wshShellObj.Runの引数にAdobe Readerを使って印刷するコマンドを入れることで、
印刷することができます。(46~50行目)
印刷したらセルの値を赤色にして判別します。(49行目)
ファイルが実在しなければセルの値に取り消し線を付けます。(52行目)
印刷処理が終われば、次の行へ移ります。
セル値が空白になれば終了します。
'オブジェクトを強制開放 Set wshShellObj = Nothing
最後にオブジェクトを強制解放して終了です。
実装してみて
使ってもらっている方に聞くと
かなり印刷が楽になったと言ってもらいました。
しかし、Acrobat Readerの機能なのか
印刷サイズがA3で統一できないのです。
'Shellコマンドを設定 strShellCommand = "AcroRd32.exe /p " & printFilePath & " " & printerName '設定画面を表示
仕方がないので上記の場所で
印刷設定画面を出してA3にして印刷しています。
1番目の印刷サイズをA3にしてしまえば
あとは、設定画面が出てくるので【印刷】を押せばA3で印刷されます。
A4のままでいい方は
'Shellコマンドを設定 strShellCommand = "AcroRd32.exe /t " & printFilePath & " " & printerName '設定画面を表示
【AcroRd.exe/】の後ろの【p】を【t】に変えれば
印刷設定画面がでません。
【参考】
VBAでPDFを印刷する方法・管理しやすいツールにする方法を解説!
VBAマクロでPDFを印刷する方法およびプリンタ情報を取得する
[ExcelVBA]64ビット版AcrobatReaderでの印刷処理
スポンサードリンク
初めまして
エクセルExcel VBA初心者の物です。
素晴らしいVBA使わせていただきました。
こちらですが、A1のセルの順番通りに印刷することは可能でしょうか
もし、よろしければ教えてください。
>OKD様
コメントありがとうございます。
質問のA1のセルの順番通りに印刷とのことですが、
A1からセルの順番通りに印刷という質問でよろしかったでしょうか。
この記事のVBAはA1からA2、A3という風に1行づつセルを下げて値を確認しているため、
A1からA2、A3という風に順番に印刷しております。
また、A1のセルに印刷したい順番を予め書いておき、
その順番通りというとこのVBAでは対応できません。
方法とするなら、A1に書いた順番を配列として読み込んで
ループ処理を行うことになります。
質問の意味を間違えていたら申し訳ございません。
ご返信ありがとうございます。
言葉足らずで申し訳ございません。
わたなべ様の仰る通りにA1→A2→A3の順で印刷したのですが
sleepの式もWaitSecの式もうまく作動してくれません・・・
もしよろしければ、式を教えていただけませんでしょうか。
失礼なお願いでしたら、削除していただいて構いません。
お忙しいところ恐れ入りますが、宜しくお願い致します。
>OKD様
sleepの式もWaitSecの式もうまく作動しないとのことですが、
このブログではsleepの式もWaitSecの式も使用してないため
どの事なのかわかりません。
申し訳ございません。
はじめまして、マクロの超初心者です。貴サイトを拝見し下記二点の仕様で使用させていただきたいのですが
①PDFではなくEXCELファイルで同じ処理を行う。
②A1からではなく、B2から処理を行う。
①②のマクロの記述をご教示いただけませんでしょうか。
以上、よろしくお願いいたします。
>鈴木様
ご返信かなり遅くなりまして申し訳ございません。
最近は本業が忙しく、ネタはあるのですがこのブログに記載する機会が減っており
コメントに気づいていませんでした。
ご質問の内容が解決していたら無視して下さい。
とりあえず、ご回答致しますね。
①Excelで同じ処理をするとなると、こちらの内容は同じものは使えません。
ExcelでExcelファイルを印刷する場合はshell機能を使う必要はありません。
ExcelでExcelファイルを印刷する場合はPrintOutメソッドを使います。
また、一覧のファイルと印刷したいファイルが別の場合はWorkbookオブジェクトなどオブジェクトを
使って印刷します。
②このVBAでB2から印刷する場合は37行目の
『listname = Cells(i, 1).Value』のiが行を示しており
34行目のカウンターのiを2で指定すると2行目から始まります。
また、37行目の『listname = Cells(i, 1).Value』の1が
A列を示しているのでB列の場合は2とします。
かなり返事が遅くなってしまいましたので
簡易的に回答させて頂きました。
遅くなり申し訳ございません。
いつも勉強させて頂いております。
フォルダーアドレスとセル指定位置だけを変更させて頂きました。
マクロを動かしてみると一つ一つ順番に進まず、一つ目のファイルを開いている間に全てのファイル名が赤くなってしまい、プリントアウトが順番に進んで行きません。
開いてプリントアウトし、ファイル名を赤字にして次に移るという順番で動かすには追加で修正が必要でしょうか?
>Naogataさま
ご質問ありがとうございます。
Runというプログラムで外部のAcrobatを動かしているのでどうしてもラグが起きてしまいます。
開いてプリントアウトを実行しようとした場合は
その際に実行を止めるなどの作業を追加する必要があります。
ただ、Acrobatが印刷を実行したという事がわかる
何かしらの信号のようなものがVBA側で受け取れれば可能かと思います。
しかし、私はそのような事を追加するスキルが現状ないので
あくまでも参考程度で聞いていただけたらと思います。
今は実作業ではAcrobatですべてのファイルを開くまでを行い、
印刷はひとつひとつで実行しています。
>わたなべさま
ご回答いただきましてありがとうございました!
Acrobatが印刷を実行したという事がわかる何かしらの信号があるか探してみたいと思います。