差込データソースとの接続をVBAで行う(2)

差込印刷のデータソースとの接続をVBAで行う

Openイベントで接続する

差込印刷機能というのは非常に便利なので、Wordスキルがど素人のレベルでも使っている人は非常に多いと思う。私もそのクチ。ただ、データソースとの接続回りが非常に素人には分かりづらくて、面倒な思いをしている人も多いと思う。

たとえば、差込印刷を設定したWordドキュメントとデータソースのExcelファイルが同じフォルダに入っているとき、フォルダごと移動したり、フォルダ名を変えたりするだけでデータソースと接続できなくなってしまう。

データソースのフルパスが変わってしまうんだから、当たり前なんだけれど、仕組みのよく分かっていない初心者なんかは、いきなり

f:id:akashi_keirin:20171202180921j:plain

こんなダイアログ出されてもなんのことやら分からなくて困る。

また、事情が分かっていたとしても、たかがフォルダごと移動したぐらいでいちいちフォルダ階層をたどってデータソースファイルを指定し直すのはメンドクサイ。

そこで、

akashi-keirin.hatenablog.com

このときに作成したマクロをドキュメントのOpenイベント発生時に実行するようにしたら良いと考えた。

とりあえず、

f:id:akashi_keirin:20171202181702j:plain

こんなふうに、差込印刷テストフォルダ内に、メイン文書.docm差込データ.xlsxを準備する。

差込データ.xlsxには、

f:id:akashi_keirin:20171202180945j:plain

このように、「競輪場」シートにデータ(w)を準備しておく。

で、メイン文書.docmのThisDocumentモジュールに以下のコードを書く。

プロジェクトエクスプローラのThisDocumentをダブルクリックしたらコード・ウインドウが開くので、

f:id:akashi_keirin:20171202180955j:plain

ここでDocumentを選んで、

f:id:akashi_keirin:20171202181003j:plain

ここで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を開いてみる。

f:id:akashi_keirin:20171202182153j:plain

開いたときには既にデータソースにつながっている。快適。

ついでに

使用環境によっては、マクロ入りのファイルを開くときに毎回

f:id:akashi_keirin:20171202181025j:plain

が出る場合がある(ウチの職場では、マクロ入りファイルを開くときは毎回出てくる)。そんな場合、データソースをつなぎっぱなしにしていると、ファイルを開くたんびに

f:id:akashi_keirin:20171202181052j:plain

まずコイツがでてきて、[はい(Y)]をクリック。で、その後、

f:id:akashi_keirin:20171202181025j:plain

コイツが出てくるので「コンテンツの有効化」をクリック。

そうするとまた

f:id:akashi_keirin:20171202181052j:plain

コイツが出てくるので[はい(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モジュールに以下のコードを書く。

今度は

f:id:akashi_keirin:20171202181242j:plain

ココで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が存在しないファイルだったりすると、

f:id:akashi_keirin:20171202180921j:plain

こいつが出てきて大混乱してしまう。

だから、Document.MailMerge.DataSourceオブジェクトのNameプロパティに何らかの文字列が入っている場合には、

Call disconnectMailMergeDataSource(ThisDocument)

でデータソースを切断してしまう。

これで、晴れてこのDocumentはデータソース未接続状態になっているので、あとは

Call setMailMergeDataSource(ThisDocument, _
                              "差込データ.xlsx", _
                              "競輪場")

で同一フォルダ内にあるデータソースに接続しておしまい。

【追記ここまで】

おわりに

もちろん、差込データのファイル名が変わったり、シート名を変更したりした場合にはコードを書き換えなければならず、それなりに面倒ではあるので、そこらへんが課題かな。

@akashi_keirin on Twitter