隠し文字を検索してカーソルを移動する(Word)

隠し文字を検索してカーソルを移動する(Word)

隠し文字は表示しないと検索に引っかからない

隠し文字は、編集画面上で非表示になっていると、Findオブジェクトを用いた検索に引っかからない。(もちろん、ふつうに検索ダイアログボックスを用いて検索しても引っかからない。)

だから、隠し文字のところを目印に、カーソルを移動させるには、ひと工夫が要る。

  • 一旦、非表示の隠し文字を表示する。
  • 検索する。
  • 選択状態のカーソルを潰す。
  • 隠し文字を非表示に戻す。

とまあ、こんな具合。

隠し文字を検索してRangeを返すFunction

まず、任意の隠し文字を検索して、ヒットしたらその箇所のRangeを返し、ヒットしなかったらNothingを返すFunctionを作る。

リスト1
Private Function getNextHiddenTextRange( _
                 ByVal a_Text As String) As Range
  Dim ret As Range
  With Selection.Find
    Call .ClearFormatting
    Call .Replacement.ClearFormatting
  End With
  With Selection.Find
    .Format = True    '……(*)'
    .Font.Hidden = True    '……(**)'
    .Text = a_Text
    .Replacement.Text = ""
    .Wrap = wdFindStop
    .MatchFuzzy = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchByte = False
    .MatchAllWordForms = False
    .MatchSoundsLike = False
    .MatchWildcards = False
  End With
  Call Selection.Find.Execute
  If Not Selection.Find.Found Then GoTo ReturnObject
  Set ret = Selection.Range
ReturnObject:
  With Selection.Find
    .Format = False
    .Font.Hidden = False
    Call .ClearFormatting
    Call .Replacement.ClearFormatting
  End With
  Set getNextHiddenTextRange = ret
End Function

例によって異様にタテ長になってしまうのは、Findオブジェクトの宿命。

ポイントは、(*)(**)のところ。

Find.FormatプロパティをTrueにすることで、書式情報をも検索対象に入れることができる。

そうしておいた上で、Find.HiddenプロパティをTrueにする。

このようにすることで、隠し文字になっている文字列のみ、検索対象とすることができる。

これで、検索でヒットしたらその箇所のRangeが返るし、ヒットしなければNothinが返ることになる。

ただし、気をつけねばならんことが一つ。

ヒットした場合は、当該の箇所が選択された状態になっている、ということである。

任意の隠し文字のある箇所にカーソルを置くFunction

たとえば、隠し文字を表示した状態で、次のようになっている文書があるとする。

隠し文字を非表示にすると、

こうなる。

この状態で、「競輪用自転車」という見出しの先頭にカーソルを移動させたいのである。

スト2
Public Function SetCursorEndOfHiddenText( _
                ByVal a_HiddenText As String) As Boolean
  SetCursorEndOfHiddenText = False
  Dim tgtRng As Range
  Dim isHidden As Boolean '最初の表示・非表示を記録するフラグ'
  With Application.ActiveWindow.View
    If .ShowAll Then GoTo ExitHere1
    If Not .ShowHiddenText Then
      '隠し文字非表示の場合、一旦表示にして元の状態を覚えておく'
      .ShowHiddenText = True
      isHidden = True
    End If
  End With
ExitHere1:
  Set tgtRng = getNextHiddenTextRange(a_HiddenText)
  If tgtRng Is Nothing Then GoTo ExitHere2
  Call tgtRng.Select
  Call Selection.Collapse(wdCollapseEnd)    '……(*)'
  SetCursorEndOfHiddenText = True
ExitHere2:
  With Application.ActiveWindow.View
    If Not .ShowAll Then
      'もともと非表示だった場合は非表示に戻す'
      If isHidden Then .ShowHiddenText = False
    End If
  End With
End Function

隠し文字の表示設定を実行前の状態に戻す、という仕様にしたので、その分だけコードが長くなっているが、メインの処理は至って簡単。

隠し文字が非表示だったら表示させた上で、先のリスト1getNextHiddenTextRangeメソッドを用いて対象の隠し文字を検索し、ヒットしたら選択範囲を後方に潰して((*)のところ。)、隠し文字の表示設定を元に戻しているだけ。

選択範囲を後方に向けて潰すのは、このFunctionを繰り返して使うときのため。

同じ隠し文字を繰り返し検索するようなとき、選択範囲を前方に潰してしまったらどういうことが起こるか、容易に想像がつくであろう!

使ってみる

次のコードで実験。

リスト3
Private Sub test03()
  Call SetCursorEndOfHiddenText("@2")
End Sub

これだけ。

バッチリ。

おわりに

見出しのところにうまい具合に隠し文字を設定すれば、任意の見出しの配下を簡単に取得することができるようになりますよ。

参考

 

akashi-keirin.hatenablog.com

akashi-keirin.hatenablog.com