【連載】差し込み印刷のレコードごとにドキュメントを作成するマクロの解説(第3回)

第3回 MailMergeオブジェクトを使う

前回

akashi-keirin.hatenablog.com

ひととおり準備ができたので、いよいよマクロの作成に移ります。

マクロに盛り込むべき処理は次のとおりです。

  • 差し込みデータを1件文書に差し込んで、新しい文書を作る
  • 新しくできた文書を整える
  • コマンド ボタンを置いてある1ページ目は不要なので削除する
  • 名前を付けて保存する

これを、差し込みデータの件数分繰り返せば良い、ということです。

今回は、上記の処理のうち、まず

差し込みデータを1件文書に差し込んで、新しい文書を作る

処理を取り上げます。

目次

MailMergeオブジェクト

差し込み印刷機能を利用するには、WordのDocumentオブジェクトのMailMergeプロパティを叩いて、MailMergeオブジェクトを取得し、それを使います。

MailMergeオブジェクトとは何か

MailMergeオブジェクトは、Documentオブジェクト配下のオブジェクトです。

Documentオブジェクトにぶら下がっているオブジェクトなので、MailMergeプロパティを叩いてやることで取得することができます。

リスト1
Private Sub test01()
    Dim doc As Document
    Set doc = ThisDocument
    Dim mm AS MailMerge
    Set mm = doc.MailMerge 
End Sub

このようにしてやれば、変数mmMailMergeオブジェクトを突っ込むことができます。(上記マクロは、変数にオブジェクトを突っ込んでいるだけなので、実行しても何も起きません。)

では、このMailMergeオブジェクトとは何者なのか。

大胆にたとえて言います。

データ差し込みおじさん

です。

このおじさん(=MailMergeオブジェクト)は、Wordのドキュメントの中にいて、ドキュメントに差し込みデータ用のテーブルが接続されていたら、そのデータについて知っていて、データを差し込みフィールドに差し込むことができるおじさんです。

なんでMailMergeという名前なのか。

それは、たぶんもともとこの機能が、葉書や封書といった書簡(Mail)に宛名などの可変的なデータを結合させる(Merge)ための機能だったからなのでしょう。

現代人は「Mail」と聞くと即座に〝Eメール〟を思い浮かべてしまいがちですが、この場合の「Mail」は昔ながらの書簡のことだと考えると良いでしょう。

MailMergeDataSourceオブジェクト

そして、このおじさんが知っている差し込みデータ用のテーブル、すなわち文書に接続されているテーブルがMailMergeDataSourceオブジェクトです。

MailMergeDataSourceオブジェクトはおじさん、すなわちMailMergeオブジェクトにぶら下がっているオブジェクトです。

MailMergeDataSourceオブジェクトは、MailMergeオブジェクトのDataSourceプロパティを叩くことで取得することができます。

リスト2
Private Sub test01()
    Dim doc As Document
    Set doc = ThisDocument
    Dim mm AS MailMerge
    Set mm = doc.MailMerge
    ' MailMergeDataSourceオブジェクト取得
    Dim mds As MailMergeDataSource
    Set mds = mm.Datasource
    mds.ActiveRecord = 1
    Debug.Print mds.DataFields("Phrase")
End Sub

上記コードでは、

Dim mds As MailMergeDataSource
    Set mds = mm.Datasource

によって変数mdsMailMergeDataSourceオブジェクト、すなわち今回データソースとしたdata-source.xlsxの「src-data」シートに作成したテーブルを表すオブジェクトを突っ込んでいます。

差し込みデータ

そして、続く

mds.ActiveRecord = 1

によって、MailMergeDataSourceオブジェクトのActiveRecordプロパティに1を指定しています。

こうすることで、MailMergeDataSourceオブジェクトが、データソースの1つ目のレコード、今回の我らのデータ(笑)でいえば、

  • ID: 1
  • Phrase: ほかにすることはないのですか。

であるように振る舞います。

この状態でMailMergeDataSourceオブジェクトのDataFieldsプロパティを叩いてやると、現在アクティブなレコードの列の情報のコレクションオブジェクトであるDataFieldsコレクションオブジェクトを取得することができます。

mds.DataFields("Phrase")のように、コレクションオブジェクトのインデックスに列(カラム)名を渡してやれば、アクティブレコードの当該列(カラム)の値を取得することができます。

したがって、

Debug.Print mds.DataFields("Phrase")

このステートメントを実行すると、現在アクティブになっているレコードのPhrase列(カラム)の値、すなわち「ほかにすることはないのですか。」がイミディエイト・ウィンドウに出力される、ということになります。

イミディエイト ウィンドウに表示された

[MailMerge].Executeメソッド

データ差し込みおじさん、すなわちMailMergeオブジェクトが、差し込むべきレコードを指定するしくみは理解できたでしょうか。

では、いよいよおじさんが実際にデータを差し込んで、新しい文書を作るフェーズです。

おじさんに〝データ差し込み・新規文書作成〟という動作をさせる命令はExecuteメソッドです。

