水野麻子さんの記事「テキストボックス内の文字を置換する 」に関連したマクロです。
私は、検索や置換をすべてマクロで実行していたため、下記のように今朝まで誤解しておりました。正しくは、青文字で追記した通りです。
通常の検索と置換では、テキストボックス内の文字は置換対象になっておりません。
検索と置換ダイアログボックスでの通常の検索や置換では、表示されている文書の文字列が検索と置換の対象になっています。
ところが、Selectoinオブジェクトを使ってマクロで検索や置換をする場合には、検索と置換の対象を正確に選択していかないと、もれが出てしまう場合があることに今朝気がつきました。
そのことを知らずに、テキストボックスの置換ができないと思い込んで半ばあきらめムードで仕事をしておりました。
実は、私は、最近の翻訳案件でテキストボックスが百個以上もある案件があったのですが、このテキストボックス内の文字列をマクロで置換できないことに気づき、非常にショックを受けていたのです。
そこで、水野さんに相談したところ(上記記事中のセミナー後にご一緒させていただいたのは私です(笑))、上記のような記事を書いていただきました。
検索・置換ダイアログボックスでは、検索する対象をテキストボックスに指定する方法があったのです。勉強不足、試行錯誤不足でした。
この記事をヒントにして、テキストボックスのみを置換対象とする処理をマクロ化してみました。
<目次>
このマクロでできること
表示されている文書中のテキストボックス、図形、吹き出しなどShapeオブジェクト内の「あいうえお」を「かきくけこ」に置換します。
検索条件はすべてオフにしてあります。
マクロの解説
文書中のすべてのShapeオブジェクトに対して、ひとつひとつ一括置換を実行しています。
For...Next ステートメントにて実行しています。
ActiveDocument.Shapes.Countにて、文書中のShapeオブジェクトの数を数えて、1つずつループを回しています。
テキストが含まれない図(イメージ)の場合には、置換処理はそのまま無視されて次のShapeに対して置換が実行されます。
「検索する文字列」と「置換後の文字列」にお好きな文字を入力して試してみてください。
もっと詳しく
検索と置換の対象を指定するSelectionオブジェクトは、選択されているオブジェクト(またはカーソルが位置する部分)を処理対象にします。
例えば、カーソルが文書に置かれている場合には、文書中でカーソルをキーボードの矢印キーで移動できる範囲が処理対象になっています。
または、カーソルがテキストボックスに置かれている場合には、そのテキストボックス1つが処理対象になります。つまり、キーボードの矢印キーでカーソルが移動できる範囲内に、処理対象が限定されているということですね。
となりのテキストボックスへは、キーボードの矢印キーでカーソルを移動することができませんので、となりのテキストボックスは範囲外というわけです。
これが、検索と置換のときに使われるSelectionオブジェクトの処理範囲の考え方みたいです。
今までよく理解しておりませんでした。
というわけで、マクロでSelectionオブジェクトを用いて文字列の検索と置換をする場合には、文書中に文字列が書かれていると思われるオブジェクトをすべて個別に選択する必要があるわけですね。
つまり、テキストボックスなどのShapeオブジェクトは、「選択をしない限り」は、検索と置換の対象にならないというわけなんですね。
ちなみに、コメント文もCommentオブジェクトとして選択しないと、検索と置換の対象外となってしまいます。
奥深いですねぇ。
追記 16-07-17 上記は、Wordのストーリー(Story)に関する処理対象の違いです。 Word VBAでは、Storyを適切に扱う必要があります。 そうしないと、すべての文字列の検索や置換ができません。 また、テキストボックスはグループ化されていることもあるので、その処理も必要です。 けっこう面倒です(笑)。
マクロ
Sub Shapeに対して置換を実行するマクロ() Dim i As Integer 'Shapeオブジェクトに対して置換実行 For i = 1 To ActiveDocument.Shapes.Count ActiveDocument.Shapes(i).Select Selection.Find.ClearFormatting Selection.Find.Replacement.ClearFormatting With Selection.Find .Text = "あいうえお" '検索する文字列 .Replacement.Text = "かきくけこ" '置換後の文字列 .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchByte = False .MatchAllWordForms = False .MatchSoundsLike = False .MatchWildcards = False .MatchFuzzy = False End With Selection.Find.Execute Replace:=wdReplaceAll Next i End Sub
関連記事