<img class="alignnone wp-image-2596" src="https://www.chishikinosoukonoseiri.com/wp-content/uploads/2018/01/pdf-155498_640-300x300.png" alt="" width="534" height="534" />

最近は企業の「生産性」というものに注意が払われるようになってきました。要はいか

に少ない労力でより多くの成果をあげるかということですが、これは個人のレベルでも

業務のやり方の「改善」という形で多くの人が創意工夫してきたと思われます。

&nbsp;

しかし現場の方たちの生産性は日本は世界の中でトップクラスと言われていますが、本

社で働いているような事務的な仕事をしている人たちの生産性は世界の国々と比較する

と燦燦たる有様のようです。

&nbsp;

自分は経理としていくつかの会社でここまで何年か働いてきましたが、特にさぼってい

たわけではなく、むしろ「どうすればもっと速くミスなくできるようになるか」を常に

考えながら仕事をしてきました。

&nbsp;

そのような意識の中で仕事をしながら見つけたのがエクセルのVBAです。エクセルの

VBAについての効果やすごさについては最近このブログでよく書いていきました。

&nbsp;

最近はどうすれば「VBAを使って指定のPDFを一括して印刷できるか」を考えていまし

た。というのも、現在の仕事で時々上司から「○○の請求書のコピーを×月から△月ま

で印刷しておいて下さい」と言われるからです。

&nbsp;

別に1枚や2枚だったら特に気にすることもないのですが、これが10枚や20枚になって

くると結構面倒になってきます。

&nbsp;

今回はタイトルにもあるように、この請求書のPDFについて拙いながらも自分なりに

「SendKeysメソッドとfolderfilelistでPDFを自動印刷できないか」どうか考えてみた

ので、そのことについて今回は書いていってみます。

&nbsp;

今回の記事の注意点として「できないか」と書いてあるので、自動印刷できるマクロ

ができたわけではありません。自動印刷するために自分がどんなことについて試行錯

誤してきたかについて書かれた内容です。

&nbsp;

ちなみに自動印刷に「近い」ことは、次の記事で書こうと思っているので、そのよう

な前提で読んでいただければと思います。
<h2>指定のPDFを印刷するまでの手順と背景</h2>
事務的な職業をしている方でもそうでない人でもPDFを印刷したことがある人は多い

でしょう。PDFを印刷する時というのは、基本的に次のような手順になるかと思いま

す。ちなみにここではパソコンのデスクトップ上にPDFファイルがあると仮定します。

&nbsp;

まず指定のPDFのファイルをダブルクリックして開く

↓

開いたPDFファイルのメニューから「ファイル」を選択

↓

ドロップダウンメニューから「印刷」を選択

↓

開かれた印刷ダイアログボックスから「印刷」を選択

&nbsp;

以上が大まかな流れかと思います。上に挙げた例はわかりやすいように非常に簡略化し

ました。実際の業務などでは印刷したいPDFはデスクトップ上にはなく、決まったフォ

ルダに格納されているのが普通かと思います。

&nbsp;

また印刷するときも、その時の状況によって印刷ダイアログボックスから「どのページ

にするのか」といったことや「カラーか白黒か」といった点など、いろいろと変えなけ

ればいけない設定が出てくる場合もあります。

&nbsp;

以上のような手順をエクセルのVBAで自動化できないものかと思いました。しかしPDF

というと、エクセルとは違うアプリケーションになります。正確にはAdobe Acrobat

Reader DCというアプリケーションになるわけですが。

&nbsp;

もしかしたら何らかの方法があるかもしれないとインターネット上でいろいろと検索し

てみました。あるにはあるのですが、どれも自分が勉強してきたレベルでは理解できな

いような難しいコードです。

&nbsp;

例えばShellオブジェクトのShellExecuteメソッドを使えばいいと書かれていても、自分

のようなVBAを勉強してから日が浅い初心者にはまだ理解するのが難しい。

&nbsp;

それらのコードについて書かれたコメントや感想などを読んでみると実際難しいようで

す。自分なりにVBEにコードを打ち込んでいっていろいろいじって動作させようとして

もなかなか意図通りには動いてくれません。

&nbsp;

もっと初心者でも簡単にPDFを自動で印刷できるコードはないものでしょうか。

&nbsp;

自分としては、この面倒で単調な作業をどうしても自動化したかったので粘り強く調べ

てみたらもしかしたらこれはいけるんじゃないか？と思えるものがありました。

&nbsp;

それがSendkeysメソッドというものです。
<h2>SendKeysメソッドとは</h2>
エクセルのVBAにおけるSendkeysメソッドとは、エクセルではなくエクセル以外の外

部アプリケーションなどにエクセルから指示が出せるコードです。

&nbsp;

一般的なイメージでは、エクセルのVBAというとエクセルの機能のひとつなのでエクセ

