Word VBAの深淵へようこそ:表内の画像を「セル幅」に完璧に適合させる極意
こんにちは。業務自動化の現場で、日々コードと格闘している皆さんのパートナー、チーフアーキテクトです。
「マクロの記録」を使って、なんとか自動化の一歩を踏み出した。素晴らしいですね。その一歩が、エンジニアとしての旅の始まりです。しかし、あなたは今、こんな壁にぶつかっていませんか?
- 「表の中に画像を挿入したけれど、サイズがバラバラで見た目が美しくない」
- 「セルの幅を変えると、画像がはみ出したり、逆に小さすぎたりする」
- 「マクロを記録した通りに動かしても、データの量が変わるとエラーになる」
安心してください。これらはすべて、「オブジェクトの性質」と「動的な計算」を理解することで、必ず突破できる壁です。
今日は、中級者への登竜門とも言える、「Wordの表内にある画像を、セルの幅に合わせて自動リサイズする」というテクニックを伝授します。単なるコードの書き方だけでなく、「なぜそうするのか」という設計思想まで、魂を込めて解説しますね。
1. なぜ「マクロの記録」では太刀打ちできないのか?
マクロの記録は、いわば「あなたの操作の録画」です。
「画像Aを、幅5cm、高さ3cmにする」という命令は記録できます。しかし、それは「その時、その画像に対して」しか通用しません。
実務では、セルの幅はデータの入力状況によって変わりますし、挿入される画像の解像度もバラバラです。
私たちが目指すべきは、「セルの幅を調べ、その幅を基準にして、画像のサイズを計算し直す」という、論理的なアプローチです。
2. 鍵を握る主役:`InlineShapes` と `LockAspectRatio`
この問題を解くために、2つの重要なプロパティ(性質)を理解しましょう。
① InlineShapes(インラインシェイプ)
Wordにおける画像には、大きく分けて2種類あります。
- Shape: 文字の上に浮いているような、自由に配置できる画像。
- InlineShape: 「文字」と同じ扱いを受ける画像。
表(Table)の中で画像を扱う場合、基本的にはInlineShapeとして扱われます。なぜなら、セルの中に「文字」として収まっている方が、レイアウトが崩れにくく、制御が容易だからです。
② LockAspectRatio(縦横比の固定)
ここが最も重要なポイントです。
画像をリサイズするとき、幅だけを変えて高さを変えないと、画像が「ひょろ長く」なったり「ぺちゃんこ」になったりします。
`LockAspectRatio = msoTrue` と設定することで、「幅を変えたら、高さも自動でいい感じに調整してね」とWordに命令できるのです。
3. 実践:セル幅に合わせる魔法のコード
それでは、実際に使えるコードを見てみましょう。このコードは、「文書内のすべての表」をスキャンし、その中のセルに画像があれば、セルの幅に合わせてリサイズするものです。
Sub ResizeImagesInTables()
Dim tbl As Table
Dim cel As Cell
Dim iShp As InlineShape
Dim targetWidth As Single
Dim padding As Single
' セルの余白(マージン)を考慮するためのバッファ
' セルの幅いっぱいに画像を広げると、枠線に当たってレイアウトが崩れることがあるため
padding = 2
On Error Resume Next ' エラーが発生しても処理を続行(画像がないセル対策)
' 1. 文書内のすべての表をループで処理
For Each tbl In ActiveDocument.Tables
' 2. 表の中のすべてのセルをループで処理
For Each cel In tbl.Range.Cells
' 3. そのセル内に InlineShape(インライン画像)があるか確認
' セル内の範囲(Range)にInlineShapesコレクションが含まれているかチェック
If cel.Range.InlineShapes.Count > 0 Then
' セル内の最初の画像を取得
Set iShp = cel.Range.InlineShapes(1)
' --- ここからがリサイズの核心部 ---
' A. 縦横比の固定を有効にする(これがないと画像が歪む)
iShp.LockAspectRatio = msoTrue
' B. ターゲットとなる幅を計算
' セルの幅から、左右の余白分(padding)を引く
targetWidth = cel.Width - padding
' C. 幅を適用する
' LockAspectRatioがTrueなので、高さは自動的に計算される
iShp.Width = targetWidth
' ----------------------------------
End If
Next cel
Next tbl
On Error GoTo 0 ' エラーハンドリングを元に戻す
MsgBox "画像のサイズ調整が完了しました!", vbInformation, "完了"
End Sub
4. プロの視点:ここをクリアすれば「基本はバッチリ」
コードを書き終えた後、さらに一歩上のエンジニアになるための「考察」を共有します。
なぜ `padding`(余白)が必要なのか?
`cel.Width` はセルの正確な幅を返しますが、Wordのセルには「セルの左右の余白(Cell Padding)」が存在します。
もし `iShp.Width = cel.Width` としてしまうと、画像が余白を無視して枠線に食い込もうとし、結果として「セルの幅が勝手に広がってしまう」という現象が起きます。これを防ぐために、少しだけ小さめに設定するのが、プロの「気遣い」です。
パフォーマンスの重み
上記のコードは、すべての表、すべてのセルをチェックします。もし100ページある文書で、表が数百個あった場合、処理に時間がかかる可能性があります。
実務では、`ActiveDocument.Tables(1)` のように、「処理対象の表を特定して絞り込む」ことで、実行速度を劇的に改善できます。
エラーハンドリングの重要性
`On Error Resume Next` を使っていますが、これは「画像がないセル」でエラーが出るのを防ぐためのものです。ただし、使いすぎは禁物です。本来、エラーは「何かがおかしい」という重要なサインですから、意図的に使っていることを意識しましょう。
最後に
いかがでしたか?
「マクロの記録」で得た断片的な知識を、このように「論理的な組み立て」へと昇華させていくこと。それが、単なる「マクロ使い」から、真の「業務自動化エンジニア」への脱皮です。
今回のコードは、あなたの武器になります。まずは自分の手元の文書で試してみてください。少しずつ、自分の思い通りにWordを操れる感覚が掴めてくるはずです。
もし躓いたら、いつでも戻ってきてください。応援していますよ!
