Oracleのデータを直接Wordに差し込み印刷
以前、Wordの差し込み印刷をVBAで制御するで、Wordの差込印刷をする時にはDBへの接続方法がOLEDB、ODBC、DDEの3種類あることを書きました。この記事では、ODBCを使って、Oracleから直接Wordに差し込み印刷する方法を示します。
参考資料は、例によって
Visual Basic で Word の差し込み印刷を自動化する方法
です。
このドキュメントの中で、ODBCを使用する方法として以下のように説明されています。
システム上でユーザー データ ソース名 (DSN) が既に設定されているデータの差し込み印刷を行う場合は、ODBC を使用してそのデータにアクセスすることができます。OpenDataSource のデータ アクセス方法として ODBC を指定するには、Name 引数に空の文字列を、Connection 引数に ODBC 接続文字列を、また SubType 引数に wdMergeSubTypeWord2000 を入力します。
例
<MailMergeObject>.OpenDataSource Name:= "", _ Connection:= "DSN=MySQLServerDSN;DATABASE=pubs;uid=sa;pwd=;", _ SQLStatement:= "Select au_id, au_lname, au_fname from authors", _ SubType:= wdMergeSubTypeWord2000
動作確認環境
WindowsXP
Microsoft Word 2002 SP3
接続先のOracleに対してデータソース名(DSN)が以下のように設定されています。
DSNの種類:ファイルDSN
ファイル名:C:\Program Files\Common Files\ODBC\Data Sources\myDB.dsn
Oracleに接続するために必要な情報は以下のとおり。
サーバー:myDB
ユーザー名:myDBA
パスワード:myDB
実行するWordのファイル名:連絡文.doc
サンプルスクリプト
差し込み印刷するWordファイル(連絡文.doc)の標準モジュールに、このサンプルプロシージャを記述します。
実行すると、「BANGO」と「SYUBETU」の2つのフィールドを差し込み印刷で使用できるようになりました。もちろん、実際に使うテーブルの定義に従って、SQLは書き替えて下さいね。
Sub MailMerge_ODBC_Oracle() Dim objDoc As Word.Document Dim strDocFileName As String Dim strNendo As Long strDocFileName = "連絡文.doc" 'Wordファイル名を設定 'For Oracle Dim mySQL As String mySQL = "SELECT KIHONHYO.BANGO" mySQL = mySQL & " , CASE WHEN KIHONHYO.SYUBETU='1' THEN '○' ELSE NULL END AS SYUBETU" mySQL = mySQL & " FROM KIHONHYO" mySQL = mySQL & " WHERE KIHONHYO.NENDO='2012' AND KIHONHYO.SYUBETU<'3'" Set objDoc = Documents(strDocFileName) With objDoc.MailMerge 'NameオプションにDNSファイルのフルパスを設定しないと、エラー .OpenDataSource Name:="C:\Program Files\Common Files\ODBC\Data Sources\myDB.dsn", _ Connection:="FileDSN=myDB;uid=myDBA;pwd=myDB", _ SqlStatement:=mySQL, _ SubType:=wdMergeSubTypeWord2000 .ViewMailMergeFieldCodes = False 'この文書がメイン文書でないときはエラーになる。 End With Set objDoc = Nothing End Sub
JetSQLでは使えないCASE式も、ちゃんと使えました。
注意点をいくつか
DSNの種類について
今回の環境では、ファイルDSNを作成してあるので、コネクション引数は
Connection:="FileDSN=myDB;uid=myDBA;pwd=myDB"
と記述しましたが、ユーザーDSNやシステムDSNならば、
Connection:="DSN=myDB;uid=myDBA;pwd=myDB"
で良いはずです。
OpenDataSourceメソッドのName引数について
Microsoftの説明と例では、「Name 引数に空の文字列を」設定していますが、私の環境では実行時エラーになります。
「実行時エラー’4198′ コマンドは正常終了できませんでした。」
Name引数には、DNSファイルのフルパスを設定しなければなりません。
SQLを設定するのにSqlStatement引数を使用していますが、もちろんSqlStatement1引数も併用できます。ただし、それぞれの文字数の上限は255です。
OLEDBは使えないようです
SubType引数にwdMergeSubTypeWord2000を設定しなければ、OLEDB接続ができるはずなのですが、私の環境では動作しませんでした。
いろいろ引数を変えたり、CASE式を外したりしてみたのですが、CPU使用率が100%近くになって、Wordがハングアップしてしまいます。1時間近く待ってみたりもしたのですが、あきらめました。
そもそも、OLEDBを使用する方法で、
推奨されるデータ アクセス方法は OLEDB を使用する方法です。OpenDataSource メソッドでのデータ アクセス方法として OLEDB を指定するには、Name 引数に、データベースまたは Office DataSource Connection (.odc) ファイルのパスとファイル名を指定します。Name 引数にデータベースを指定した場合、指定したデータベースの形式をサポートする OLEDB プロバイダがインストールされていれば、Word で自動的に OLEDB が使用されます。
例
<MailMergeObject>.OpenDataSource Name:="C:\MyDB.mdb", _ SQLStatement:="SELECT * FROM [MyTable]"または
<MailMergeObject>.OpenDataSource Name:="C:\MyDataSource.odc", _ SQLStatement:="SELECT * FROM [MyTable]"
と説明されているように、Name引数にはデータベースファイルもしくはOffice DataSource Connection (.odc) ファイルを指定しなければならないので、ネイティブOLEDBプロバイダを使うのは仕様外なのでしょう。
DNSレスの接続文字列ではハングアップする
ODBCの接続文字列の書き方は、主にDSN名を指定するものと、DSN名を指定しない「DSNレス」といわれるものがあります。
DSN名を指定する場合は、
FileDSN=myDB;uid=myDBA;pwd=myDB
DSNレスの場合は、
PROVIDER=MSDASQL.1;DRIVER={Microsoft ODBC for Oracle};SERVER=myDB;UID=myDBA;PWD=myDB;
と記述します。
しかし、そもそもName引数を設定しないと、「データファイル形式の確認」ダイアログが表示されて、それを無視すると、「実行時エラー’4198′ コマンドは正常終了できませんでした。」エラーになります。
また、Name引数の設定にかかわらず、Connection引数に、
PROVIDER=MSDASQL.1;DRIVER={Microsoft ODBC for Oracle};SERVER=myDB;UID=myDBA;PWD=myDB
とDNSレス流に記述すると、Wordがハングアップします。
結局のところ、使える方法なのか?
バックデータをOracleにもっているならば、Oracleから直接Wordに差し込み印刷できるのは、魅力的な方法です。なにしろ、データをレコードセットにも、CSVファイルにも、Excelにも、Accessにも落としこまずに差し込み印刷できます。
ただ、注意点はSQLの文字数。SqlStatement、SqlStatement1共に上限は255文字。最大でも510文字までしかSQLを設定できません。
また、ODBC接続なので、速度の面でも不安があります。実際に使う際には、レコード数と項目数を絞り込まないと辛いでしょう。
これらの条件を満たすならば、利用する価値があります。
お気づきの点があれば、about and commentsからお知らせください。
最近のコメント