LoginSignup
0
1

WordのVBAを使って指定した文字列(集合)に蛍光マーカーをつける。その際、テキスト本体だけでなく図形オブジェクトで作成したテキストエリア内にも反映させる。

Last updated at Posted at 2024-02-20

1. はじめに

ワードで作成した文書に、ある特定の文字列(集合)に蛍光マーカーで着色したいと思ったことはないだろうか。たとえば作成していた資料の校正を行うために用語のゆらぎを調べたり、あるいは目次を作るために索引語をマーキングしたりと、用途はいろいろありそうだ(Fig.1参照)。

サンプル.JPG
Fig.1 蛍光マーキングの例 本文以外に2つのテキストエリア内もマーキングしている。

ネットでその方法を検索すると、あるにはあるのだが、それでやってみても本文だけはマーキングできるのだが、図形オブジェクトのテキストアリア内に打ち込んだ文章にはマーキングされないなどいろいろトラブルに出くわした経験はないだろうか。

テキストアリアも処理対象にしたいと検索キーワードに「ワード VBA テキストエリア 文字列 蛍光マーカー」など入力して検索するのだがなかなか的を射たコンテンツが見つからない。ChatGPTに尋ねても嘘ばかり教えられる。そういった経験はないだろうか。

そういった方々のために私が悪戦苦闘した解決方法を備忘録として書き留めることにした。

2. 概要

要点は Selection オブジェクトの Find メソッドで指定した文字列を検索し、Selection.Range.HighlightColorIndex に蛍光マーカーの色番号を設定するだけである。とはいえ、不慣れな人には何をしてよいのやらわからない。そこで、具体例を交えながら一つずつ説明していく。

2.1 Selection オブジェクト

Selectionオブジェクトは文字列をマーキングする際のターゲット(Word文書本体なのか図形オブジェクトのテキストエリアなのか)である。Selectメソッドでターゲットを選択して、あとはSelectionオブジェクトを使って検索文字列を Find し、見つかったら Find オブジェクトの Execute メソッドを見つかった数だけ繰り返して蛍光ペンの色を設定する(たとえば黄色の蛍光ペンなら Selection.Range.HighlightColorIndex = wdYellow)だけだ。
具体的な例を示そう。

コード1
        With Selection.Find
            Selection.Move wdStory
            .Text = buf
            .Replacement.Text = buf
            .Wrap = wdFindContinue
            Do While .Execute
                Selection.Range.HighlightColorIndex = wdYellow
            Loop
        End With

ここで、bufは蛍光マーキングしたい文字列である。
では、Selectionオブジェクトはいまどこをターゲットにしているのだろうか?本文だろうか?それとも図形オブジェクトのテキストエリアだろうか?
実はそのターゲットは意識して選択(Select)しなければならない。何も書かずに上記のコードを実行すると文書本体がターゲットになるみたいだ。通常は文書本体しかマーキングする必要性を感じないだろうからこれで片が付く。しかし、凝った文書を作成して図形オブジェクトのテキストエリアを多用して、重要な内容をその中に詰め込んだらどうなるだろう?上記のコードはテキストエリアの中までマーキングしてくれない。
そこで登場するのが Selectメソッドである。

2.2 Select オブジェクト

Selectオブジェクトはターゲットを選択する。たとえばWordの文書本体であれば

コード2
ActiveDocument.Range.Select

とすればよい。ここで、ActiveDocumentは現在アクティブになっている文書である。Word文書内のマクロであれば、今開いているWord文書それ自身だ。だが、普通こんなものは書かない。書かないでも文書に付属するマクロが実行する時点で現在開いている文書のドキュメント(本体)がSelectされているからだ。しかし、たまたま何か処理で別のオブジェクトがSelectされていたらどうなるだろう?コード1は一生懸命そのSelectされたオブジェクトにマーキングしようとすることだろう。だから、その場合の安全策として本文を対象としたい場合はいつでもコード1に先立ってコード2を書いておけばよい。

では、図形オブジェクトのテキストアリアをSelectするにはどうすればよいか。コード3がそれである。

コード3
    For Each shp In ActiveDocument.Shapes
        If shp.Type = msoTextBox Then
            shp.TextFrame.TextRange.Select
            Call [任意の蛍光マーキング処理]
        End If
    Next

ActiveDocument.Shapesは現在開いているWord文書のすべての図形オブジェクトを表すコレクションで、そこから一つずつShapeオブジェクトをshpに取り出してShapeオブジェクトのTextFrameオブジェクトの中にあるTextRangeオブジェクトをSelectメソッドで選択する。それがshp.TextFrame.TextRange.Selectである。ただし、コード3ではShapeオブジェクトのTypeプロパティで図形オブジェクトがテキストエリア(msoTextBox)であることを確認してからターゲットに選択している。やっていないのでわからないが、他のオブジェクト(たとえば矩形オブジェクト)でも、その中にテキスト領域があればこのコードでマーキングができるかもしれない。こうしてターゲットが選択(Select)できたら任意の蛍光マーキング処理を呼び出す。

3. WordマクロとExcelマクロ

さて、概要が分かったところで実際にコードを作っていこう。その際、考えなければならないのは、そのコードをどこに書くかである。どこに、というのはWordファイルそのものにか、それともVBAが利用できる他のファイル、たとえばExcelファイルにか、ということである。
もっとも簡単なのはWordファイルそのものに書くことである。これまで紹介したコードはすべてWordファイル本体に書くコードを想定していた。しかし、Word本体にコードを書くと様々な問題点が出てくる。まず最初に、これが一番問題となるが、ファイルの種類をWordファイル(.docxファイル)ではなくマクロ付きWordファイル(.docmファイル)に変換しなければならない。自分の自由にしてよいWordファイルならともかく、チーム内や公に共有(公開)するファイルだとまず無理である。
そこで、次善の策として、VBAが利用できるOffice関連ファイル、あるいはVBScriptを利用することが考えられる。ここでは最もVBAが利用しやすいExcelファイルを用いる例を紹介する。

3.1 Wordマクロ

Wordマクロを使う場合、前準備として2つの作業がある。一つ目は、前述したように、ファイルの種類をWordファイル(.docxファイル)からマクロ付きWordファイル(.docmファイル)に変換すること、二つ目はメニューに[開発]ボタンを表示することである。Word で [開発] タブを表示するにはこのサイトを参考に設定を行なえばよいだろう。
[開発]ボタンをクリック後、VIsualBasicエディタを開いて新規に標準モジュールを作成して次のコードを入力する。

コード4
Option Explicit

Sub 蛍光マーキング()
Dim strArray() As String

    strArray = Split("急性骨髄性白血病:白血病", ":")
    
    Call 本文蛍光マーキング(strArray)
    Call テキストエリア蛍光マーキング(strArray)
End Sub

Sub 本文蛍光マーキング(strArray() As String)
    ActiveDocument.Range.Select
    Call 選択蛍光マーキング(strArray)
End Sub

Sub テキストエリア蛍光マーキング(strArray() As String)
Dim shp As Shape
     
    For Each shp In ActiveDocument.Shapes
        If shp.Type = msoTextBox Then
            Debug.Print shp.Name
            'Debug.Print shp.TextFrame.TextRange.Text
            shp.TextFrame.TextRange.Select
            Call 選択蛍光マーキング(strArray)
    
        End If
    Next
    
End Sub

Sub 選択蛍光マーキング(strArray() As String)
Dim buf As Variant

    For Each buf In strArray
        With Selection.Find
            Selection.Move wdStory
            .Text = buf
            .Replacement.Text = buf
            .Wrap = wdFindContinue
            Do While .Execute
                Selection.Range.HighlightColorIndex = wdYellow
            Loop
        End With
    Next
    
End Sub

メイン関数はSub 蛍光マーキング()で、まず、マーキングする文字列配列strArrayを組み立てたのちに本文をマーキングするプロシージャ本文蛍光マーキング(strArray)を呼び出し、ついで図形オブジェクトのテキストアリアをマーキングするテキストエリア蛍光マーキング(strArray)を呼び出す。

本文蛍光マーキング(strArray)は、マーキング文字列配列strArrayを受け取り、ActiveDocument.Range.Selectで本文を選択(Select)したのちに共通「マーキング」ルーチン選択蛍光マーキング(strArray)を呼び出す。
テキストエリア蛍光マーキング(strArray() As String)はマーキング文字列配列strArrayを受け取り、ActiveDocument.Shapesから図形オブジェクトを一つずつ取り出して変数shpに格納し、それがテキストアリア(msoTextBox)であればshp.TextFrame.TextRange.Selectによってテキストアリアを選択(Select)し、共通「マーキング」ルーチン選択蛍光マーキング(strArray)を呼び出す。
共通「マーキング」ルーチン Sub 選択蛍光マーキング(strArray() As String) では受け取ったマーキング文字列配列 strArray から一つずつ文字列を取り出して変数 buf に格納し、それを Selection.Find メソッドで検索し、見つかったら Find````オブジェクトのExecuteメソッドで Selection.Range.HighlightColorIndex = wdYellow によって黄色(wdYellow```)にマーキングする。

3.2 Excelマクロ

Excelマクロを使う場合、前準備として3つの作業がある。最初の2つはWordマクロと同様にファイルの種類の変更(.xlsxファイルから.xlsmへ)と[開発]ボタンの表示で、残る一つは参照設定である。これは、Excel から Word オブジェクトを参照するための設定で、これをやっておくとコードのオートフィルが有効になり、効率的であると同時にミスタイプ防止や発見的コーディングが可能となって嬉しい。ネットで検索するプログラムの中には参照設定を行わず、何でもかんでも Object で宣言する例をよく見るが私は好きではない。さて、その参照設定だが、Visual Basic エディタ(略してVBエディタ)のメニュー画面から[ツール]→[参照設定]→[Microsoft Word 16.0 Object Library]にチェックを入れる。ただし、16.0 の部分はマシン依存なので適宜読み替えて欲しい。

さて、準備が整ったら、新規に標準モジュールを作成して次のコードを入力する。

コード5
Option Explicit

Sub 蛍光マーキング()
    Dim wdApp As Word.Application
    Dim wdDoc As Word.Document
    Dim strArray() As String

    ' Wordアプリケーションを開く
    Set wdApp = New Word.Application
    wdApp.Visible = False
    
    ' Word文書を開く
    Set wdDoc = wdApp.Documents.Open(ActiveWorkbook.path & "\サンプル.docm")
    
    ' 病名を":"で区切る
    strArray = Split("急性骨髄性白血病:白血病", ":")
    
    ' 蛍光マーキング
    Call 本文蛍光マーキング(wdApp, strArray)
    Call テキストエリア蛍光マーキング(wdApp, strArray)
    
    ' Word文書を保存して閉じる
    wdDoc.Save
    wdDoc.Close
    
    ' Wordアプリケーションを終了
    wdApp.Visible = True
    wdApp.Quit
    
End Sub

Sub 本文蛍光マーキング(wdApp As Word.Application, strArray() As String)
    wdApp.ActiveDocument.Range.Select
    Call 選択蛍光マーキング(wdApp, strArray)
    
End Sub

Sub テキストエリア蛍光マーキング(wdApp As Word.Application, strArray() As String)
Dim shp As Word.Shape
    
    For Each shp In wdApp.ActiveDocument.Shapes
        If shp.Type = msoTextBox Then
            Debug.Print shp.Name
            'Debug.Print shp.TextFrame.TextRange.Text
            shp.TextFrame.TextRange.Select
            Call 選択蛍光マーキング(wdApp, strArray)
        End If
    Next
    
End Sub

Sub 選択蛍光マーキング(wdApp As Word.Application, strArray() As String)
Dim buf As Variant

    For Each buf In strArray
        With wdApp.Selection.Find
            wdApp.Selection.Move wdStory
            .Text = buf
            .Replacement.Text = buf
            .Wrap = wdFindContinue
            Do While .Execute
                wdApp.Selection.Range.HighlightColorIndex = wdYellow
            Loop
        End With
    Next
    
End Sub

Word マクロとの違いに留意して説明する。もっとも大きな違いは、Excel で Word 文書を操作するには Word アプリケーションオブジェクト Word.Application を使う。 また、処理対象の Word ドキュメントをインスタンス化するために Word ドキュメントオブジェクト Word.Document を使う。両者はメイン関数 Sub 蛍光マーキング() で定義しインスタンス化する。コード5では、各々 wdAppwdDoc という名前で定義している。Word ドキュメントオブジェクト wdDoc は Word アプリケーションオブジェクト wdAppDocuments.Open メソッドを使ってインスタンス化する。引数には Word 文書ファイルを指定する。ActiveWorkbook.path は現在この Excel ファイルが格納されているパスが返されるので、Excel ファイルと同じフォルダに格納された Word 文書ファイル サンプル.docm が開かれる。

マーキングする文字列配列strArrayを組み立てたのちに本文をマーキングするプロシージャ本文蛍光マーキング(wdApp, strArray)を呼び出し、ついで図形オブジェクトのテキストアリアをマーキングするテキストエリア蛍光マーキング(wdApp, strArray)を呼び出すのは Word マクロの場合と同様である。違うのは、各々のプロシージャの第一引数に Word アプリケーションオブジェクト wdApp が引き渡されている点である。これはマーキング処理のターゲットを選択(Select)する際に必要となる。なぜなら、Word マクロでは対象とする Word 文書は ActiveDocument で参照できたが、Excel マクロではそれが wdApp.ActiveDocument となるからである。これを考慮して本文をマーキングするプロシージャ Sub 本文蛍光マーキング(wdApp As Word.Application, strArray() As String) とテキストアリアをマーキングするプロシージャ Sub テキストエリア蛍光マーキング(wdApp As Word.Application, strArray() As String) を修正する。

最後に、共通「マーキング」ルーチン Sub 選択蛍光マーキング(wdApp As Word.Application, strArray() As String) も Word アプリケーションオブジェクト wdApp を受け取る。これは Selection オブジェクトが Word のものだと明確に指定するためである(単に Selection とすると、それは Excel の Selection オブジェクトとみなされる)。

全ての蛍光マーキング処理が終了したら、Word 文書を保存して閉じてから Word アプリケーションを終了させる。

4. おわりに

作成したマクロを使って Word のサンプル文書に対して蛍光マーキングを行った結果が Fig.1 である。この文書には本文以外に2つのテキストエリアがあるが、指定した文字列(この場合は「急性骨髄性白血病」と「白血病」)が本文に対してもテキストエリアに対しても蛍光マーキングされているのがわかる。

今回紹介した蛍光マーキングに限らず、Word 文書に対して様々な処理を行う際に、いちいち Word 文書にマクロを書くのは運用面でも得策ではなく Excel ファイルを Word 文書のハンドラとして利用することが多いのではないか思う。その際のテンプレートとして今回紹介した Excel マクロが利用できるのではないかと思う。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1