事務作業の現場では、ファイルサーバ上に於いてディレクトリ構造に合わせてファイルを配置したり作成したりといった、本業に付随する雑務が結構な量あります。しかもそれにかなりの時間を費やしていたりするケースもあります。

配置だけでなく配置後の加工や編集作業などの業務も非常に多く、さらに加工後はこちらに配置といったように移動が行われたりもするわけです。これらの業務は時間は掛かるもののそれ自体に大きな価値があるわけではありません。そこでこれらの業務を自動化となると出てくるのが「VBA」。

今回はそういったジャンルの1つである「特定フォルダ内のPDFをキーワードで検索しファイルを印刷する」を、フォルダのドラッグアンドドロップで実現するものを作ってみました。

今回使用するファイル

※事前にプログラムの設定を行う必要があります。

事前準備

参照設定

今回のプログラムは、いくつかの参照設定を追加しています。手動で追加する項目は

  • Microsoft Scripting Runtime
  • Windows Script Host Object Model (shellによるコマンドライン実行で使用します)

の2つ。及び、UserFormで「ListView」を追加している関係で、

  • Microsoft Forms 2.0 Object Library
  • Microsoft Windows Common Controls 6.0 (SP6)

が追加されています。この2つについては参照設定ではなく、UserForm上でのコントロールの追加にて自動的に追加されるようになっています。

図:参照設定の追加

ListViewコントロールの追加

Visual Basicの画面にて新しくユーザフォームを追加したい場合には、「挿入」⇒「ユーザフォーム」を選択する事で、フォームを追加する事が可能です。また、標準で用意されているコントロールの他に、Visual Basic 6.0等で用意されてるOCXファイルを指定出来、今回は「ListViewコントロール」を追加してあります。追加手順は以下の通り。

  1. UserFormを開く
  2. メニューより「ツール」⇒「その他のコントロール」を開く
  3. コントロールの追加ダイアログにて、Microsoft ListView Control, version X.Xを探して、チェックを入れてOKする
  4. コントロールのツールボックスにListViewコントロールが追加されるようになります。
  5. 実際に貼り付けて、コントロールのプロパティに於いて、OLEDragMode = ccOLEDragAutomaticOLEDropMode = ccOLEDropManualに設定を変更してあります。

図:ListViewコントロールは追加しないと表示されない

図:開発時はOLEDragModeなども設定しておく必要があります。

使い方

今回使用するファイルを開くと「ファイル抽出」というリボンが追加されています。事前にセッティングが必要となります。

セッティング

アプリの設定」をクリックすると、プログラムセッティング用のダイアログが表示されます。以下の項目をセッティングしておきましょう。

  1. 保存先 – キーワードに合致したファイルを指定のフォルダにコピーします。【必須】
  2. 抽出ファイル名 – ファイル名を指定します。実際には前後をアスタリスクで括ったワイルドカードで検索しています【必須】
  3. プリンタ選択 – 連続印刷をする場合にはここでプリンタを選んでおきます。リストは自動でインストール済みプリンタが出ます
  4. 連続印刷実行オプション項目で、2.でヒットしたファイル(PDF)を連続で印刷する場合にはチェックを入れます。

設定はBookと同じファイル名で同じディレクトリにiniファイルとして保存されます。途中でファイル名を変えてしまうと前の設定はiniファイルの方もファイル名を変えてやる必要があります。

図:設定用のダイアログは必ずセットアップが必要です

実際にファイルを取り出してみる

ファイルの抽出と印刷」を実行するとListViewのついたダイアログが表示されます。このListViewに対して以下の処理を行うと、ファイルのコピーと連続印刷が実行されます。

  1. 検索したいフォルダを掴んで、ListViewコントロールにドラッグ・アンド・ドロップする。
  2. 処理をするか否かのメッセージで「はい」を選ぶと処理を実行します。
  3. 指定のキーワードをファイル名に含むファイルをリストへと追加しつつ、オプションで連続印刷を実行にチェックが入っている場合、ここでAdobe Readerを利用して印刷を行っています。
  4. また、同じファイルを指定のフォルダにコピーを行います。

図:ヒットするファイルがあるとリストに登録されます。

ソースコード

