業務で何らかの処理をする時に、PDFを表示させて見る箇所がいつも同じだった、なんてことはないでしょうか。
PDFで何らかの帳票から数値や文字列を確認して、エクセルに入力していくなどの処理のために、毎回指定のPDFファイルをダブルクリックして開いて、毎回マウスでスクロールしたり縮小拡大させるのは面倒くさいでしょう。
それが1つや2つであればいいですが、毎回数十、数百といった数を処理する場合、気が滅入ります。少しでも業務を改善したい、楽にしたいと考えた時に最初からPDFの表示位置が調整されていたら毎回数百回分のマウスのスクロールをしなくても済むようになります。
今回はそれを実現するためのExcelVBAのコードを整理していってみます。
ExcelVBAのWebBrowserとsetZoomScrollでPDFの表示位置を調整するコード
結論から先に書くと次のコードになります。確認した動作環境はExcel2013です。
Private Sub CommandButton1_Click() Dim P As Object Set P = WebBrowser1.Document P.setZoomScroll 100, 200, 150 End Sub
上記のコードを解説すると、フォームモジュールにWebBrowserコントロールとコマンドボタンを設置します。そのコマンドボタンのクリックイベントでWebBrowserを通してPDFの表示される位置が記述したコードの位置に表示されるようになっています。
2行目でオブジェクト型の変数Pを宣言、3行目でオブジェクト変数としてWebBrowserコントロールを格納。4行目のsetZoomScrollメソッドでPDFの表示位置を調整しています。
少し補足すると、事前にInitializeイベントなどでWebBrowserコントロールのNavigateメソッドでPDFを表示できるようしておく必要があります。
setZoomScrollメソッドの引数は自分が確認できている範囲だと3つあります。1つ目の引数は「表示倍率」です。引用したコードの最初の引数は「100」とありますが、これはPDFの表示倍率が100%という意味になります。
基本的に100%が標準サイズでそれよりも拡大して見たい場合は、200、300に増やしていきます。縮小して見たい場合は、90、80という風に数値を小さくしていきます。
2つ目と3つ目の引数はPDFを表示する位置の「座標」になります。2つ目の引数がX軸、3つ目の引数がY軸を指定します。起点はWebBrowserに表示されたPDFの左上になります。
Excelにおける座標の単位はポイント(1ポイントは約0.35ミリ)で表されるので、2つ目の引数に200、3つ目の引数に150と入力するとPDFの一番左上の部分から右方向(X軸)に7cm、下方向(Y軸)に5.25cm進んだ位置が表示されることになります。
つまり上記のコードは、コマンドボタンを押すとWebBrowserに表示されているPDFの表示倍率が100%になり、右方向に7cm、下方向に5.25cmスクロールされた箇所が表示されることになります。
今回はコマンドボタンを使って表示位置を調整できるようなコードを書きましたが、別にUserForm_Initializeで最初からPDFの表示される位置が指定の箇所になるようにしてもいいですし、PDFを切り替える度(スピンボタンを利用した場合など)に表示位置が調整されるようにすることもできます。
使う人が使いやすい形のコードに変えていけるのが一番良いと思います。
ちなみに、ExcelVBAには「WebBrowser」というコントロールがあり、そのコントロールの追加・設定方法、さらに「Set P = WebBrowser1.Document」というコードを利用するとWebBrowserコントロールを通してPDFを操作できる点については以下の過去記事でも触れています。
WebBrowserコントロールでPDFを操作できるようになるまでに試してみたコード
今回引用したコードはすごく簡単に見える気がしますが、このコードに辿り着くまでに非常に苦労しました。
まず「情報自体が少ない」という状態でした。ExcelVBAであればメジャーなプログラミング言語なので関連書籍もたくさん出ていますし、インターネットでも簡単に多くの情報を探し出すことが出来ます。
一方ExcelVBAからPDFを操作する情報というのは非常に少ないです。まずそういった本自体も見たことがない(探せばあるかもしれません)ですし、インターネット上でもなかなかわかりやすい情報がなかったので、四苦八苦して自分の手を動かすという方法を取らざるを得ませんでした。
WebBrowserコントロールを格納したオブジェクト変数を通してPDFを操作できるようにする方法を思いつく前は、例えば大きく分けて次のようなコードで試行錯誤してました。
- Image1.Picture = LoadPicture(“○○○”)
- WebBrowser1.Document.Body.Style &= “;Zoom:200%”
- WebBrowser1.Document.Body.runtimeStyle.Zoom = “150%”
上記3つのコードについて、試行錯誤しながら気づいたことを順番に説明していってみます。
ExcelVBAのImageコントロールではPDFは表示できない
1はExcelVBAに元々あるImageコントロールを使ったコードです。最初は、これを使えばもしかしたらいけるんじゃないかと思って、コードをいろいろといじってみましたが駄目でした。ちなみにImageコントロールで表示できる拡張子は以下のようになっています。
- ビットマップ (*.bmp)
- JPEG (*.jpg)
- カーソル (*.cur)
- メタファイル (*.wmf)
- 拡張メタファイル (*.emf)
- GIF (*.gif)
- ランレングス (*.rle)
- アイコン (*.ico)
「Image」というぐらいですからJPEGやビットマップはいけるだろうと思っていました。今回良い機会なので一度Imageコントロールで使える拡張子の一覧を調べてみましたが、意外と使える拡張子が多いことに驚きます。けれどもこの一覧の中には「.pdf」の拡張子はありませんね。
コードを試行錯誤していた時はもしかしたら「PDF」も表示できるんじゃないかと試してみたが、元々表示できる拡張子は上記のように決まっているので、Imageコントロールで表示はできませんでした。
WebBrowserコントロールを通してのPDFの操作はどうしてもできなかった。だがしかし・・・
2つ目の「WebBrowser1.Document.Body.Style &= “;Zoom:200%”」というコードですが、インターネットで調べたコードを参考にさせていただきました。元々はVBで使われるコードのようです。
VBで使われるコードではありますが、VBAはVBをベースに作られたと言われています。ですからその言語環境の関連性などからもしかしたら動作するんじゃないかと淡い期待を抱いていましたが、見事に打ち砕かれました。
「Document」はWordVBAにおいては、Wordを構成する「文書」や「段落」などの要素を扱うためのオブジェクトとなっています。また、IE(InternetExplorer)で使われる時は、HTML文書を扱うためのプロパティとして使われます。
2と3で共通して使われている「Document.Body」の「Body」からもわかるように基本的にWebBrowserを通してIE(InternetExplorer)などのWeb画面を操作するために作られています。
インターネット上で調べた範囲でもWebBrowserを利用する方法のほとんどがIEに関する記述で、PDFを扱う情報は少数派です。
とはいうものの「WebBrowser1.Document.Body」というコードから、要は「WebBrowser」の内部情報、表示情報を操作するためのコードということだから、いろいろと試行錯誤していればいづれ上手くいく時が来るんじゃないかと思っていました。
しかしここまで書いた3つのコード(実際はもっとたくさんのコードを試しています。)では、どうしてもWebBrowserに表示されるPDFを操作できるようにはなりませんでした。
まぁ上手く噛み合わなかったということなんでしょうが、その後偶然にもWebBrowserコントロールをオブジェクト変数に格納して使うとPDFを操作できるようになるという方法に辿り着きます。
自分はVBA初心者なので具体的な内部構造まではわかりませんが、オブジェクト変数を利用することでコンピューターがそれまでとは違うオブジェクトとして認識するようになったということでしょうか。
とにかく詳細はわかりませんが、この方法で操作できるようになりました。
WebBrowserを通してPDFが操作できるというのは、かなり応用範囲が広がるのではないか
今回の記事と前回の以下の過去記事で思ったのは、PDFが表示されるWebBrowserコントロールをオブジェクト変数を通して使うとPDFの操作の応用範囲がかなり広がるんじゃないかと思いました。
実際にPDF関連のコードを全て試してみたわけではありませんが、いくつかは自分の意図通りに動作したコードもあったので、「お?これは!?」という感じでした。
ExcelVBAのフォームのWebBrowserコントロールを利用すると、開いたPDFを直接操作するコードよりも全然簡単なコードで操作できるので、今後はこの方法をいろいろと試していってみようかと思います。
コメント