カーソルが段落の先頭にあると正しい段落インデックスが取得できない(Word)
カーソルが段落の先頭にあると正しい段落インデックスが取得できない
[Range].Startプロパティと[Range].[Paragraphs].Countプロパティを用いる方法
Range
オブジェクトの終端がある段落インデックスを取得する方法は、かつて
で紹介したことがある。
簡単に言うと、
Range
オブジェクトのStart
プロパティを強引に「0
」にすることにより、Range
オブジェクトの始端をドキュメントの先頭にしてRange
オブジェクトを拡張。その中のParagraphs
コレクションの数(Count
プロパティで取得可能)を勘定する
というやり方である。
当時は、脳天気に「最初にこのアイディアを考えついたやつは天才だと思う。」などと喜んでいたものだ。
落とし穴があった!
ところが、「上手の手から水が漏る」のことば通り、先の方法には落とし穴があったのである!
落とし穴をお目にかけよう。
この通り、どう見てもカーソルは第4段落の先頭にある。したがって、Selection.Range
が返すRange
オブジェクトは、第4段落の先頭を指し示すのである。
しかし!
リスト1
Public Function GetParagraphIndex( _ ByVal a_Target As Range) As Long Dim ret As Long a_Target.Start = 0 ret = a_Target.Paragraphs.Count GetParagraphIndex = ret End Function
このGetParagraphIndex
メソッドに、Selection.Range
を渡して実行すると、
この通り、「3
」が返る〔*〕のである!
これでは全然だめである!
*
GetParagraphIndex
メソッドは、Normal.dotm
プロジェクトの標準モジュールParagraphUtil
に書いてあるので、このような呼び出し方になっている。
検証:なんでこうなるのか
先のリスト1に、次の1行を付け加える。
リスト2
Public Function GetParagraphIndex( _ ByVal a_Target As Range) As Long Dim ret As Long a_Target.Start = 0 Call a_Target.Select '……(*)' ret = a_Target.Paragraphs.Count GetParagraphIndex = ret End Function
a_Target
のStart
プロパティを「0」にした直後、つまりa_Target
の始端をドキュメントの先頭まで拡張した直後に、Select
メソッドを実行して止めてみる。
確かに、第3段落目までしか選択されていない。
道理で「3
」が返るわけである。
検証終わり。
おわりに
というわけで、カーソルが段落の先頭にある場合にも正しい段落インデックスを返すように、改修する必要があります。
いちおう、改修自体はしているのですが、なんとも不細工なやり方で、もっとスマートな方法はないものか、と思っています。
〈カーソルが段落先頭にあることを判定するスマートな方法〉を知っていたら教えろえてください。