「えっ!?こんな簡単なコードでいいの?」
少し前にExcelVBAのフォームのWebBrowserというコントロールを通してPDFを拡大や縮小できないかといろいろと試行錯誤していました。
もちろん自分にはそれまでそんな知識はなかったのでインターネットで調べながらコードの試行錯誤をしていたのですが、全く突破口が見えませんでした。それらしい情報もないことはないのですが、ちゃんとしたコードがどうしても見つけられませんでした。
これが本当に全くの偶然なのですが、とあるコードから簡単にPDFを拡大縮小できるようになったのです。
このことについて今回書いていってみます。
ExcelVBAから外部アプリケーションの操作は難しいし情報自体が少ない
ExcelVBAでExcelを操作するのであればそれほど難しくは感じないのですが、ExcelVBAから外部アプリケーションを操作するとなると勝手が違ってきます。その中でも「PDF」の操作はVBAの初心者にとっては難しいのではないでしょうか。
どうやらExcelVBAから外部アプリケーションを操作できるようになるためには、その外部アプリケーションの「オブジェクトモデル」の理解が必要なようで、これがいろいろと複雑で難しいのです。
ExcelやAccessは関連書籍があるのでまだいいですが、それ以外となるとそもそも本自体が少ない、もしくは売られていないしインターネット上での情報自体も少ないです。ですからExcelVBAからPDFを操作できるようにするには、基本的に手を使った「思考錯誤」が必要でした。
もちろんインターネット上に情報がないことはないのですが、「これは!」と思うような題名の記事があっても記事内に具体的なコードがないとか、あっても自分のような初心者から見ると非常に難解だったりとかあまり参考になりませんでした。
そんな状況で偶然ではありますが、ExcelVBAのフォームのWebBrowserというコントロールを通してPDFの拡大や縮小ができるコードを見つけたので今回整理していってみます。
ExcelVBAのWebBrowserでPDFを拡大縮小させるコード
結論としては次のコードになります。Excel2013で動作を確認しました。
Private Sub ScrollBar1_Change() Dim P As Object Set P = WebBrowser1.Document P.setZoom (ScrollBar1.Value) End Sub
このコードを解説すると、まずはVBEのプロジェクトエクスプローラーにフォームモジュールを挿入、挿入したフォームモジュール上にWebBrowserコントロールとスクロールバーコントロールを設置します。それからスクロールバーのChangeイベントプロシージャとして上記のコードを記述します。
2行目でオブジェクト型の変数Pを宣言します。3行目でWebBrowser1.Documentをオブジェクトとして変数Pに格納。4行目でWebBrowser1.Documentを格納した変数PをsetZoomメソッドの引数ScrollBar1の値から拡大縮小できるようにしています。
もちろんフォームを表示させる上で上記以外のコードも必要です。事前にユーザーフォームの初期設定としてUserForm_InitializeプロシージャからWebBrowserコントロールのNavigateメソッドを通してPDFを表示できるようしておく必要があります。
「WebBrowser」というぐらいですからWebとかInternetExplorerの画面を表示させる方法が一般的かと思いますが、自分のパソコンにあるPDFもパスを通して表示させることが出来ます。
ちなみにWebBrowserは最初の状態ではVBEのツールボックスからは選択できません。
そのため、ツールボックスを表示させたら右クリック、するとショートカットメニューが表示されます。その中の「その他のコントロール」を選択、「コントロールの追加」ダイアログボックスが表示された後、その中から「Microsoft Web Browser」を選択してください。
「コントロールの追加」ダイアログボックスから「Adobe Acrobat Dc Browser Contorol Implementation」とか「Adobe PDF Reader」というコントロールも選択は出来ます。
しかし、詳しいバージョンは忘れてしまったんですが、Excel2007かExcel2010のフォームで使おうとするとExcelファイルを開く時にどうしても警告メッセージが表示されてしまいます。
Application.DisplayAlerts = Falseを使えば大丈夫だろうと思ったのですが、このコードを使っても警告メッセージが表示されてしまいました。
これを出ないようにするは「レジストリ」の操作が必要になってくるようです。レジストリとはOSのWindowsの設定情報のデータベースであり、ここを操作するというのはパソコンの操作全般に影響が出てくるので注意が必要です。
ここを操作するということは、もしかしたら何らかの手違いでパソコンの調子がおかしくなってしまう可能性もあります。また、自分以外の人が使うかもしれないことを考えると、警告メッセージが出る度に毎回その人にパソコンのレジストリの操作をしてもらわなければいけなくなります。
以上のことを考慮すると「Adobe Acrobat Dc Browser Contorol Implementation」や「Adobe PDF Reader」コントロールの使用は却下せざるを得ません。
また、Excel2013の場合はフォームに設置しようとした時点で「要素が見つかりません」とメッセージが表示されて、そもそもコントロールが設置できませんでした。
そういう経緯もあってWebBrowserを使うという方法を考えました。
PDFを拡大縮小できるようにしようと思ったきっかけ
そもそもフォーム上からPDFを操作できるようにしたいと考えたきっかけは、PDFファイルの内容から名前を変更できるようにしたいと思ったからです。
PDFの中身の内容にある情報から判断してPDFファイル名を変更するとしたら一旦開く必要があります。しかし、ExcelVBAでPDFファイルを開く操作は出来ますが、開いた後のPDFの操作方法はその時の自分では思いつきませんでした。
上手く言えないんですが、一旦PDFを開いたら開いたPDFのコントロールを失うというか、それぞれ個別に判断したいんだけど、ある開いたPDFをクリックしたらその時にExcelから判断できるのか・・・
みたいな感じでとにかく処理方法とかどういったコードにすればいいか思いつかなかったんです。それで他に代替案はないか考えを巡らせていた所思いついたのが「フォームで表示させて操作する」という方法です。
この方法であれば、個別にPDFファイルを選択してフォーム上に表示させて操作できます。例えば「A」というPDFをフォーム上から表示させれば、「A」をコントロール下に置いた状態で操作できるようになります。
その状態であればそれぞれのPDFファイルを個別に判断して個別に操作できます。そこまでの考えには至ったのですが、それを「実現」させるための「コード」を見つけるのに非常に苦労しました。
また、PDFの内容からファイル名を変更する時に通常の倍率ではわからない時もあり得ます。もしくは一番最初に表示された時に文字が大きすぎるとか小さすぎるといった可能性もあります。
フォーム上からPDFを操作した時に発生すると考えられる問題の中のひとつに、内容が人によっては「見づらい」可能性も考えられたのでPDFも拡大縮小できるようにしたら利便性が上がるんじゃないかと考えました。
「フォームを使ってPDFを操作する」というアイデアは我ながら良いアイデアだとは思ったのですが、次の2点が問題でした。
- どうやってフォーム上にPDFを表示させるか
- フォーム上に表示させたPDFをどうやって操作するか
1については、それほど時間はかからずに解決策が見つかりました。冒頭でも書きましたが、インターネットで調べていたら「Web Browser」というコントロールが存在することを知ります。
これでWebBrowser1.Navigate ()というコードとPDFのパスを使うことでフォーム上にWebBrowserを通してPDFを表示させる所までは辿りつく事が出来ました。
他にも「Adobe Acrobat Dc Browser Contorol Implementation」や「Adobe PDF Reader」コントロールを使おうとした時に表示されたエラーメッセージや警告メッセージも表示されないので、このコントロールを使わない手はないと思いました。
問題は、2の「フォーム上に表示させたPDFをどうやって操作するか」です。
フォーム上のWebBrowserを通して表示させたPDFをどうやって操作するか
この部分まで辿りついた時は、全くもって甘く考えていました。なぜなら「後は、インターネット上にあるコードをコピペして多少いじればできるだろう」と考えていたからです。
インターネット上の情報は膨大です。ExcelVBA関連の情報については、ちょっと調べれば山のように詳しい情報が出てきます。
また、ExcelVBAというものがMicrosoft Officeに搭載されて広く使われるようになって(Wikipediaによると「1994年、マイクロソフトはExcel 5.0とともにVBAをリリースした。」とある)から20年以上経っているんだから「VBA関連の情報はほとんど網羅されているはずだ」と高を括っていました。
ですから「VBA関連についての情報はすぐに見つかるだろう」と思っていたのですが、現実は全く違ってました。以下の過去記事にも書いたのですが、自分の欲しい情報がどうしても見つからなかったんです。
最初の内は「自分の探し方が悪いんだろう」とか「自分が見落としてしまっているんだろう」と思っていました。けれども自分の欲しい情報、今回でいうところの「フォーム上でPDFを拡大縮小させるコード」がどうしても見つかりません。
なかなか欲しい情報が見つからないことに業を煮やし、自分もコード上で試行錯誤を始めました。
最初の内はインターネット上の他の人のサイトにあるコードを参考に、自分のパソコンでいろいろといじってみたのですが、そもそもPDFのオブジェクトモデルを理解してないのだからそんな簡単に上手くいくはずがありません。
「参照設定がちゃんとできていないからではないか」と思って、VBEの「ツール」→「参照設定」から表示される「参照可能なライブラリファイル」ダイアログボックスからPDF関連の項目にチェックを入れて試してみても上手く動作しませんでした。
「何が足りないんだろう」と考えながら、とにかくコードをいじっていたのですが、ある時のことです。既に引用しましたが次のコードを入れてデバッグで1行ずつ進めていた時のことです。
Set P = WebBrowser1.Document
「VBAから直接WebBrowserを通してPDFは操作できないのか?じゃあオブジェクト変数に入れる方法は?」などと考えながらとにかく手を動かして試行錯誤しながら偶然作ったのが上記のコードです。
VBAでF8キーを押しながら1行ずつデバッグしていると黄色のラインが上から下に順番に進んでいくのですが、エラーがあるとそれに対応したメッセージが表示されてしまいます。
しかし、この時は何も問題が起きずに黄色のラインが上記の引用したコードを通り過ぎました。
「えっっっっっっっっっ!?」
この時は本当にびっくりしました。「えっ?それ通るの?」と思わずにはいられませんでした。詳しい内部構造はわかりません。とにかくWebBrowserコントロールがオブジェクト変数Pに格納されたわけです。
以下に今回引用したコードを再掲します。
Private Sub ScrollBar1_Change() Dim P As Object Set P = WebBrowser1.Document P.setZoom (ScrollBar1.Value) End Sub
最初からスクロールバーコントロールを使っていたわけではありませんが、とにかく上記のコードからフォーム上でPDFを表示しながら操作が可能となり、「拡大縮小」ができるようになったわけです。
最初の内はこんな簡単なコードでいいのか信じられませんでした。なぜならインターネット上で調べた他のPDF関連のコードはほとんどPDF専用のコードを使っていて難解で、なおかつ行数もかなりあったからです。
でもとにかくこれで自分の思ったとおりに動作をしたので、「あぁこういったやり方、こういったコードもあるんだなぁ」と勉強になりました。
まとめ
今回の件で思ったのは、過去記事にもいくつか書いたのですが、「インターネット上には意外にも自分の欲しいコードが見つからない」ということです。
VBAは歴史もあるし、Excelを通して使ってきた人も多いはず、だから「VBA関連の情報はほぼ網羅されているに違いない」と以前は思っていました。しかし今回の件から、「全ての情報が探し出されたわけではなく自分で試行錯誤しなければいけないこともある」ということを学びました。
なんというか、自分が探していた情報の領域はあまり他の人が手をつけてこなかったのかもしれませんし、需要がなかったのかもしれません。世の中にはまだまだ自分の思いも寄らない世界、気づいていない世界があるのかもしれないなと思った出来事でした。
コメント