Word VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


52 / 308 ツリー ←次へ | 前へ→

【715】文字検索 ゆい 12/1/15(日) 18:04 質問[未読]
【716】Re:文字検索 H. C. Shinopy 12/1/15(日) 22:42 回答[未読]
【717】Re:文字検索 ゆい 12/1/16(月) 16:14 お礼[未読]
【743】Re:文字検索 マナ 13/5/1(水) 14:08 質問[未読]
【753】Re:文字検索 マナ 13/5/5(日) 10:55 発言[未読]

【715】文字検索
質問  ゆい  - 12/1/15(日) 18:04 -

引用なし
パスワード
   こんにちは
Word-VBA超初心者です。(Excel-VBAはそれなりに...)

Findを用いた文字検索において、位置情報を取得することは出来ますか?
  
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "■"
        .Replacement.Text = "■"
        .Wrap = wdFindStop
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
    
    位置 = Selection.Start

このような感じで、「位置」に位置情報を格納したいのですが、なぜだか、格納される時と格納されない(1が入っている)時があります....

どなたか、正しい方法をお教え頂けないでしょうか?

また、Findを用いる際、選択範囲(マウスでドラッグして黒く反転させた範囲)のみ実行させる方法はござますか?今組んでいるマクロでは、選択範囲は無視されて、ドキュメントの最後まで検索してしまいます。

宜しくお願いいたします。

【716】Re:文字検索
回答  H. C. Shinopy  - 12/1/15(日) 22:42 -

引用なし
パスワード
   残念ながら簡単には行かないようです。
選択範囲の文字の位置を取り込んで、
Ifステートメントで範囲内かどうか判断しながら処理する方法はありますが、
どうしても範囲外の文字列を検索してしまいますし、
Ifステートメントが悪さをするのか下記の「二重検索」マクロより処理時間が長くなります。

私の場合は、まず正規表現で検索して、
再びFindで検索してカーソルを移動させ書き換えする方法でやっています。
(正規表現のメタキャラクタ(\|()[]{}^$*+?.など)に該当する文字列を検索する場合は、
その前に「\」を付ける必要があるので注意!)

下記のマクロは選択した範囲内の文字列で、
例えば「cx」(あるいは「c^」)・「a_」を検索して、
各々「^」の付いたc、「^」の付いたaに置換する処理です。

また、位置については下記マクロの
Dim myRangeStart As Word.Range

Set myRangeStart = Selection.Range ' 検索開始点を取得する。

myRangeStart.Select ' 検索開始点に戻る。
を見て下さい。
以下、マクロ。

Sub MyFindReplace()
 Rem *----*----*  *----*----*  *----*----*  *----*----*
 Rem 選択範囲内 文字列検索置換処理
 Rem 作譜:Hitrock Camellia Shinopy
 Rem 言語:Word VBA
 Rem 機能...
 Rem  1. 選択した範囲内で、指定した文字列を検索し置換する。
 Rem 注記...
 Rem  1. 正規表現で検索した文字列を再度Selection.Findプロパティで検索。
 Rem  2.
 Rem 履歴...
 Rem  第01版:2010/09/30:作成。
 Rem *----*----*  *----*----*  *----*----*  *----*----*
 Dim myRegExp As Object ' VBScript_RegExp_55.RegExp
 Dim myMatches As Object ' MatchCollection
 Dim myMatch As Object ' Match
 Dim myTextReplace As String
 '
 Dim myRangeStart As Word.Range
 '
 Dim i As Long
 Dim c As Long
 Dim myStatusBar As String
 Rem *----*----*  *----*----*  *----*----*  *----*----*
 '
 If Len(Selection.Range.Text) <= 0 Then
  Rem 範囲を指定しなかった場合は、カーソルより後で文書の末尾まで選択する。
  Selection.EndKey Unit:=wdStory, Extend:=wdExtend
 End If
 '
 Set myRegExp = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp
 Rem *----*----*  *----*----*  *----*----*  *----*----*
 '