ル上でしか動作させることができないと思いがちです。しかしそうではなく例えばエク

セルからでもワードとかエクセル以外のアプリケーションでもエクセルから動作させる

ことができるのです。

&nbsp;

自分は最初このようなやり方があるのを知ったときは驚愕しました。「こんなやり方も

あるのか！？」と。詳しい内容についてはMicroSoftが以下のようなページを掲載して

います。
<ul>
 	<li><strong><a href="https://msdn.microsoft.com/ja-jp/library/cc364423.aspx">SendKeysメソッド</a></strong></li>
</ul>
<blockquote>キーボードから入力したときのように、1 つ以上のキー ストロークをアクティブなウィンドウに送ります。
<div id="code-snippet-1" class="codeSnippetContainer">
<div class="codeSnippetContainerCodeContainer">
<div id="CodeSnippetContainerCode_1dd13a61-a7b0-417c-8676-c8af870676c8" class="codeSnippetContainerCode" dir="ltr">
<div>
<pre>object.SendKeys(string)
</pre>
</div>
</div>
</div>
</div>
<p class="dtH4">引数</p>

<dl>
 	<dt><em>object</em></dt>
 	<dd>WshShell<strong> </strong>オブジェクトです。</dd>
 	<dt><em>string</em></dt>
 	<dd>送信するキーストロークを文字列式で指定します。</dd>
</dl>
<p class="dtH4">解説</p>
SendKeys<strong> </strong>メソッドは、オートメーション インターフェイスを持たないアプ

リケーションにキーストロークを送信する場合に使用します。キーボードの

文字のほとんどは単一のキーで表現されます。キーボードの文字の中には、

<strong>Ctrl</strong>+<strong>Shift</strong>+<strong>Home</strong> などのように、いくつかのキーの組み合わせで表現され

るものもあります。キーボードの文字を 1 つ送信するには、その文字自身

を <em>string</em> 引数に指定します。たとえば、<strong>X</strong> キーを送信するには、<em>string</em> 引

数に文字列 "X" を指定します。</blockquote>
ShellオブジェクトとかOpenステートメント といったものは初心者には難しいかもし

れませんが、ショートカットキーの「Ctrl+P」などであれば難しくはないでしょう。

&nbsp;

そういった動作をエクセルから外部アプリケーションに指示を送れるのが、Sendkeys

メソッドです。

&nbsp;

例えばここまでPDFを印刷する手順について書いてきました。それをキーボードだけで

操作した場合どういった形になるでしょうか？それは以下のような形になります。

&nbsp;

PDFファイルを選択してenterを押す

↓

PDFファイルが画面上に表示されるので、Ctrl+Pのショートカットキーで印刷ダイアロ

グボックスが開く

↓

印刷ダイアログボックスが開かれている状態でenterを押すと印刷が実行される

↓

Alt+F4でPDFファイルを閉じる

&nbsp;

どうでしょうか。どのページを印刷するかといった特に込み入った設定が必要なければ

、マウスを操作しなくてもキーボード上のキーだけでPDFファイルを印刷することがで

きます。

&nbsp;

自分はこのやり方をエクセルからVBAを通してPDFへ指示を送れないかを試してみまし

た。

&nbsp;
<h2>Folderfilelistとは</h2>
Folderfilelistとはフリーソフトのひとつで、指定のフォルダの中にある全部のファイル

までのパスを全て抽出することができます。ちなみに以下のVectorのページからダウン

ロードできます。Folderfilelistの使い方の詳細は以下のページから見ていただければと

思います。

<a href="http://www.vector.co.jp/soft/winnt/util/se515451.html">FolderFileList-対象のフォルダの中を解析し、フォルダとファイルの一覧を確認</a>

&nbsp;

ファイルまでのパスがどう役に立つの？今回のPDFを印刷するマクロとどう関係がある

の？と思うかもしれませんが、使い方によっては本当に便利なんです。

&nbsp;

なぜファイルまでのパスを抽出できることが良いのかというと、コンピュータは、この

パスで指定のファイルがコンピュータ上のどこにあるのか、というのを理解できるから

です。

&nbsp;

この機能を利用して、指定のPDFへリンクして開いて印刷できるようにしようと考えま

した。
<h2>ボタンひとつでPDFを印刷できるマクロのコード</h2>
以上のようないくつかのアイデアをVBAを使ってコードに落とし込んだものが以下のよ

うな形になります。
<blockquote>Sub 印刷()

Dim i As Long

Dim buf As String

On Error Resume Next

Range("F7").Select

Range("F7").Value = "=VLOOKUP(RC[-4],パス!C[-5]:C[3],9,0)"

Selection.AutoFill Destination:=Range("F7:F100"), Type:=xlFillDefault

For i = 7 To 100

If Cells(i, 2) &lt;&gt; "" Then