settingフォーム

  • FileDialogにて保存先フォルダの指定を行わせています。初期値はデスクトップのパスを取得して割り当てています。
  • フォームを開いた時にInitializeが実行され、iniファイルからの設定値がロードされます。
  • また、インストール済みのプリンタリストを構築し、コンボボックスに追加も行っています。
  • 設定を保存ボタンにて、入力済みの設定値をiniファイルへと保存を行います。

listviewフォーム

通常の連続印刷の場合

  • 設定値関係はグローバル変数で格納してあります。
  • ListViewに於いてOLEDragDropイベント内に今回のメインとなるコードを記述します。
  • Dragされたフォルダのパスをtargetfolderに格納し、次のサブルーチンへと渡しています。
  • サブフォルダがあった場合には、サブフォルダ内を探索するように再帰的にFileSearchを呼び出す仕組みになっています。
  • PDFファイルであるか?また、ファイル名に指定のキーワードが入っているか?をLikeで調査し、含まれている場合にはファイルの処理を続行する。
  • コピー先ではファイル名の頭に連続した数字を付与するようにしています。
  • 印刷オプションが有効な場合には、Adobe Readerを立ち上げ、印刷を実行するShellコマンドをCallするようにしてあります。
  • ListViewコントロールには、File.typeがAdobe Acrobat Documentで、指定のキーワードを含むものが今回の処理対象となります。File.typeの部分をExcelなどにすれば、Excelのファイルがヒット対象になります。

両面印刷をしたい場合

VBAではExcelなどの場合はそこそこ詳細な印刷の指示を渡す事が可能ですが、それでもプリンタドライバに対する非常に詳細な設定を、直接操作する事が出来ません(それ専用のDLLがあれば可能ですが、非常にお高い)。そのため、結構よく利用する「両面印刷」ですが、VBAから正攻法で実行する手段がありません。

そこで利用するのがVBAで他のアプリケーションを操作するでも紹介してる、特定のウィンドウに対してキー操作を送り込む手法で両面印刷に対応する事が可能です。今回はAdobe Readerを対象としてるため、他のプリンタドライバ等の場合には、キーが異なると思いますので、適宜読み替えてください。

以下に前のコードに追加した部分を追記します。

settingフォーム

フォームに1個オプションとして、両面印刷のチェックボックスを追加し、設定を保存するコードを追加しています。

listviewフォーム

連続印刷オプションにチェックが入ってる場合にオンとなるようにコードを組んであります。もちろん、両面印刷オプションもオンである必要性があります。

両面印刷コード

pdfremote関数として呼び出される、両面印刷を実行する為のコードです。直接ドライバに指示が出せないので、印刷ダイアログをVBAで操作して印刷を実行させるテクニックです。

  • 連続印刷実行オプションが有効で、尚且つ、両面印刷実行のオプションが有効な時だけ実行されます。
  • shellのexecコマンドの場合、Runコマンドと違い、実行した結果のプロセスIDなどが取得出来ます。
  • Adobe Readerのexeまではフルパスで。パスが通っていれば、AcroRd32.exeだけでも実行可能。
  • ウェイトはおよそ15秒ほど。sleep関数にて実行しています。
  • shellの返り値のオブジェクトに対して、ProcessIdにてプロセスIDを取得可能です。
  • OpenProcess関数にてProcessIdからウィンドウハンドルを取得しています。取得しないどれか別の開いてるウィンドウに対して処理が実行されてしまいます。
  • SetForegroundWindow関数にて、指定のウィンドウハンドルのウィンドウをアクティブにしています。
  • Sendkeysにてキーコードを送りつけます。印刷実行⇒ダイアログ表示されたらAlt+Bにて両面印刷にチェックを入れさせる。
  • 最後はEnterキーにて両面印刷を実行しています、その後Alt + F4キーの送信でプログラムを終了させています。
  • 印刷実行まで完了したら、呼び出し元に返り値を返します。
  • 注意事項として、印刷指示実行中はPCの操作は禁物。おかしな挙動になったり、プログラムが終了する可能性もあります。
  • Adobe Readerのコマンドラインスイッチでは今回は印刷を実行させていません。

関連リンク

共有してみる: