次の方法で共有


Office Space: Microsoft Word 文書でテキストを検索、置換する

Office Space

Office Space へようこそ。Office Space は、Microsoft® Office アプリケーションのスクリプト作成に関するヒントとテクニックを紹介する新しいコラムです。毎週火曜日と木曜日に新しいヒントを掲載します。過去のヒントについては、「Office Space アーカイブ」を参照してください。Microsoft Office でのスクリプト作成について質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

Microsoft Word 文書のテキストを検索、置換する

変化は避けられないものです。しかし、それが常に面白いことばかりだとは限りません。たとえば、あなたが Contoso 社で働いているとします。ああ、それで思い出しました。Ken Myer という人物をご存知ですか。彼は Contoso 社で働いていたことがあるんですが。背が高くて、茶髪の男です。

まあともかく、あなたは Contoso 社で働いており、ある朝会社にやってくると、社名が Fabrikam に変わっていました (Fabrikam のようなすごくかっこいい名前に "変えたくない" という会社なんてありますかね)。ある問題を除けば、それでかまいません。あなたは莫大な Word 文書 (テンプレート、トレーニング資料、定型書簡) すべてにおいて、旧会社名である Contoso を使用しています。そこで、その文書をそれぞれ一読し、"Contoso" という社名をすべて "Fabrikam" に変更する必要があります。いいですか。

確かに、Microsoft Word のテキストを検索して置換することは、それほど難しいものではありません。私たちの多くは、[検索と置換] ダイアログ ボックスを熟知しています。

検索と置換

唯一の問題は、Word 文書をどれもこれも開いて手動で [検索と置換] ダイアログ ボックスを起動し、適切な基準を入力してから [すべて置換] をクリックしなければならないことです。文書が 2 つか 3 つであればそれほど問題ではありませんが、200 または 300 にもなると話が少し変わってきます。その仕事はいつまでたっても終わらないかもしれません。たとえば、Word 文書のテキストをプログラムで検索、置換する方法があるというオッズはどれくらいだと思いますか。

ケンタッキー ダービーでの大誤算のおかげで (セクレタリアトが今年のレースに参戦しなかったことはもちろん、彼が亡くなっていたことも誰も教えてくれませんでした)、Scripting Guys は今やギャンブルや他のすべての悪しき慣習に対して対立の姿勢をとっています。だから、オッズがどうかなんて知りません。しかし、Word 文書のテキストをプログラムで検索、置換することは非常に簡単であることは言えます。たとえば、"Contoso" という単語が文書 C:\Scripts\Test.doc で見つかるかどうかを示す単純で小さなスクリプトがあります。

Set objWord = CreateObject("Word.Application")
objWord.Visible = True

Set objDoc = objWord.Documents.Open("C:\Scripts\Test.doc")
Set objSelection = objWord.Selection

objSelection.Find.Text = "Contoso"
objSelection.Find.Forward = TRUE
objSelection.Find.MatchWholeWord = TRUE

If objSelection.Find.Execute Then
    Wscript.Echo "The search text was found."
Else
    Wscript.Echo "The search text was not found."
End If

ここでは何を行ったのでしょう。最初に Micorsoft Word のインスタンス (Word.Application オブジェクト) を作成してから、Visible プロパティを True に設定します。Visible プロパティを True に設定したのは、画面上で文書を見ることができるようにするためです。次に Open メソッドで文書 C:\Scripts\Test.doc を開き、その文書を開いた状態で、冒頭に Selection オブジェクトのインスタンスを作成します。

おもしろいのはここからです。Selection オブジェクトに子オブジェクト Find があることがわかります。名前が示すように、Find オブジェクトは文書内の検索に使用されます。今日は、テキストの検索を中心に話を進めていきますが、Find オブジェクトは、書式、スタイル、画像、特殊文字など、[検索と置換] ダイアログ ボックスを使用して検索可能なものを検索するためにも使用できます。凝った機能についてはまた別の機会に扱うとして、差し当たり、"Contoso" という単語を検索できるかどうか確認してみましょう。

Find オブジェクトの 3 つのプロパティを設定します。

  • Text: これは、単なる検索対象のテキストです。したがって、Text プロパティの値を "Contoso" に設定します。

  • Forward: これは検索方向です。文書の冒頭に Selection オブジェクトを作成したので、前に進みます (つまり、文書の最後に向かいます)。したがって、Forward プロパティの値を True に設定します。

  • MatchWholeWord: これは、単に "Contoso" という単語のみを照合するようにスクリプトに指示します。この場合、他の語に埋め込まれた "Contoso" という単語を検出する可能性が低くなります。ただし、"cat" という単語を "dog" に置き換えるとします。単語の完全一致がオフになっている場合は、文字 "c-a-t" のインスタンスを "dog" と置き換えます。つまり、"catalog" は "dogalog" に変更されます。このような奇妙なことを避けるために、MatchWholeWord を True に設定します。

: Find オブジェクトの設定可能なプロパティは、これだけではありません。完全な一覧については、MSDN の 「Microsoft Word VBA Language Reference」(英語) を参照してください。

Find オブジェクトのプロパティを設定した後で、Execute メソッドを呼び出して文書を検索します。Execute メソッドでは、検索文字列が見つかった場合は True、見つからなかった場合は False が返されます。Execute メソッドが返した値を確認し、適切なメッセージを返します。その処理は次のコード部分で行われます。

If objSelection.Find.Execute Then
    Wscript.Echo "The search text was found."
Else
    Wscript.Echo "The search text was not found."
End If

確かに、これはこれでいいでしょう。このスクリプトによって、"Contoso" という単語が Test.doc のどこかで見つかったことがわかります。しかし正直に言うと、この情報はそれほど重要ではありません。文書に "Contoso" という単語が含まれていなければ、それはどうでもいいことです。"Contoso" が含まれて "いれば"、"Fabrikam" に置換したいのです。検索と置換スクリプトの置換部分を、私たちはどのように処理すればよいでしょう。

実際は次のように行います。

Const wdReplaceAll  = 2

Set objWord = CreateObject("Word.Application")
objWord.Visible = True

Set objDoc = objWord.Documents.Open("C:\Scripts\Test.doc")
Set objSelection = objWord.Selection

objSelection.Find.Text = "Contoso"
objSelection.Find.Forward = TRUE
objSelection.Find.MatchWholeWord = TRUE

objSelection.Find.Replacement.Text = "Fabrikam"
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll

お分かりのように、このスクリプトの大部分は、すでにお見せした最初のスクリプトと非常によく似ています。最初に新しく行が追加されています。まず 定数 wdReplaceAll を定義し、値を 2 に設定します。この定数は後で使用し、"Contoso" という単語のすべてのインスタンスを自動的に置換するようにスクリプトに指示します。続いて Word 文書を開き、Find オブジェクトのプロパティを設定します。このとき、"Contoso" という単語を文書内で見つけることができたかどうかを報告するだけのスクリプトで使用したコードと全く同じコードを使用します。

ここだけが、我々のスクリプトと異なります。"Contoso" の既存インスタンスを実際に置換するため、Replacement オブジェクト (Find オブジェクトの子オブジェクト) のプロパティのいくつかを設定する必要があります。行いたいのは単語と単語の単純な置換だけなので、設定する必要のある唯一のプロパティは Text プロパティです。Text プロパティは、単なる置換テキストです。"Fabrikam" を置換テキストとして使用すると、Text プロパティを設定するコードは次のようになります。

objSelection.Find.Replacement.Text = "Fabrikam"

続いて、Execute メソッドを呼び出します。しかし、今回はコードが少し奇妙に見えることを認めなければなりません。

objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll

コンマの連続は何を意味するのでしょうか。Execute メソッドには多くのオプションのパラメータがあります (完全な一覧については、「Word VBA Language Reference」(英語) を参照してください。最初のスクリプト (単にテキストを検索するもの) では、オプションのパラメータは必要ありませんでした。したがって、パラメータなしで Execute メソッドを呼び出しました。しかしテキストを置換するには、"Contoso" という単語のすべてのインスタンスを自動的に置換することを示す必要があります。これが、パラメータ一覧にある定数 wdReplaceAll を参照する理由です。

しかし、コンマの連続はどうでしょう。"Contoso" のすべてのインスタンスを置換することを示すためには、定数 wdReplaceAll がパラメータ一覧の 11 番目の項目である必要があります。つまり、定数 wdReplaceAll の前に他の 10 パラメータがなければなりません。これらのパラメータのいずれも設定しませんが、その存在は示す必要があります。したがって、コンマで区切られた空白のパラメータを使用します。ばかげたことに見えますが、これがうまく機能します。スクリプトを実行してください。"Contoso" のすべてのインスタンスが、"Fabrikam" に置換されます。

変化が良いのか悪いのかまだわかりません。しかし、これらの変更が簡単であれば、気にする人などいないでしょう。スクリプトを使用すれば、Word 文書のテキストの置換が非常に素早く簡単になるので、他の仕事を進めるのに十分な時間が残されることになります (このことは言いふらさないでくださいね。次回の競馬 "プリークネス" に出走する名馬マンノウォーのとびきり情報を持ってるんですがね)。