リスト3
Private Sub test02()
    Dim doc As Document
    Set doc = ThisDocument
    Dim mm As MailMerge
    Set mm = doc.MailMerge
    ' データを差し込んで新規文書を作成する
    mm.Destination = wdSendToNewDocument
    ' データがないとき差し込みデータだけの段落は表示しない
    mm.SuppressBlankLines = True
    Dim mds As MailMergeDataSource
    Set mds = mm.DataSource
    ' 差し込み対象レコードと範囲を指定
    mds.ActiveRecord = 1
    mds.FirstRecord = 1
    mds.LastRecord = 1
    ' 差し込み実行
    Call mm.Execute( _
        Pause:=True _
    )
End Sub

Executeメソッド実行の準備

おじさんに〝データ差し込み・新規文書作成〟という動作をさせる前に、どんなふうに実行するのかという方針を伝える必要があります。

このコードでは、まず

' データを差し込んで新規文書を作成する
mm.Destination = wdSendToNewDocument

変数mmに突っ込んだMailMergeオブジェクトのDestinationプロパティに、データ(笑)を差し込んでできた文書の出力先を指定しています。

今回の例では、wdSendToNewDocumentを指定しているので、データ(笑)を差し込んだ文書を新規文書として出力することになります。

次の

' データがないとき差し込みデータだけの段落は表示しない
mm.SuppressBlankLines = True

は、コメントに記したとおり、差し込みデータだけの段落がある場合に、差し込みデータがない場合は段落ごと表示しない、という設定をしています。

たとえば、

差し込みフィールドだけの段落

このように差し込みフィールドが設定されているときに、差し込みレコードのPhrase列(カラム)にデータがあれば

データがあるとき

このように表示されますが、Phrase列(カラム)にデータがないときは、

データがないとき

このように段落ごと削る、という設定です。

差し込みデータだけの段落について、差し込むレコードが差し込むべきデータがない(Blank)行(Line)であった場合に、その段落の表示を抑制する(Suppress)という設定です。

今回の例では、差し込みフィールドは「」の中、すなわち段落の一部なので、SuppressBlankLinesプロパティはTrueでもFalseでも結果はかわりませんが、多くの場合、空の段落を表示してもしかたがないはずなので、Trueにすることが多いと思います。

さて、データを差し込んだ文書をどうするかに関する設定は終わりました。

あとは、どのレコードを使うかに関する設定です。

' 差し込み対象レコードと範囲を指定
mds.ActiveRecord = 1
mds.FirstRecord = 1
mds.LastRecord = 1

この3行がその設定です。

MailMergeDataSourceオブジェクトのActiveRecordプロパティは、現在ドキュメントに差し込むレコードです。1を設定し、1番目のレコードを差し込む設定にしています。

FirstRecordLastRecordプロパティは、その名のとおり、どのレコードからどのレコードまで差し込むかという設定です。

1番目から1番目まで、すなわち全体として1番目のレコードのみ差し込む、という設定にしています。

これで準備が整いました。

Executeメソッドの実行

いよいよ実行です。

' 差し込み実行
Call mm.Execute( _
    Pause:=True _
)

名前付き引数PauseTrueを渡しています。

この引数Pauseは、コチラによると、

True for Microsoft Word pause and display a troubleshooting dialog box if a mail merge error is found. False to report errors in a new document.

とのことです。

Trueにしておくと、差し込み時にエラーが発生したときに一時停止(Pause)してダイアログボックスを表示する、とのことなのでTrueにしておきました。

今回は、比較的小規模なデータを差し込み、実行後すぐに処理が終わる想定なので、エラーが出たときは止まってくれた方がありがたいでしょう。

逆に、大量のレコードを処理するような場合は、いちいち止まられると困るので、Falseにすることもあるかもしれません。(どんな場面か、いまいち想像がつきませんが。)

いざ、実行

では、リスト3を実行します。

次のような処理を行うはずです。

  • データを差し込んだ新規文書を作成する、という設定にする
  • データがないときは、差し込みフィールドだけの段落は削除する、と言う設定にする
  • 1番目のレコードをアクティブにして、1番目のレコードだけを差し込む設定にする
  • エラーが出たらダイアログボックスを出す設定にして差し込みを実行する

新規文書の1ページ目

このように、文書が表示されます。

ウィンドウのタイトルが「定型書簡1」になっているところがポイントです。

まだ保存されていない文書が、アクティブな状態になって表示されている、ということです。

これは、

Executeメソッドによって作成された文書(Documentオブジェクト)をActiveDocumentでつかまえることができる

ことを意味します。

新規文書の2ページ目

新しくできた文書の2ページ目です。

ちゃんと1番目のレコードのPhraseカラムの値が差し込まれています。

おわりに

これで、1件分のレコードを差し込んで新規文書を作成することができるようになりました。

作成した文書は、ApplicationオブジェクトのActiveDocumentプロパティを叩けば捕まえることができるので、

  • 作成直後の文書に必要な加工を施す
  • 名前を付けて保存する
  • レコードの件数分ループする

ことによって、目的を果たすことができます。

関連記事

akashi-keirin.hatenablog.com

akashi-keirin.hatenablog.com

akashi-keirin.hatenablog.com

迷わず押せよ 押せばわかる