Cells(i, 6).Hyperlinks.Add Anchor:=Cells(i, 6), Address:=Cells(i, 6).Value

Cells(i, 6).Hyperlinks(1).Follow

SendKeys "^{p}"

SendKeys "{enter}"

SendKeys "%{F4}"

End If

Next i

Range("F7:F100").Delete

End Sub</blockquote>
以上のコードをエクセルの開発タブ＞Visual Basicを開いて標準モジュールに貼り付けます。

それと並行してエクセルのシートを以下のような形にします。

<img class="alignnone wp-image-2611 " src="https://www.chishikinosoukonoseiri.com/wp-content/uploads/2018/01/aaaa.png" alt="" width="673" height="467" />

「印刷」シートに以下の処理をする

・B4セルに印刷したいファイルが入っているフォルダのパスをコピペ

・B7セルにコピペしたフォルダに入っているファイルのファイル名をコピペ

&nbsp;

「パス」シートに以下の処理をする

フリーソフトのFolderfilelistを利用して、印刷したいファイルが入っているフォルダから

抽出した全てのファイルへのパスをコピペする

&nbsp;

以上の処理を実行後、「ボタン1」に登録した「印刷マクロ」を押すことで「印刷したい

PDFファイルを自動で印刷」できるはずでした。

&nbsp;

しかし、ここで問題が発生します。
<h2>問題点と今後の課題</h2>
以上ここまで書いたやり方で「こんなやり方でもVBAでPDFを印刷できるようになりま

すよ」と言えればこれほど嬉しいことはないのですが、やはり問題点もあります。

&nbsp;

それは「コピペしたファイル名のファイルを全て印刷できるわけではない」という問題

です。今の時点では「なぜそうなってしまうのか」というのはわかりません。

&nbsp;

自分の中の仮説では「読み込み時間」の問題ではないかと思っています。

&nbsp;

VBAという分野には「OLEオートメーション」というやり方があります。これもエクセ

ル上から外部アプリケーションに対して何らかの動作をさせるための方法です。

&nbsp;

『VBAエキスパート公式テキスト ExcelVBAスタンダード 』という本には次のように書

かれています。
<blockquote>p.188

インターネットへの接続では、ページが完全に読み込まれるまでに時間が必要

だからです。ページの読み込みが完了する前にInnerTextプロパティの値を取

得しようとするとエラーになります。

&nbsp;

そこでページの読み込みが完了するまで処理を一時停止しなければなりませ

ん。これには、Do...Loopステートメントを使います。・・・</blockquote>
&nbsp;

もしかしたらこれだろうか？と思いました。エクセルからの指示が速すぎてPDFの方が

ついてこれていないのかも・・・。

&nbsp;

確かにPDFファイルをダブルクリックして画面上に完全に開かれるまでの時間とか印刷

ダイアログボックスが開くまでの時間、印刷を実行して印刷ダイアログボックスが閉じ

るまでの時間には若干の「タイムラグ」があります。

&nbsp;

う～ん。そういったタイムラグからエクセルからのPDFへの指示とその指示を実行でき

るタイミングに「ズレ」が生じてしまっているのではないか、というのが今の自分の仮

説です。

&nbsp;

じゃあそれを今すぐやってみればいいじゃないか、ということになるんでしょうが、い

ろいろ仕事で忙しいし、VBAについてもっと理解してからやりたいし、もう少しまとま

った時間の中でやりたいし・・・

&nbsp;

しかし、どうしてもこの処理を自動化したいという想いからインターネットで何か良い

方法はないかと調べていたら別の方法を発見しました。

&nbsp;

今回書いた記事の方法は、後日改善されることになります。そのことについては、次の

次の記事で書こうかと思っています。

&nbsp;
<h2>あわせて読みたい</h2>
<ul>
 	<li><strong><a href="https://www.chishikinosoukonoseiri.com/entry/2017/12/31/0830">業務を自動化できる技術を持たないと自動化される時代が来るかもしれない</a></strong></li>
 	<li><strong><a href="https://www.chishikinosoukonoseiri.com/entry/2017/12/28/1057">2017年の心の変化と「VBA」という新しい道具を手に入れてみて</a></strong></li>
 	<li><strong><a href="https://www.chishikinosoukonoseiri.com/entry/2017/12/03/0104">人間世界における勉強の概念の今後の1つの方向性について</a></strong></li>
 	<li><strong><a href="https://www.chishikinosoukonoseiri.com/entry/2017/11/11/0256">今まで大したことないと思っていた仕事が今は宝の山に見える</a></strong></li>
 	<li><strong><a href="https://www.chishikinosoukonoseiri.com/entry/2017/10/07/1206-2">経理でマクロやVBAが使えるとミスが劇的に減って仕事が本当に楽になる</a></strong></li>
</ul>