Microsoft Word®には、単純な処理を反復して行うときに便利な、マクロという機能が備わっております。
Visual Basic for Applications(略して「VBA」)とも呼ばれておりますが、言葉のとおり、Visual Basic言語から派生した言語です。
操作を記録することでマクロを作成する方法もありますが、Visual Basic言語がわかる方ならマクロのコードを直接書くこともできます。
世の中が.NET Frameworkへとシフトしていく中、マクロは依然としてVBAのまま新しいバージョンにも引き継がれております。
.NET FrameworkとしてはVisual Studio Tools for Office(略して「VSTO」)というソリューションも用意されているものの、配布や導入の手軽さからか、.NET Frameworkが普及した現在でもマクロの人気は根強いものがあります。
僕もいまだにマクロの開発依頼を受けることが多いです。より正確に言いますと、VSTOの開発依頼を受けたことがないほどです。
ここから本題
そんな手軽で便利なマクロですが、マクロのコードを直接書くみなさんは次のような体験をしたことはありませんでしょうか。
-
たくさんあるファイルのページ数をひたすらカウントしたいのだけど、正確なページ数が取得できないファイルがある。
-
たくさんあるファイルから、ある条件に合致するものが何ページの何行目にあるか知りたいのだけど、正確なページ番号が取得できないファイルがある。
-
たくさんあるファイルから、段落や表の設定値を取り出したいのだけど、正確な値が取得できないファイルがある。
必ずではないけれども、たまにちゃんとした値が取得できない事態って、開発者としては本当に困りますよね。
今回は、そんな事態を避けるための解決策をご紹介したいと思います。
原因は、Microsoft Word®のページ調整タイミングにある
Microsoft Word®で一定以上のボリュームのある文書を開いてスクロールしていくと、ステータスバーに表示された総ページ数がどんどん増えていく、そんな場面を目撃したことはありませんか。
Microsoft Word®は、文書を開いた瞬間にはちゃんとした総ページ数を算出しておらず、最もひどいケースでは最後のページまで進んでいって初めて算出される、といった動作をします。
特に、段落設定で改ページを指定してある文書や、セクション区切りを入れてある文書においては、この現象が顕著に表れます。
マクロで文書を開くと、文書の先頭部分が表示されている状態になります。
この状態で、上述のような値を取得しようとすると、ちゃんと算出される前の値を取得してしまうことになり、文書によっては正確な値が取得できないという現象に繋がっているのだろうと推測します。
値を取得する前にページ調整させること
要は、値を取得する前に、Microsoft Word®がページ調整を済ませてくれればよいわけです。
つまり、値を取得する前に、Microsoft Word®がページ調整をしなければならないような状況を作ってあげればよい、ということになります。
そして答えがコレ
今回は「さくっと解決シリーズ」史上最短となるかも知れませんが、答えを書いちゃいます。
値を取得するコードの前に、次のコードを入れるだけです。
Public Sub PageCount()
Dim WdDoc As Document
Set WdDoc = ActiveDocument
WdDoc.Paragraphs(WdDoc.Paragraphs.Count).Range.Select
'値を取得するコード
Set WdDoc = Nothing
End Sub
文書の最後まで表示させればページ調整が完了するわけですから、手っ取り早く文書の最後を表示させてしまえばよいというわけです。簡単ですね。
この一文を入れるだけでほぼ解決するだろうと思いますが、そこはやはりMicrosoft Word®ですから、これでも解決しない事例ももしかしたらあるかも知れません。
マクロ開発者の宿命ですが、「これですべて大丈夫!」と安易に高を括らずに、「想定外のことは起こるかも知れないよ」とユーザに伝えることもお忘れなく。
ちなみに、セクション区切りがいっぱい入っていたりするような複雑な文書では、この方法でもページ数を正確に取得できない場面が必ずあります。
Microsoft Word®2007からはPDFに変換する機能も備わったことですし、一旦PDFに変換してPDFのページ数を何らかの方法で取得することもご検討ください。