読者です 読者をやめる 読者になる 読者になる

写しPDF作成マクロ~(3)―ページ先頭位置を割り出して画像を追加する―

VBA一般 VBA覚書 WordVBA

Wordドキュメントに画像を貼り付ける

今回作成するマクロでは、Wordドキュメントにpng画像を貼り付ける必要がある。しかも、その処理をExcelから行う、という無駄にややこしい仕様w

とりあえず、今回は

Wordドキュメントの各ページの先頭中央にpng画像を貼り付ける

ことに特化して書く。

ExcelVBA使いにとって、WordVBAって、

似ているのに何かちょっとクセがつかみづらい

気がするので、自身の覚書も兼ねてちょっとこってり書くよ。

やるべきこと

ひとまず、やるべきことを整理しておこうかね。

参考文献は土屋和人さんの『Wordマクロ/VBA徹底入門』という本。

WordVBA関連の情報ってホントに乏しくて、本屋で見つけて清水の舞台から飛び降りるつもりで定価購入した直後に敦賀ブックオフで500円ぐらいで売っていたのを見つけてずっこけたのは良い思い出だw

閑話休題

  1. ドキュメントの先頭を選択する
  2. png画像を貼り付ける(追加する)
  3. Wordの「検索」機能を用いて改ページ位置を割り出す
  4. 改ページ位置の次の場所を選択する
  5. 改ページが見つからなくなるまで繰り返し

とまあ、これだけのことをやらせればよい。

使用したコード

下に挙げるコードは、クラスのメソッドとして書いたものの抜粋。従ってよく分からん変数が使われていると思うので、先に説明しておく。

objRange

こいつは、WordのRangeオブジェクトを格納するための変数。

objDoc_

こいつは、クラス内で操作対象のWordのDocumentをセットしておくための変数。

imgPath

こいつは、このメソッドに渡される引数で、ハンコ用のpngファイルのフルパスが入っている。

まあ、これだけのことを頭に置いて、次のコードを読んでくだされ。

Dim objRange As Word.Range                                       '……(1)
Set objRange = objDoc_.Range(0, 0)                               '……(2)
objRange.Select                                                  '……(3)
Do
  objDoc_.Shapes.AddPicture fileName:=imgPath, _
                            Top:=0, _
                            Left:=200                            '……(4)
  With objWord_.Selection.Find                                   '……(5)
    .MatchWildcards = False                                      '……(6)
    .MatchFuzzy = False                                          '……(7)
    .Text = "^m"                                                 '……(8)
    .Execute Forward:=True                                       '……(9)
	End With
  Set objRange = objDoc_.Range(objWord_.Selection.End + 1, _
                               objWord_.Selection.End + 1)       '……(10)
    objRange.Select                                              '……(11)
Loop Until objWord_.Selection.Find.Found = False                 '……(12)

コードの説明

久しぶりに読んでみたら、すっかり意味を忘れていたのでw 復習も兼ねてしっかり説明しよう。

  • (1)は、WordのRangeオブジェクトを格納するための変数の準備。このコードはExcelのモジュールに書いているので、型を指定するときに「Word.Range」と書いているところが注意かな。
    ※実は、私、これでしばしハマりました。
  • (2)で、Wordドキュメントの0文字目~0文字目、つまり文書の先頭位置をobjRange_に格納している。
  • (3)で、その位置を選択している。
    f:id:akashi_keirin:20170319084940j:plain
  • (4)で、png画像を追加。AddPictureメソッドを使用。Topプロパティの「0」はともかく、Leftプロパティの「200」は完全に目分量。
  • いよいよ(5)からが本番。(5)~(9)の説明の前に画像をば。

f:id:akashi_keirin:20170319084955j:plain

スキルがないので、画像が汚くてすまん。そのうち勉強する。

赤で書き込んだのが今回使用するプロパティ。

  • (5)では、SelectionオブジェクトのFindプロパティを参照。Withしているので、ここから先はFindオブジェクトに対する操作。

最初はコレが分からなかった。「Find」なんて言ったらメソッドだと思うよねえ……。このFindオブジェクトというのは、
f:id:akashi_keirin:20170319084955j:plain
こいつのことなんだな。

  • (6)、(7)で、ワイルドカードとあいまい検索(日)をオフにしている。特にMatchFuzzyプロパティをFalseにしておかないと、この後の特殊文字の検索ができないので注意。
    ※ちなみにここでも相当長時間ハマりました。
  • (8)で検索する対象をセット。「^m」ってのは「改ページ」を表す特殊文字
  • ここまでで検索の設定ができたので、(9)で検索を実行。「execute」ってのは、「exeファイル」でおなじみ、「実行する」って意味だよね。
  • あと、Excecuteメソッドの引数「Forward」ってのは「次を検索」ってやつだな。

f:id:akashi_keirin:20170319085006j:plain

ちなみに、この時点で、「Selection」オブジェクトの「End」プロパティには「171」が入っていることが分かる。

f:id:akashi_keirin:20170319085016j:plain

Wordの方では、改ページ記号が選択されている。

  • (10)で、現在選択中の最後の場所の次の場所、すなわち、次のページの先頭を新たにobjRangeにセット。
  • (11)でその場所を選択。
    f:id:akashi_keirin:20170319085026j:plain
  • (12)は繰り返し判定。検索の結果、検索対象が見つかっていなければ、FindオブジェクトのFoundプロパティにFalseが返るので、その場合はループを抜ける、ということ。

おわりに

WordVBAって、いまいち使いどころがよく分からないけれど、このFindオブジェクトの使い方はしっかり身につけておいたら、いろいろ面白そうだ。

@akashi_keirin on Twitter