Rangeオブジェクトの終端があるParagraphオブジェクトのインデックス番号を返すFunction(Word)

Rangeオブジェクトの終端があるParagraphオブジェクトのインデックス番号を返すFunction

更新頻度ガタ落ちですが、またしてもWordVBAネタです。

まずはコードを

お急ぎの方は、コードをコピッペして使ってください。

リスト1
Public Function getParagraphIndex( _
            ByVal tgtRange As Range) As Long
  Dim ret As Long
  tgtRange.Start = 0
  ret = tgtRange.Paragraphs.Count
  getParagraphIndex = ret
End Function

たったこんだけ。正味2行w

まさかこんなに簡単にできるとは思っていませんでした。

使ってみる

たとえば、テキトーなドキュメントを用意して、

f:id:akashi_keirin:20200704095029j:plain

こんなふうにテキトーに範囲を選択しておく。

画像では、4~5段落にまたがった範囲を選択している。

で、イミディエイト・ウィンドウに次のコードを書いて[Enter]を押す。

?getParagraphIndex(Selection.Range)

すると、

f:id:akashi_keirin:20200704095032j:plain

ちゃんと「5」が出力されておる。

バッチリ!

解説

こんなしょうもないコードだが、二つも発見があった。

短いコードなので再掲する。

リスト1(再掲)
Public Function getParagraphIndex( _
            ByVal tgtRange As Range) As Long
  Dim ret As Long
  tgtRange.Start = 0  '……(1)'
  ret = tgtRange.Paragraphs.Count  '……(2)'
  getParagraphIndex = ret
End Function

Start(End)プロパティはRead/Writeだった

これは、完全に思い込み。

勝手にRead onlyだと固く信じて疑っていなかった。

Microsoft Docsの「Range.Start Property」の項にも、

Range.Start property (Word)

Returns or sets the starting character position of a range. Read/write Long.

と明記してあるし。

(1)の

tgtRange.Start = 0

によって、tgtRangeが指し示すRangeオブジェクトの始端をドキュメントの先頭にしているわけだ。

RangeオブジェクトにもParagraphsコレクションがある

これも全然知らなかった。

Paragraphs」というぐらいだからてっきりDocumentオブジェクトの直参だと思っていた。

これまた、Microsoft Docsの「Range.Paragraphs Property」の項にはっきりと

Range.Paragraphs property (Word)

Returns a Paragraphs collection that represents all the paragraphs in the specified range. Read-only.

と書いてある。

つまり、(1)を実行した段階で、tgtRangeが指し示すRangeオブジェクトの範囲は、〈ドキュメントの始端~選択範囲の終端〉になっているわけなので、(2)の

ret = tgtRange.Paragraphs.Count

によって、〈ドキュメントの始端~選択範囲の終端〉に含まれる段落数、すなわち選択範囲の終端がある段落が先頭から数えて何番目か、を表す数値が変数retに返る、というわけだ。

最初にこのアイディアを考えついたやつは天才だと思う。

おわりに

世の中、天才だらけでいやになるぜ。