MyFindReplaceSubEntry:
 With myRegExp
  .Pattern = "[cghjsu][x\^]|[aeiou]_" ' パターンを設定
  .IgnoreCase = False ' 大文字と小文字を区別する
  .Global = True ' 文字列全体を検索
  '
  If .Test(Selection.Range.Text) = False Then
   MsgBox "該当する文字列がありません。"
   Selection.Collapse wdCollapseStart
   GoTo MyFindReplaceSubExit
  End If
  '
  i = 0
  Set myMatches = .Execute(Selection.Range.Text)
  Selection.Collapse wdCollapseStart
  Set myRangeStart = Selection.Range ' 検索開始点を取得する。
  '
  For Each myMatch In myMatches
   With Selection.Find
    .Text = myMatch.Value
    .Execute
   End With
   '
   Select Case myMatch.Value
    Case "cx": myTextReplace = ChrW(265)
    Case "c^": myTextReplace = ChrW(265)
    Case "a_": myTextReplace = ChrW(226)
   End Select
   '
   Selection.TypeText myTextReplace ' 置き換え。
   '
   i = i + 1
   c = i * 100 \ myMatches.Count
   myStatusBar = Format(c, "##0") & "% " & i & "/" & myMatches.Count & "件"
   Application.StatusBar = "MyFindReplace" & ":処理中" & " " & myStatusBar
   DoEvents
  Next ' myMatch
 End With
 '
 myRangeStart.Select ' 検索開始点に戻る。
 Rem *----*----*  *----*----*  *----*----*  *----*----*
 '
MyFindReplaceSubExit:
 Set myRegExp = Nothing
 Set myMatches = Nothing
 Set myRangeStart = Nothing
 Application.StatusBar = "MyFindReplace" & ":" & "処理完了!"
End Sub ' MyFindReplace *----*----*  *----*----*  *----*----*  *----*----*

[End]

【717】Re:文字検索
お礼  ゆい  - 12/1/16(月) 16:14 -

引用なし
パスワード
   アドバイス頂いた内容をきちんと理解できていませんが、
何とか希望通りの動作をするマクロにすることが出来ました!
ありがとうござました。

アドバイス頂いたマクロの内容の勉強をこれから行います!

【743】Re:文字検索
質問  マナ  - 13/5/1(水) 14:08 -

引用なし
パスワード
   ▼ゆい さん:
>アドバイス頂いた内容をきちんと理解できていませんが、
>何とか希望通りの動作をするマクロにすることが出来ました!
>ありがとうござました。
>
>アドバイス頂いたマクロの内容の勉強をこれから行います!

私も勉強中でまだまだわかっておりません。どなたか教えて下さい。
解決済みなうえに、1年以上も前なのですが、ここで便乗質問してもよいでしょうか。

ゆいさんの質問の
>今組んでいるマクロでは、選択範囲は無視されて、ドキュメントの最後まで検索してしまいます。

ですが、私の環境では、ゆいさんが最初に提示されたマクロで、
選択範囲のみの検索になっているみたいです。

> .Wrap = wdFindStop
これでは駄目なのでしょうか?

それとも私は何か勘違いしてるのかしら。

【753】Re:文字検索
発言  マナ  - 13/5/5(日) 10:55 -

引用なし
パスワード
   >>今組んでいるマクロでは、選択範囲は無視されて、ドキュメントの最後まで検索してしまいます。
>
>ですが、私の環境では、ゆいさんが最初に提示されたマクロで、
>選択範囲のみの検索になっているみたいです。

>それとも私は何か勘違いしてるのかしら。

もしかするとわかったような気がします。

ht tp://www.ka-net.org/blog/?p=1199
リンク先のように、検索を繰り返す場合の問題なのかもしれませんね。
確かに、マクロを使う場合は、単純な検索・置換でなく、
検索しながら、何らかの処理を繰り返し、
といった場合のほうが、多いと思いますので。

つまり、ゆいさんの提示されたコードは、
もう一つのほうの位置取得の質問のためのものだったと。

以前書いた検索を使ったコードを探してみました。
全然覚えていませんでしたが、
自分ではこんな感じにしていたものがありました。

Set myRng = Selection.Range

With myRng.Find
  .Text = "■■"          
  Do While .Execute
    If myRng.End > Selection.End Then Exit Do
    'ここで処理実行
   Loop
End With

でも今試してみたら、リンク先のInRange(知りませんでした)を使った方法と同じで、検索範囲と検索語が同じだった場合は、期待通りになりませんでした。
それがわかったことと、InRangeの存在を知ったのは収穫です。

H. C. Shinopyさんの
>Ifステートメントで範囲内かどうか判断しながら処理する方法はありますが、

これは、InRangeを使う方法のことだったのかも知れませんね。

というわけで、私の便乗質問については、何とか納得(解決)です。

52 / 308 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
207161
(SS)C-BOARD v3.8 is Free