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

画像の配置でいらいらした

ページ横幅の中心位置を割り出そうとしたら謎だらけだった

問題のコード

写しPDF作成マクロを改良して、常にページ横幅の中心部分にハンコ画像が配置されるようにしようとしたら、謎だらけだったので書き残しておく。

リスト1
Dim objRange As Word.Range
Set objRange = objDoc_.Range(0, 0)
objRange.Select
Dim tmp As Long
tmp = CLng(Word.PointsToMillimeters(objDoc_.PageSetup.PageWidth))    '……(1)'
Dim tmpShape As Object    '……(2)'
With objDoc_
  .Shapes.AddPicture fileName:=imgPath, _
                          Top:=-20, _
                         Left:=0            '……(3)'
  Set tmpShape = .Shapes(.Shapes.Count)    '……(4)'
  tmp = tmp - CLng(tmpShape.Width / 2)    '……(5)'
  tmpShape.Left = tmp
End With

変数objDoc_にはWordのDocumentが、変数imgPathには、ハンコ用画像のフルパスが入っていると思ってください。

謎その1

リスト1の(1)、

tmp = CLng(Word.PointsToMillimeters(objDoc_.PageSetup.PageWidth))

では、ページ横幅の中心位置を割り出しているのだが、なぜこれで中心が割り出せるのか分からない。

コチラによると、

取得またはページの幅をポイント単位で設定します。読み取り/書き込み1 つです。

ということなので、

tmp = (objDoc_.PageSetup.PageWidth) / 2

こうしたら良さそうなものなんだが、実際こうすると、

f:id:akashi_keirin:20170429215154j:plain

とんでもなく右にずれる。

リスト1の(1)のようにすると

f:id:akashi_keirin:20170429215157j:plain

こんなふうにちゃんと真ん中になる。わけ分からん。

謎その2

リスト1の(2)のところ、

Dim tmpShape As Shape

と、Shape型にしたら良さそうなものなんだが、Shape型にすると「型が一致しません」エラーが出る。

わけ分からん。

しかも、「Dim tmpShape As」まで入力して半角スペースを入れると、インテリセンスで候補が出るんだが、

f:id:akashi_keirin:20170429215205j:plain

このように「Shape」が2つも出てくるし……。

んで、どっちを選んでも「型が一致しません」エラー。

マジでわけ分からん。

謎その3

画像を中心に据えるためには、画像の左端の座標が、

[ページの中心]-[画像の横幅の1/2]

になっていればよい。

画像の横幅を取得するのに、

LoadPicture関数

を使おうとしたらアンタ、

pngファイルには未対応とか!!!!!!!!

なんでやねん!

というわけで、リスト1の(3)~(5)のような、非常に面倒な方法を使った。

まず、(3)の

objDoc_.Shapes.AddPicture fileName:=imgPath, _
                               Top:=-20, _
                               Left:=0

で一旦ページの左端に画像を追加した。

追加した画像は、Shapesコレクションの末尾に追加されているはずなので、ShapesコレクションのCountプロパティの値をShapesコレクションのインデックスにセットしたら追加したてのShapeオブジェクトが取得できるはず。

というわけで、(4)の

Set tmpShape = .Shapes(.Shapes.Count)

で変数tmpShapeに追加したばかりの画像をセット。

あとは、(5)の

tmp = tmp - CLng(tmpShape.Width / 2)

で、画像の横幅の半分をページ中心の座標から引いてやれば、画像がほぼ中心にセットされることになる。

f:id:akashi_keirin:20170429215209j:plain

まとめ

  • PageSetupオブジェクトのPageWidthプロパティを半分にしているのにページ横幅の中心の値が得られないのはまるで意味が分かりません
  • PointsToMilliMeters関数の戻り値だけでページ横幅の中心が得られるのが意味分かりません
  • ShapeオブジェクトをShape型の変数にセットしようとしただけなのに「型が一致しません」とか言われるのは納得がいきません
  • LoadPicture関数がpng画像に対応していないのは意味が分かりません

とにかく、意味の分からないことばかりでいらいらしました。

@akashi_keirin on Twitter