差込データソースとの接続をVBAで行う(2)
差込印刷のデータソースとの接続をVBAで行う
Openイベントで接続する
差込印刷機能というのは非常に便利なので、Wordスキルがど素人のレベルでも使っている人は非常に多いと思う。私もそのクチ。ただ、データソースとの接続回りが非常に素人には分かりづらくて、面倒な思いをしている人も多いと思う。
たとえば、差込印刷を設定したWordドキュメントとデータソースのExcelファイルが同じフォルダに入っているとき、フォルダごと移動したり、フォルダ名を変えたりするだけでデータソースと接続できなくなってしまう。
データソースのフルパスが変わってしまうんだから、当たり前なんだけれど、仕組みのよく分かっていない初心者なんかは、いきなり
こんなダイアログ出されてもなんのことやら分からなくて困る。
また、事情が分かっていたとしても、たかがフォルダごと移動したぐらいでいちいちフォルダ階層をたどってデータソースファイルを指定し直すのはメンドクサイ。
そこで、
このときに作成したマクロをドキュメントのOpenイベント発生時に実行するようにしたら良いと考えた。
とりあえず、
こんなふうに、差込印刷テストフォルダ内に、メイン文書.docmと差込データ.xlsxを準備する。
差込データ.xlsxには、
このように、「競輪場」シートにデータ(w)を準備しておく。
で、メイン文書.docmのThisDocumentモジュールに以下のコードを書く。
プロジェクトエクスプローラのThisDocumentをダブルクリックしたらコード・ウインドウが開くので、
ここでDocumentを選んで、
ここでOpenを選んだらPrivate Sub Document_Open()~End Subが自動で挿入される。
リスト1 ThisDocumentモジュール
Private Sub Document_Open() Call setMailMergeDataSource(ThisDocument, _ "差込データ.xlsx", _ "競輪場") End Sub
setMailMergeDataSourceに引数を3つ渡して実行しているだけ。
setMailMergeDataSourceというのは、自作のプロシージャで、このときにご紹介したやつです。
短いコードなので再掲しておく。
リスト2 標準モジュール
'差込データソースに指定する' Public Sub setMailMergeDataSource(ByVal objDoc As Document, _ ByVal objFileName As String, _ ByVal objSheetName As String) '///objDoc:差込対象文書' '///objFileName:データソースExcelファイルのファイル名(拡張子付き)' '///objSheetName:データソースのあるシート名' '///※差込対象文書とデータソースファイルが同じフォルダにあることが' '/// 前提。' On Error GoTo errorHandler Dim dataSourceFullName As String dataSourceFullName = objDoc.Path & "\" & objFileName '" With objDoc.MailMerge .OpenDataSource _ Name:=dataSourceFullName, _ SQLStatement:="SELECT * FROM `" & objSheetName & "$`" End With Exit Sub errorHandler: Debug.Print Err.Number Debug.Print Err.Description End Sub
これで、ドキュメントOpen時にsetMailMergeDataSourceが実行されるので、差込データ.xlsxがメイン文書.docmと同じフォルダ内にあって、シート名を変更でもしない限り、フォルダごとどこのディレクトリに持って行っても大丈夫、ということになる。
実行結果
フォルダごと別のディレクトリに移動してメイン文書.docmを開いてみる。
開いたときには既にデータソースにつながっている。快適。
ついでに
使用環境によっては、マクロ入りのファイルを開くときに毎回
が出る場合がある(ウチの職場では、マクロ入りファイルを開くときは毎回出てくる)。そんな場合、データソースをつなぎっぱなしにしていると、ファイルを開くたんびに
まずコイツがでてきて、[はい(Y)]をクリック。で、その後、
コイツが出てくるので「コンテンツの有効化」をクリック。
そうするとまた
コイツが出てくるので[はい(Y)]をクリック、とひと手間余分にかかってしまう。わづか一手といえど、毎回毎回となるとさすがにうっとうしい。
よって、ドキュメントをCloseするたびに接続を切ってしまおうと思った。
まずは、接続を切断するためのプロシージャを作る。
リスト3 標準モジュール
'差込データソースを切断する' Public Sub disconnectMailMergeDataSource(ByVal objDoc As Document) On Error GoTo errorHandler objDoc.MailMerge.DataSource.Close '……(1)' errorHandler: Set objDoc = Nothing End Sub
引数としてDocumentを受け取って処理する。
(1)の
objDoc.MailMerge.DataSource.Close
Document.MailMerge.DataSourceオブジェクトのCloseメソッドを使っているだけ。
んで、ThisDocumentモジュールに以下のコードを書く。
今度は
ココでCloseを選ぶ。
リスト4 ThisDocumentモジュール
Private Sub Document_Close() Call disconnectMailMergeDataSource(ThisDocument) End Sub
ほい。たったのコレだけ。
実にカンタンに差込印刷用セットを使えるようになる。
訂正と追記
上で、得意げにドキュメントをCloseするたびに接続を切ってしまおうと思ったでんでんうんぬん書いてますけど、
ハッキリ言って、無意味
だよね。なんぼドキュメントのClose時にデータソースとの接続を切っても、別に上書き保存するわけじゃないんだからさ。
てなわけで、コードを修正する。
リスト5 ThisDocumentモジュール
Private Sub Document_Open() If ThisDocument.MailMerge.DataSource.Name <> "" Then _ Call disconnectMailMergeDataSource(ThisDocument) Call setMailMergeDataSource(ThisDocument, _ "差込データ.xlsx", _ "競輪場") End Sub
Closeイベントに書いてもムダなので、データソースの切断と接続をOpenイベントにまとめたわけです。
まず、条件判定
If ThisDocument.MailMerge.DataSource.Name <> "" Then
ですが、差込データ未接続だったら、Document.MailMerge.DataSourceオブジェクトのNameプロパティが""なので、
ThisDocument.MailMerge.DataSource.Name <> ""
がTrueということは、何らかのデータソースが設定されているということになる。
で、そのときにDataSourceが存在しないファイルだったりすると、
こいつが出てきて大混乱してしまう。
だから、Document.MailMerge.DataSourceオブジェクトのNameプロパティに何らかの文字列が入っている場合には、
Call disconnectMailMergeDataSource(ThisDocument)
でデータソースを切断してしまう。
これで、晴れてこのDocumentはデータソース未接続状態になっているので、あとは
Call setMailMergeDataSource(ThisDocument, _ "差込データ.xlsx", _ "競輪場")
で同一フォルダ内にあるデータソースに接続しておしまい。
【追記ここまで】
さらに追記
実は、上記のOpenイベントで一旦切断する方法もダメですw
どうもOpenイベント発生前に差込データソースを探しに行っているっぽい。
コチラをどうぞ。
おわりに
もちろん、差込データのファイル名が変わったり、シート名を変更したりした場合にはコードを書き換えなければならず、それなりに面倒ではあるので、そこらへんが課題かな。