第3回 MailMergeオブジェクトを使う
前回
ひととおり準備ができたので、いよいよマクロの作成に移ります。
マクロに盛り込むべき処理は次のとおりです。
- 差し込みデータを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
このようにしてやれば、変数mm
にMailMerge
オブジェクトを突っ込むことができます。(上記マクロは、変数にオブジェクトを突っ込んでいるだけなので、実行しても何も起きません。)
では、この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
によって変数mds
にMailMergeDataSource
オブジェクト、すなわち今回データソースとした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
番目のレコードを差し込む設定にしています。
FirstRecord
とLastRecord
プロパティは、その名のとおり、どのレコードからどのレコードまで差し込むかという設定です。
1
番目から1
番目まで、すなわち全体として1
番目のレコードのみ差し込む、という設定にしています。
これで準備が整いました。
Executeメソッドの実行
いよいよ実行です。
' 差し込み実行
Call mm.Execute( _
Pause:=True _
)
名前付き引数Pause
にTrue
を渡しています。
この引数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」になっているところがポイントです。
まだ保存されていない文書が、アクティブな状態になって表示されている、ということです。
これは、
Execute
メソッドによって作成された文書(Document
オブジェクト)をActiveDocument
でつかまえることができる
ことを意味します。
新しくできた文書の2ページ目です。
ちゃんと1番目のレコードのPhrase
カラムの値が差し込まれています。
おわりに
これで、1件分のレコードを差し込んで新規文書を作成することができるようになりました。
作成した文書は、Application
オブジェクトのActiveDocument
プロパティを叩けば捕まえることができるので、
- 作成直後の文書に必要な加工を施す
- 名前を付けて保存する
- レコードの件数分ループする
ことによって、目的を果たすことができます。