指定した文字列に挟まれた箇所を取得する(Word)
補足 指定した文字列に挟まれた箇所を取得する
の補足。
ワイルドカードを用いたらもっと簡単にできるので、書いておきます。
目次
こんなことができます
たとえば、
「《》」で括られた箇所を取得したい!
というときに、引数に「《
」と「》
」を指定してやると、後方にある直近の当該箇所を指し示すRange
オブジェクトを取得することができます。
考え方
Find
オブジェクトのText
プロパティに、ワイルドカードを用いて文字列を指定する。
それだけ。たったそれだけ。
たとえば、〝「《》
」で括られた箇所〟が必要なら、Text
プロパティを、
With Selection.Find .Text = "《" & "*" & "》" ' 以下省略' : : End With
とすればよい。
指定した文字列に挟まれた箇所を取得するFunction
さっさとコードを書いてしまおう。
リスト1 標準モジュールFormatStrings
Public Function GetSandwichedRange( _ ByVal StartChar As String, _ ByVal EndChar As String) As Range Dim ret As Range Set ret = Nothing With Selection.Find .Text = StartChar & "*" & EndChar .Replacement.Text = "" .Wrap = wdFindStop .Format = False .Highlight = False .MatchCase = False .MatchWholeWord = False .MatchByte = False .MatchAllWordForms = False .MatchPhrase = False .MatchSoundsLike = False .MatchFuzzy = False '……(*)' .MatchWildcards = True End With Call Selection.Find.Execute If Not Selection.Find.Found Then GoTo ReturnObject Set ret = Selection.Range ReturnObject: Set GetSandwichedRange = ret End Function
気をつけないといけないのは、(*)のところ。
今回は、ワイルドカードを有効にするためにMatchWildcards
プロパティをTrue
に設定したいのだが、だからといって、たとえば
.MatchWildcards = True .MatchFuzzy = False
という順でコードを書くと、
という実行時エラーに見舞われるのである。
これは、先のエラーメッセージに挙げられている「MatchPhrase
」、「MatchWildcards
」、「MatchSoundsLike
」、「MatchAllWordForms
」、「MatchFuzzy
」の各プロパティのうち、唯一「MatchFuzzy
」プロパティのみが、初期値True
であるという事情による。
つまり、MatchFuzzy
をFalse
にする前に、「MatchPhrase
」、「MatchWildcards
」、「MatchSoundsLike
」、「MatchAllWordForms
」のうちどれか一つでもTrue
にすると、
「MatchPhrase、MatchWildcards、MatchSoundsLike、MatchAllWordForms、MatchFuzzyパラメータ」を「同時に True に設定」した呼ばわり
されることになるのである!
まさに、天に二日なし!!!!!!!!
たぶん、多くの人は、Find
オブジェクトを利用するコードなんてコピッペして使い回しているはずなので(ですよね?)、初めから「.MatchFuzzy
」はMatch
一族の中で一番上に置いておくのが良いかもしれない。
おっと、話がそれた。
このGetSandwichedRange
メソッドを用いれば、
たとえば、
この状態で、次のコードをイミディエイトで実行すると、
?GetSandwichedRange("《", "》").Text
こうなる。意図どおりの結果。
指定した文字列に挟まれた箇所を置換するメソッドはこんなに短くなります
前回のリスト2のコードは、次のように劇的に(?)短くなる。
リスト2 標準モジュールFormatStrings
Public Function ReplaceSpecifiedRange( _ ByVal StartChar As String, _ ByVal EndChar As String, _ Optional ByVal ReplaceText As String = "") As Boolean ReplaceSpecifiedRange = False Dim tgtRange As Range Set tgtRange = GetSandwichedRange(StartChar, EndChar) If tgtRange Is Nothing Then Exit Function tgtRange.Text = ReplaceText ReplaceSpecifiedRange = True End Function
おわりに
ただ、なんとなく今回の方式の方が遅い気がする。
ちょいと測ってみたら、
やっぱり少しだけ遅い。(何度も実験したわけではないので、毎回こうなるかどうなのかは不明。)
うーん……。何なのだろう。