こんにちは!マクロの記録を卒業し、「よし、本格的にWord VBAを使いこなすぞ!」と意気込んでいるあなたへ。
Word VBAの世界へようこそ。
ここまで来ると、ドキュメントの中を縦横無尽に動き回る「Rangeオブジェクト」の魅力、そして同時にその気難しさに気づき始めている頃ではないでしょうか。
「あれ?今扱っているこのRangeと、さっき取得したあのRange、指している場所はまったく同じなんだろうか?」
「指定した範囲の中に、別の範囲がすっぽり含まれているかどうかを判定したいんだけど……」
Excel VBAならセルのアドレス(`A1`とか)で一発比較できますが、文字の塊であるWordのRangeには「番地」という概念がありません。
でも、安心してください。ここをクリアすれば、あなたのWord VBAのスキルは「初級者」から「中級者」へと確実にステップアップします。今日は、二つのRangeオブジェクトを比較し、その関係性を暴くための極意を、優しく、そして深く伝授しましょう。
—
1. Word VBAの「位置」と「範囲」の正体を知る
まず大前提として、Wordの`Range`オブジェクトが何者であるかを頭に叩き込んでおきましょう。
Excelのセルは「箱」ですが、WordのRangeは「文書の始まりから終わりまでの間にある『始点(Start)』と『終点(End)』という文字カウンターの数値」です。
- Start: 範囲の先頭が、文書の先頭から何文字目にあるか(0始まり)
- End: 範囲の末尾が、文書の先頭から何文字目にあるか
つまり、Wordにおける位置の比較とは、突き詰めると「整数の大小比較」に他なりません。この本質を知っていれば、どんな複雑な判定も怖くありませんよ。
—
2. 完全に一致するかを調べる:`IsEqual` メソッド
まずは、「二つのRangeが、全く同じ場所を指しているか」を判定するスマートな方法です。
もちろん `Range1.Start = Range2.Start And Range1.End = Range2.End` と書いても判定できますが、Word VBAには専用の美しくエレガントなメソッドが用意されています。それが `IsEqual` です。
基本的な使い方
Sub CheckRangeEqual()
Dim rng1 As Range
Dim rng2 As Range
‘ 適当にRangeを設定(ここでは段落全体と、その中の文字)
Set rng1 = ActiveDocument.Paragraphs(1).Range
Set rng2 = ActiveDocument.Paragraphs(1).Range
‘ IsEqualメソッドで比較
If rng1.IsEqual(rng2) Then
MsgBox “二つのRangeは完全に一致しています!”, vbInformation
Else
MsgBox “別々の場所を指しています。”, vbExclamation
End If
End Sub
💡 ここで陥りやすい罠
「えっ、同じ段落を指しているなら、変数の中身が違っても `IsEqual` は `True` になるの?」
はい、指している文書上の位置と範囲が同じであれば `True` になります。
ただし、対象となる文書(Document)そのものが違う場合は、エラーになるか `False` を返すため、必ず同じドキュメント内のRange同士を比較するようにしてくださいね。
—
3. 包含関係を暴く:Start と End の論理演算
「完全一致」だけではなく、「範囲Aの中に範囲Bがすっぽり含まれているか(包含関係)」を調べたいシーンは、文書の解析や重複削除ロジックにおいて本当によく出てきます。
ここで登場するのが、先ほどお話した `Start` と `End` の数値を使った論理演算 です。
図解イメージ:包含関係とは?
[ 範囲A (外側) ]
├── Start (例: 10)
│ [ 範囲B (内側) ]
│ ├── Start (例: 15)
│ └── End (例: 25)
└── End (例: 50)
範囲Aの中に範囲Bが含まれている条件は、算数・数学で考えると非常にシンプルです。
- 「範囲AのStart」 ≦ 「範囲BのStart」 かつ
- 「範囲BのEnd」 ≦ 「範囲AのEnd」
このロジックをコードに落とし込んでみましょう。
実用コード:包含関係を判定するファンクション
現場でそのままコピペして使える、美しい判定関数のサンプルです。
Sub TestContainsRange()
Dim parentRng As Range
Dim childRng As Range
‘ 例として、文書全体を親、第1段落を子とする
Set parentRng = ActiveDocument.Content
Set childRng = ActiveDocument.Paragraphs(1).Range
‘ 自作の関数で包含関係をチェック
If IsRangeContained(parentRng, childRng) Then
MsgBox “親Rangeの中に、子Rangeが完全に含まれています!”, vbInformation
Else
MsgBox “含まれていません。”, vbExclamation
End If
End Sub
‘ — 包含判定を行う汎用ファンクション —
Function IsRangeContained(ByOuter As Range, ByInner As Range) As Boolean
‘ ByOuterの中に ByInner がすっぽり入っているか判定
If ByOuter.Start <= ByInner.Start And ByInner.End <= ByOuter.End Then
IsRangeContained = True
Else
IsRangeContained = False
End If
End Function
---
4. 応用編:重複削除や複雑な文書解析へのアプローチ
なぜ、このようなRangeの比較が必要なのでしょうか?
例えば、文書内から特定のキーワード(例:「重要」)を複数検索し、そのキーワードが「特定の太字部分(Bold)」の中に含まれている場合だけ処理をスキップしたい、といった複雑な要件を考えてみてください。
1. 検索で見つかったキーワードのRangeを取得する。
2. あらかじめ収集しておいた「太字部分のRangeリスト」と一つずつ比較する。
3. `IsRangeContained` を使って、「太字のRangeの中に、キーワードのRangeがすっぽり含まれているか」を判定する。
4. 含まれていれば処理を分岐させる。
このように、「位置の比較」ができるようになると、Word VBAで扱える自動化の幅が何倍にも広がります。 単なる「文字の置き換え」から、「文書構造のコンテキスト(文脈)を理解した高度な処理」へとステップアップできるのです。
—
まとめ
- WordのRangeの本質は、文書の先頭からの文字数を示す `Start` と `End` の数値である。
- 完全に同じ範囲を指しているかの比較には `IsEqual` メソッドを使うとスマート。
- 包含関係(含まれているか)を調べたいときは、`Start` と `End` の大小を論理演算子(`<=` や `And`)で組み合わせる。
ここをクリアすれば、あなたのWord VBAの基本はもうバッチリです!
ぜひ、実際の業務データやテスト用の文書で、この比較ロジックを試してみてくださいね。あなたの自動化ライフが、より一層快適なものになりますように!
