PDFの自動印刷のためにAPIのkernel32を利用してみた

今回の記事の2つ前に以下のような過去記事を書いています。今回は以下の過去記事

の続きです。

SendKeysメソッドとFolderfilelistでPDFを自動印刷できないか

エクセルのVBAでSendkeysメソッドとフリーソフトのFolderfilelistでPDFを自動で

印刷できるマクロをつくろうと試みたのですが、思うように動作せずに失敗したと

いった内容です。

考えられる理由として、エクセルからPDFへSendkeysメソッドで指示を送れるよう

にしていたが、指示が速すぎてPDFが表示される前に送ってしまっていたのではない

かということでした。

その解決策として、VBAのコードにAPIのkernel32を利用してみました。今回のこの

部分で試行錯誤した内容について書いていってみます。

VBAにおけるAPIとは、kernel32とは

過去記事の課題をなんとかするために、何か良い方法はないかとインターネットを使

って調べていたら、「これはいけるんじゃないか?」と感じられたものがありました。

それは「APIのkernel32」です

冒頭の過去記事で書いたコードに、今回はAPIのkernel32というコードを利用してみ

ました。ではAPIのkernel32とはどんなコードなのでしょうか。自分の勉強という意

味でも備忘録という意味でもちょっと引用してみます。

『VBAエキスパート公式テキスト Excel VBA スタンダード』には次のように書かれ

ています。

p.191

APIとはApplication Programming Interfaceの略称です。APIは、Windows

などが持っている機能のうち、外部に公開している関数などで、VBAなど他の

プログラムから利用できます。

一般的に、APIとはWindowsのAPIを差しますが、機能をAPIとして公開できる

のはWindowsに限りません。そのほかのプログラムでも、機能の一部をAPIと

して公開しているものがあります。そのように外部に公開している機能や関数

などを「ライブラリ」と呼びます。

プログラム自身を操作するOLEオートメーションとは異なり、APIは公開され

ている機能や関数だけを呼び出して実行します。両者は、Excel VBAによるプ

ログラミングの中でも、高度な部類に入ります。しかし適切に使いこなせれ

ば、VBAだけでは難しい機能を実現できます。

同様に本書においてkernel32は次のように書かれています。

p.191

「Declare Function GetTickCount Lib “kernel32″()As Long」は、

kernel32というライブラリが公開しているGetTickCountという関数を使用

するための宣言です。

APIとは、要はVBAで使えるいろんなコードの種類の中のひとつといったところでし

ょうか。Kernel32というのは「Kernel32というライブラリ」とあるので、そういっ

た種類のコードがまとめられている所があるということでしょう。

ちなみにAPIを使用するには、どのライブラリの、どの関数を使うかを予め宣言しな

ければならず、そのためには宣言セクションでDeclareステートメントを使う必要が

あります。変数の宣言に似ています。

今回はこのコードを使って、前回の課題だった読み込み時間中にエクセルに待機さ

せるという指示が出せるか試してみます。

Sleep関数を利用して自動で印刷できるようにしたコード

冒頭部分の過去記事で書いたコードにAPIのkernel32のコードを利用してつくったの

が以下のコードになります。

Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
Sub 印刷()
Dim time As Long
time = 1500
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) <> "" Then
Cells(i, 6).Hyperlinks.Add Anchor:=Cells(i, 6), Address:=Cells(i, 6).Value
Cells(i, 6).Hyperlinks(1).Follow
Sleep time
SendKeys "^{p}"
Sleep time
SendKeys "{enter}"
Sleep time
SendKeys "%{F4}"
End If
Next i
Range("F7:F100").Delete
End Sub

上のDeclareステートメント内とコード中には「Sleep関数」というものを使っていま

す。Sleep関数とは指定した時間(ミリ秒間)だけ処理を中断できる関数です。例えばコ

ードに中に「1000」と入れれば1000ミリ秒、つまり1秒間、「待ち」の時間をつくる

ということです。

このSleep関数を

  • PDFが開かれる前
  • PDFが開かれて「Ctrl+P」で印刷ダイアログボックスが開かれる前
  • 印刷ダイアログボックスが開かれてenterが押された後

に「待機」の時間をつくることで、エクセルからの指示を対応できるようにしました。

結果と感想

とりあえず形にはなったかな、という感じです。過去記事ではPDFファイルが開かれる

までに若干のタイムラグがあり、その間にエクセルがSendkeysメソッドで指示を送っ

てPDFが開かれていないので対応できない、という課題がありました。

しかし、今回見つけたコードを入れることで「待ち」の時間をつくることができ、PDF

が開いてから指示を送れるようになりました。

それによってある程度は理想的な動きをしてくれるようにはなったのですが、問題は

「ちょっと時間がかかってしまう」ことだと感じています。

VBAでマクロをつくるんだから、一瞬で作業を終わらせてしまう、とは言わないまで

ももうちょっと何とかならないかなぁと思いました。

特に数が印刷する数が増えれば増えるほどより時間がかかってしまいます。自分は

VBA初心者なのでまだこういったコードしか書けませんが、たぶんもっと汎用性があ

って便利なコードはあるはずです。

実際インターネットでいろんなコードを見てみると、難しそうなコードをたくさん目

にしますし。そのようなコードが理解できるように、自分は今後も勉強が必要だと感

じました。

あわせて読みたい

こんな記事も読まれています