Microsoft OfficeをVisual Basicから印刷ツールとして使う
酒井 法雄 SAKAI,Norio norio@int21.co.jp
| 一家に1セットのMicrosoft Office? |
|---|
一時はOffice戦争などと呼ばれ,各社からOfficeと呼ばれるスイート製品が発売され,しのぎを削っていた.しかし,それも今や勝負あったかという感じだ.そうじゃないとおっしゃる方もいらっしゃるとは思うが,そう書いてしまいたくなるほどにMicrosoft Officeは普及しているように感じる.有効に使われているかはともかくとして… なにせ,パソコンを買うと有無をいわせずインストールされていたりするほどだ.
Microsoft Officeには,ワードプロセッサのWord,表計算のExcel,データベースのAccess,プレゼンテーションのPowerPointといった製品群が含まれている.
え? OutLookが抜けているじゃないかって? そういえばそんなものもあった.あれはインターネットでマトモに使えるシロモノではないし,重いし,結局のところ役に立たないのでパスである.これぞ抱き合わせ販売の妙ともいえるものである.OutLookの入っていないMicrosoft Office Enterprise Editionでも出してくれればよいのにと思うほどだ.
くれぐれも,OutLookなど使ってインターネットに接続しないように.ちゃんと動かないのも,あちこちから顰蹙を買うのもあなたのせいではなく,OutLookのせいだ.こう書いても使っちゃったら,あなたのせいだ.
日頃Mailing ListやらNetNewsやらを運営していると,このようなインターネットではスタンダードではない非常識なソフトウェアのために,大変な迷惑を被ることが多いので,つい関係ない話なのに長くなってしまった.
| 印刷ツールとしてのOffice使用例 |
|---|
それでは,印刷の話に行こう.
印刷にOffice製品を使おうというのには,次の理由がある.
・そのへんにタダ同然で転がっているのでコストがかからない
・文書,表,チャート,データベースとそれぞれの機能に合わった印刷の仕組みがある
・ODBC経由でRDBMSサーバーのデータも扱うことができる
・VBAを搭載しているので,Visual Basicから入ってもさほど違和感がない
・AutomationでVisual Basicからコントロールできる
というわけで,端的にいえば,次のような使い方ができる.
A.Visual BasicからAutomationを使って,アプリケーションを操作(データアクセス,ビジネスロジック,印刷)する.
B.各アプリケーション内にあるマクロ(VBAで書かれた関数)や,印刷をするために作成したレポート,文書などをキックして呼び出す.
A.の使い方は,すべてをAutomationで実現する方向で考えるというわけだが,たとえばデータベースに入っているデータをクエリーして,適切なデータに変換するといった作業を,いちいちVisual Basicからやるのは効率的ではない.これはAutomationを実行するときには,マーシャリングが介在するために実行速度が落ちてしまうからだ.
したがって,B.のやり方を使う方がよいだろう.たとえば,次のような使い方だ.
Access活用あるいは次のようなシナリオも考えられる.
Access + Excel活用
1)印刷以外の仕事はVisual Basicで書く
2)Accessで必要なRDBMSサーバーとのリンクあるいはテーブルを作成しておく
3)必要に応じてAccessでクエリーを作っておく
4)ExcelのVBAを使って印刷するマクロを作っておく
5)Visual BasicからAccessの機能を呼び出して,CSVあるいはXLS形式でファイルを保存する
6)Visual BasicからExcelの機能を呼び出して,先に作ったファイルを読み込み,マクロを実行して印刷する
Access + Word活用
1)印刷以外の仕事はVisual Basicで書く
2)Accessで必要なRDBMSサーバーとのリンクあるいはテーブルを作成しておく
3)必要に応じてAccessでクエリーを作っておく
4)Wordの差し込み印刷でAccessのクエリーを使って印刷する
あるいは,
Access + Word活用2
1)印刷以外の仕事はVisual Basicで書く
2)Accessで必要なRDBMSサーバーとのリンクあるいはテーブルを作成しておく
3)必要に応じてAccessでクエリーを作っておく
4)Visual BasicからAccessの機能を呼び出して,CSVあるいはXLS形式でファイルを保存する
5)Wordの差し込み印刷でCSVあるいはXLSファイルをマージして印刷する
| Visual Basicからの制御方法 |
|---|
では,どのようにすればAccessやExcel,Wordの機能をVisual Basicから使うことができるのかということになる.正直に書くと,私はこのへんのアプリケーション自体には明るくない.むしろ,読者諸氏の方が詳しい方が多いくらいだろう.Excelはマクロ記録してからVBAを編集すればよいし,Wordの差し込み印刷は,[ツール]-[差し込み印刷ヘルパー]メニューを選べば,誰でも使うことができるに違いない.
少々面倒なのはAccessの制御だが,これはAccess95が発売された当初に本誌No.6にまさにそういった内容の記事を執筆した.詳しくはバックナンバーを… と,それはもうなくなってしまったそうだから,拙著『酒井法雄のVisual Basic 5.0ブリーフィング』(翔泳社)をお買い求めいただくと,付録CD-ROMで読むことができる.こうしていただけるとありがたい.
しかし,どうしても酒井の本は買いたくないという方は,実はPCDNの「Visual Basic Magazineライブラリ」(http://pcdn.int21.co.jp/pcdn/vb/noriolib/vbmag/6/vbacc/vbacc.html)に該当記事が掲載されているので,この記事ならタダで読むこともできる.
では,そういうことで今回はこれくらいにしておこう.と思ったのだが,念のためこのサンプルプログラムを動かしてみたら,見事に動かなかった.実は,ちょっとだけ手直ししたものを今月号の付録CD-ROMに納めてあるのだが,調べてゆくとその後も動かないところがあることが判明した.というわけで,一応今回も簡単に説明しておくことにしよう.
| Accessの制御 |
|---|
ご存じのように,Accessのデータベースエンジンは,Visual BasicにもついてくるDAOのエンジンそのものである.これは,Visual Basicの参照設定ダイアログからDAOをチェックすれば使えるようになる.同様にして,Access Object Libraryを選ぶと,Access固有の機能も使えるようになる(図1).
図1:Visual Basicの参照設定ダイアログからAccess Object Libraryを選ぶ
次に,AccessのヘルプでAccessのApplicationオブジェクトを見てみよう(図2).
図2:AccessのApplicationオブジェクト![]() |
|
DoCmdオブジェクトには,次のようなメソッドがある.だいたいのAccessの操作はこれらのメソッドを使って実現することができる(表1a).なお,これらのメソッドを使っても解決できないAccessの操作は,表1bのようにして行なう.
表1a:DoCmdオブジェクトのメソッド一覧
| ApplyFilter | GoToPage | OutputTo | SelectObject |
| Beep | GoToRecord | PrintOut | SendObject |
| CancelEvent | HourGlass | Quit | SetMenuItem |
| Close | Maximize | Rename | SetWarnings |
| CopyObject | Minimize | RepaintObject | ShowAllRecords |
| DeleteObject | MoveSize | Requery | ShowToolbar |
| DoMenuItem | OpenForm | Restore | TransferDatabase |
| Echo | OpenModule | RunCommand | TransferSpreadsheet |
| FindNext | OpenQuery | RunMacro | TransferText |
| FindRecord | OpenReport | RunSQL | |
| GoToControl | OpenTable | Save |
表1b:メソッドで実現できない操作とその対処
| 関数名 | 該当する操作 | 対処 |
|---|---|---|
| AddMenu | メニューの追加 | (なし) |
| MsgBox | メッセージボックス | MsgBox関数を使用 |
| RunApp | アプリケーションの実行 | Shell関数を使用して他のアプリケーションを実行 |
| RunCode | プロシージャの実行 | 関数をVisual Basicで直接実行 |
| SendKeys | キー送信 | SendKeysステートメントを使用 |
| SetValue | 値の代入 | 値をVisual Basicで直接設定 |
| StopAllMacros | 全マクロの中止 | (なし) |
| StopMacro | マクロの中止 | (なし) |
これらのうち,OpenReportメソッドはAccessで作成してあるレポートを開くものだ.また,TransfreDatabase,TransferSpreadsheet,TransferTextあたりのメソッドでは,別の形式のファイルとして保存することができる.他にもたくさん楽しそうなコマンドがあるが,ここでは印刷をすることと,中間ファイルを作ることを目的としたので,次の機会に譲ることにする.というわけで,ここでは次のメソッドを使ってみることにしよう.
・テーブルのメンテナンス:テーブルを開く(OpenTable)
・印刷:レポートを開く(OpenReport)
・データのCSV形式コンバート:テキストのCSV形式での保存(TransferText)
・データのワークシート形式コンバート:ワークシート変換(TransferSpreadsheet)
・その他形式コンバート:RTF形式,Excel形式でのファイル作成(OutputTo)
・SQLデータベースの使用:データベース変換(TransferDatabase)
| Accessのテーブルを開く:OpenTable |
|---|
| サンプル:oleacc1 |
さて,いきなりOpenReportメソッドなどを使ってみたいところだが,すぐにそうはできない.というのも,データベース自体を開く必要があるからだ.何ごとにも順番というものがある.まずはデータベースを選んでテーブルを抜き出してみよう.これは,次の手順で行なう.
まず,Accessのアプリケーションオブジェクトを作成する.CreateObjectでもよいし,参照設定してあればNewキーワードを使うこともできる.以前にAccess95を使ったときには,CreateObjectだといろいろと不具合があったので,今回もNewを使ってみた.これ以後,appAccessがAccessのApplicationオブジェクトなので,その下にあるDoCmdオブジェクト下のさまざまなメソッドも呼び出すことができるようになる.
Private Sub Form_Load()
' Set appAccess = _
' CreateObject("Access.Application")
Set appAccess = _
New Access.Application
End Sub
オブジェクトを作成したら,肝心のMDBファイルを指定しなくてはならない.ここでは,コモンダイアログを使ってMDBファイルを指定する.これにはとくに注意はない.
' Select MDB File
Private Sub cmdSelect_Click()
On Error Resume Next
cmdlg1.ShowOpen
If Err.Number = 0 Then
On Error GoTo 0
lblDBName.Caption = cmdlg1.filename
GetTable
End If
End Sub
として,指定されたMDBファイル名から,テーブルの一覧を得よう.OpenCurrentDatabaseメソッドを使ってMDBファイルをオープンする.この他にも
・OpenCurrentDatabase:既存のデータベースファイルを開く
・NewCurrentDatabase:新しいデータベースファイルを作成して開く
・CloseCurrentDatabase:現在のデータベースファイルを閉じる
などを使うことができる.オブジェクト変数dbにデータベースの0番目を得る.あとは,TableDefsコレクションからFor Eachを使ってテーブル名を得て,コンボボックスに追加する(リスト1,図4).
では,いよいよ,指定されたテーブルを開いてみよう.ここでは,DoCmdオブジェクトのOpenTableメソッドを使う.しかし,実際にはノーマル,デザイン,プレビューの3つの開き方がある.これはまさにAccessのテーブルを開くときと同じである.
そこで,オプションボタンで指定されたパラメータを渡して次のような文で実行することができる.
appAccess.DoCmd.OpenTable _ cboTables.Text, view, datamodeこの部分の全体のコード(リスト2)と,終了およびWaitのコード(リスト3)を示す.また,表2にはOpenTableメソッドの概要を示してあるので参照されたい.
リスト2:テーブルを開く
Private Sub cmdOpenTable_Click()
Dim v As Integer
Dim view As Integer
Dim datamode As Integer
Dim i As Integer
' get specify view value
For i = 0 To 2
If optView(i).Value = True Then
v = i
Exit For
End If
Next i
Select Case v
Case 0
view = acViewNormal
Case 1
view = acViewDesign
Case 2
view = acViewPreview
End Select
If chkRO.Value = 1 Then
datamode = acReadOnly
Else
datamode = acEdit
End If
appAccess.DoCmd.OpenTable cboTables.Text, view, datamode
End Sub
|
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
appAccess.CloseCurrentDatabase
Set db = Nothing
Set appAccess = Nothing
End Sub
Sub Wait(sec As Integer)
Dim n As Variant
n = Now
Do Until Now - n >= TimeSerial(0, 0, sec)
DoEvents
Loop
End Sub
|
| 指定項目 | 内容 |
|---|---|
| tablename | カレントデータベースのテーブルの有効名を文字列式で指定 |
| view | 次のいずれかの組み込み定数を指定(acViewNormal/acViewDesign/acViewPreview) |
| datamode | 次のいずれかの組み込み定数を指定(acAdd/acEdit/acReadOnly) |
次に,ノーマルでの内容表示,デザイン,プレビューがそれぞれの画面を示す(図5〜7).このプログラムでAccess95と違っていたのは,これらの区別をするacViewPreviewなどの定数値である.なお,プレビューはVisibleチェックボックスをチェックし,可視にしておく必要がある.
図5:テーブル内容の表示
|
図6:テーブル内容のデザイン
|
| Accessのレポートを開く:OpenReport |
|---|
| サンプル:oleacc2 |
テーブルを開くことができたので,次にレポートを開いてみることにしよう.
ここでは,先ほどのGetTableプロシージャを書き換えてレポートオブジェクトを得る.しかし,Reportsといったコレクションを直接得ることはできないので,db.ContainersコレクションからContainerオブジェクトを取り出すことになる.さらに,そのContainerオブジェクトに含まれるDocumentsコレクションを調べると,そこにDocumentオブジェクトが入っているという二重ループだ(リスト4).
ただし,これだけではダメで,プロパティなどを調べてレポートだけを表示するようにする必要がある.実は前回もここはよく調べていなかったのだが,今回も時間がなかった.申しわけない.
リスト4:データベースからレポートを取り出す
Private Sub GetTable()
Dim ct As Container
Dim doc As Document
Screen.MousePointer = vbHourglass
Me.Enabled = False
appAccess.OpenCurrentDatabase lblDBName.Caption, False
Set db = appAccess.DBEngine.Workspaces(0).Databases(0)
cboReports.Clear
For Each ct In db.Containers
For Each doc In ct.Documents
cboReports.AddItem doc.Name
Next
Next
cboReports.ListIndex = 0
cmdOpenReport.Enabled = True
chkVisible_Click
Me.Enabled = True
Screen.MousePointer = vbDefault
End Sub
|
次に,OpenReportメソッドの概要を示す(表3).これもAccess95と比較すると,viewの定数名が変更されている.
表3:OpenReportメソッドの概要
構文:DoCmd.OpenReport reportname [, view] [, filtername] [, wherecondition]
| 指定項目 | 内容 |
|---|---|
| reportname | カレントデータベースのレポートの有効名を文字列式で指定 |
| view | 次のいずれかの組み込み定数を指定(acViewNormal/acViewDesign/acViewPreview) |
| filtername | カレントータベースのクエリーの有効名を文字列式で指定 |
| wherecondition | 有効なSQL WHERE句を文字列式で指定 |
気をつけてほしいのは,引数viewの内容である.acNormalではいきなりレポートが印刷されてしまうということだ(リスト5).
リスト5:レポートを開く
|
図8:レポートのプレビュー
|
というわけで,いとも簡単にAccessのレポートの呼び出すことができるのである.
また,いきなり印刷しようというときには,次のメソッドPrintOutも有効だ(表5).
表4:PrintOutメソッドの概要
構文:DoCmd.PrintOut [printrange][, pagefrom, pageto][, printquality][, copies][, collatecopies]
| 指定項目 | 内容 |
|---|---|
| printrange | 次のいずれかの組み込み定数を指定(acPrintAll=既定値/acSelectionacPages) |
| pagefrom | アクティブフォームまたはアクティブデータシートの有効なページ番号を数式で指定.引数printrangeにacPagesを指定した場合は省略不可 |
| pageto | アクティブフォームまたはアクティブデータシートの有効なページ番号を,数式で指定.引数printrangeにacPagesを指定した場合は省略不可 |
| printquality | 次のいずれかの組み込み定数を指定(acDraftacHigh=既定値/acLowacMedium) |
| copies | 数式.既定値は1 |
| collatecopies | 部単位で印刷するには True (- 1) を使い,部単位で印刷しない場合は False (0) を使う.既定値はTrue |
ここまでは,Accessだけでできることであり,Visual BasicからボタンひとつでAccessの印刷プレビューを呼び出すことができる可能性を示したに過ぎない.
| テキストのCSV形式での保存:TransferText |
|---|
| サンプル:oleacc2 |
ここまでできれば,もう他のこともそう難しくはないように思えてくる.次に,他のアプリケーションで汎用に使えるCSV形式やExcelで使うときに便利なExcel形式へのコンバートなどをしてみよう.
テキストをCSV形式で保存するなどというのは,Visual Basicでコーディングしても大したものではないのだが,Access 95がやってくれるならわざわざコーディングする必要もないだろう.
これには,TransferTextメソッドを使う.次にこのメソッドの概要を示す(表6).
表5:TransferTextメソッドの概要
構文:DoCmd.TransferText [transfertype][, specificationname], tablename, filename[, hasfieldnames][, HTMLtablename]
| 指定項目 | 内容 |
|---|---|
| transfertype | 次のいずれかの組み込み定数を指定(acExportDelim/acExportFixed/acExportHTML/acExportMerge/acImportDelim=既定値/acImportFixed/acImportHTML/acLinkDelim/acLinkFixed/acLinkHTML) |
| specificationname | 作成してカレントデータベースに格納したインポートまたはエクスポート定義の名前 |
| tablename | テキストデータとのインポート,エクスポート,あるいはリンクを行なうAccessテーブルの名前,または結果をテキストファイルにエクスポートするAccess 選択クエリーの名前 |
| filename | インポート,エクスポート,またはリンクを行なうテキストファイルの,パスを含めた完全な名前 |
| hasfieldnames | インポート,エクスポート,またはリンク時に,テキストファイルの最初の行をフィールド名として使うか |
| HTMLtablename | インポートまたはリンクするHTMLファイル内のテーブルまたはリストの名前 |
ここからもわかるように,CSV形式のファイルはインポート,エクスポートまたはリンク(従来のアタッチに当たる)させることができる.実は,この後に出てくるその他のファイル形式とのやりとりも,たいていはこの3つの形式を選ぶことができる.つまりは,データコンバートは自由自在ということだ.
このあたりの作業は,次の3つのいずれかということになる.
1.元テーブルとコンバート先のファイル形式を指定してエクスポートする
2.コンバート元のファイル形式とファイルを指定してインポートし,適当なテーブルを作らせる
3.外部のファイル形式とファイルを指定し,内部のテーブル名を指定(なければ自動的に作られる)してリンクさせる
こう考えると,ワークシート形式,RTF形式,HTML形式,他のデータベース形式とも基本線は同じやりかたということになる.そこで,ここでは大枠のプログラムからCSV形式のもののみのコーディング例を示す(リスト6).
リスト6:CSV形式ファイルの変換
Private Sub cmdLoadCSV_Click()
Dim CSVFile As String
CSVFile = App.Path & "\ACCOLE.CSV"
appAccess.DoCmd.TransferText acImportDelim, _
, cboTables.Text, CSVFile, -chkUseField.Value
MsgBox "Load CSV File Complete!!"
End Sub
' Save CSV
Private Sub cmdSaveCSV_Click()
Dim CSVFile As String
CSVFile = App.Path & "\ACCOLE.CSV"
appAccess.DoCmd.TransferText acExportDelim, _
, cboTables.Text, CSVFile, -chkUseField.Value
MsgBox "Save CSV File Complete!!"
End Sub
|
| ワークシート変換:TransferSpreadsheet |
|---|
| サンプル:oleacc3 |
ワークシート変換は,ExcelやLotus 1-2-3形式のファイルと変換するものだ.例によって,インポート,エクスポート,リンクのいずれもが可能である.ただし,実際にはアプリケーションのバージョンによってサポートが違うので気をつけなくてはならない.
次に,ワークシート変換をするTransferSpreadsheetメソッドの概要を示す(表7).ExcelおよびLotusのワークシートのデータをインポート,エクスポート,およびリンクすることができる.ただし,Lotus ワークシートは読み取り専用.
表6:TransferSpreadsheetメソッドの概要
構文:DoCmd.TransferSpreadsheet [transfertype] [, spreadsheettype], tablename, filename [, hasfieldnames] [, range]
| 指定項目 | 内容 |
|---|---|
| transfertype | 次のいずれかの組み込み定数を指定(acImport/acExport/acLink) |
| spreadsheettype | 次のいずれかの数値を指定(0:acSpreadsheetTypeExcel3=既定値/6:acSpreadsheetTypeExcel4/5:acSpreadsheetTypeExcel5/5:acSpreadsheetTypeExcel7/8:acSpreadsheetTypeExcel97/2:acSpreadsheetTypeLotusWK1/3:acSpreadsheetTypeLotusWK3/7:acSpreadsheetTypeLotusWK4/4:acSpreadsheetTypeLotusWJ2 - 日本語バージョンのみ) |
| tablename | ワークシートデータのインポート先,エクスポート元,またはリンク先のAccessテーブルの名前を指定.あるいは,Access選択クエリーの結果をワークシートにエクスポートするときには選択クエリーの名前を文字列式で指定 |
| filename | インポート元,エクスポート先,またはリンク先のワークシートのファイル名をフル パスで指定 |
| hasfieldnames | インポート,エクスポート,またはリンクするときに,ワークシートの 1 行目をフィールド名として使うときはTrue(-1)を指定し,通常のデータとして扱うときにはFalse(0)を指定 |
| range | セルの有効範囲またはワークシートの範囲名を文字列式で指定.この引数はインポートする場合にだけ指定する |
ここでは,Excelとの変換をするコーディング例を示す(リスト7).
リスト7:エクセルファイルにエクスポート
Private Sub cmdExpExcel_Click()
Dim EXCELFile As String
EXCELFile = App.Path & "\Book1.Xls"
appAccess.DoCmd.TransferSpreadsheet _
acExport, acSpreadsheetTypeExcel97, _
cboTables.Text, EXCELFile, -chkUseField.Value
MsgBox "Export Excel File Complete!!"
End Sub
' Import from Excel File
Private Sub cmdImpExcel_Click()
Dim EXCELFile As String
EXCELFile = App.Path & "\Book1.Xls"
appAccess.DoCmd.TransferSpreadsheet _
acImport, acSpreadsheetTypeExcel97, _
"IMPORT_EXCEL", EXCELFile, -chkUseField.Value
MsgBox "Import Excel File Complete!!"
End Sub
' Link Excel File
Private Sub cmdLinkExcel_Click()
Dim EXCELFile As String
EXCELFile = App.Path & "\Book1.Xls"
appAccess.DoCmd.TransferSpreadsheet _
acLink, acSpreadsheetTypeExcel97, _
"LINK_EXCEL", EXCELFile, -chkUseField.Value
MsgBox "Link Excel File Complete!!"
End Sub
|
| RTF形式,Excel形式でのファイル作成:OutputTo |
|---|
| サンプル:oleacc3 |
OutputToメソッドでは,RTF形式,Excel形式あるいはテキスト形式でのファイル作成ができる.インポートはできないので注意してほしい.
次に,OutputToメソッドの概要を示す.
表7:OutputToメソッドの概要
構文:DoCmd.OutputTo objecttype[, objectname][, outputformat][, outputfile][, autostart][, templatefile]
| 指定項目 | 内容 |
|---|---|
| objecttype | 次のいずれかの組み込み定数を指定(acOutputForm/acOutputModule acOutputQuery/acOutputReport/acOutputTable) |
| objectname | 引数objecttypeで選択した種類のオブジェクトの有効名を文字列式で指定 |
| outputformat | 次のいずれかの組み込み定数を指定(acFormatXLS/acFormatRTF/acFormatTXT) |
| outputfile | オブジェクトの出力先のファイルの名前をフルパスで指定.この引数を指定しない場合,出力ファイル名を入力するためのプロンプトが表示される |
| autostart | Windows対応のアプリケーションを起動して,引数outputfileで指定したファイルをロードするときに,True(-1)を設定 |
| templatefile | HTMLファイル,HTXファイル,またはASPファイルのテンプレートとして使うファイル |
OutputToメソッドで面白いところは,ファイルを保存したあとに,対応するアプリケーションを自動的に実行することができる点だ.次に,サンプルコードと実行例を示す(リスト8,図9・10).
なお,この例ではobjecttypeを省略しているが,これはAccess95のときの書き方であるが,そのまま動く.カンマをつけると「引数は省略できません」エラーになってしまう.この例では,テーブルあるいはクエリーのいずれからも出力できるようにしてあるので,objecttypeをいっさい記述しない方法の方が簡単だ.
念のために書いておくが,HTML形式は例によってMicrosoftの独自タグやらが入っていて気持ちが悪い.このまま使うことのないようお気をつけいただきたい.
リスト8:OutputToメソッド
' Save to HTML File and Execute WebBrowser
Private Sub cmdSaveHTML_Click()
Dim HTMLFile As String
HTMLFile = App.Path & "\ACCOLE.HTM"
appAccess.DoCmd.OutputTo _
cboOutput.ListIndex, cboTables.Text, acFormatHTML, _
HTMLFile, -chkExec.Value
MsgBox "Save RTF File Complete!!"
End Sub
' Save to RTF File and Execute Word
Private Sub cmdSaveRTF_Click()
Dim RTFFile As String
RTFFile = App.Path & "\ACCOLE.RTF"
appAccess.DoCmd.OutputTo _
cboOutput.ListIndex, cboTables.Text, acFormatRTF, _
RTFFile, -chkExec.Value
MsgBox "Save RTF File Complete!!"
End Sub
|
図9:.RTF形式で保存しWordで開く
|
図10:.HTM形式で保存しWebブラウザで開く
|
| データベース変換:TransferDatabase |
|---|
クライアント/サーバー型RDBMSにも応用可能なデータベース変換機能だ.Accessではさまざまな種類のデータベースファイルとのコンバートが可能であるが,これをすべてVisual Basicからも呼び出して使うことができる.しかも,ODBCを使ってOracleやSQL ServerなどのRDBMSとのインポート,エクスポート,そしてリンクも可能である.こうなってくると,SQL*PlusやISQLなどを使うのが馬鹿馬鹿しくなってくる.
この機能を実現するのが,TransferDatabaseメソッドだ.次に,概要を示す(表9).
表8:TransferDatabaseメソッドの概要
構文:DoCmd.TransferDatabase [transfertype], databasetype, databasename [, objecttype], source, destination [, structureonly] [, saveloginid]
| 指定項目 | 内容 |
|---|---|
| transfertype | 次のいずれかの組み込み定数を指定(acImport/acExport/acLink) |
| databasetype | データのインポート,エクスポート,またはリンクが可能なデータベースの種類の有効名を文字列式で指定 |
| databasename | データのインポート,エクスポート,またはリンクに使うデータベースの名前をフルパスで指定 |
| objecttype | 次のいずれかの組み込み定数を指定(acTable/acQuery/acForm/acReport/acMacro/acModule) |
| source | インポート,エクスポート,またはリンクするデータのオブジェクト名を文字列式で指定 |
| destination | データベースのインポート,エクスポート,またはリンクする先のオブジェクト名を文字列式で指定 |
| structureonly | データベーステーブルの構造だけをインポートまたはエクスポートするときに True(-1)を,テーブルの構造とそのデータをインポートまたはエクスポートするときにはFalse(0)を指定 |
| saveloginid | ODBCデータベースのログオンIDとパスワードをデータベースからリンクされたテーブルの接続文字列に格納するときは,Trueを指定 |
ここでは,ODBCデータソースに接続してみた.ちなみに,引数databasetypeには,“ODBC”を指定する.このあたり,サンプルプログラムやヘルプには誤った記述がされているので注意してほしい.
エクスポートでは,指定されたテーブルをそのままの名前でODBCデータソース名SQL65のMicrosoft SQL Server 6.5にエクスポートした.
インポートでは,SQL Server上にある“authors”テーブルを,ローカルの“Import_SQL60”テーブルにインポートしている.この順番もPreview Programのヘルプでは誤って記述されていたので注意してほしい.
リンクでも,同様に“authors”テーブルを“Link_SQL65”テーブルにリンクしている.
次に,それぞれのコードを示す(リスト10).
リスト10:TransferDatabaseメソッドのコーディング例
' Export to ODBC SQL
Private Sub cmdExpDB_Click()
On Error Resume Next
appAccess.DoCmd.TransferDatabase acExport, "ODBC", _
"ODBC;DSN=SQL65;UID=sa;PWD=;LANGUAGE=japanese;DATABASE=pubs", acTable, cboTables.Text, cboTables.Text
If Err Then
MsgBox Err.Description, vbCritical, "Error " & CStr(Err.Number)
Else
MsgBox "Export ODBC File Complete!!"
End If
End Sub
' Import from ODBC SQL
Private Sub cmdImpDB_Click()
On Error Resume Next
appAccess.DoCmd.TransferDatabase acImport, "ODBC", _
"ODBC;DSN=SQL65;UID=sa;PWD=;LANGUAGE=japanese;DATABASE=pubs", _
acTable, "authors", "Import_SQL65", False
If Err Then
MsgBox Err.Description, vbCritical, "Error " & CStr(Err.Number)
Else
MsgBox "Import ODBC File Complete!!"
End If
End Sub
' Link ODBC SQL
Private Sub cmdLinkDB_Click()
On Error Resume Next
appAccess.DoCmd.TransferDatabase acLink, "ODBC", _
"ODBC;DSN=SQL65;UID=sa;PWD=;LANGUAGE=japanese;DATABASE=pubs", _
acTable, "authors", "Link_SQL65", False
If Err Then
MsgBox Err.Description, vbCritical, "Error " & CStr(Err.Number)
Else
MsgBox "Link ODBC File Complete!!"
End If
End Sub
|
| Excelのマクロをキックする |
|---|
| サンプル:xlspr |
AccessではCSVやExcel形式でのファイル保存ができた.これをExcelのマクロを装備したシートに読み込ませてマクロを実行して印刷してしまおうというのが,次のステップである.
一般的には,単なるテキストファイルであるCSVの方が,Excel形式ファイルより汎用性があるが,マクロで自動実行したときには,\が行頭についているセルを文字列型として認識してしまうといった問題が発生した.そのため,ここではあえてExcel形式で保存したものを読み込ませることにした.
さて,このファイルを読み込ませて印刷するといった手順だが,いちいちコードを各必要はない.次の手順でExcelに記録させて,後から適当に書き直すことができるのである.
1)[ツール]メニューの[マクロ]-[新しいマクロの記録]を開く
ちなみに,Alt + F11キーでExcelのVBA環境を起動することができる.
ここでお断りしておくと,私はExcelはまったくのシロートであり,よくわかっていない.今回のExcelサンプルプログラムも,弊社の清水義明氏にマクロ作成を依頼した.次のサンプルは,Nwind.Mdbに含まれるOrdersテーブルをそのままXLS形式で吐き出したOrders.xlsを表形式で印刷するものである(リスト11).同氏によると,これにはかなり冗長なコードが含まれているそうだが,これがExcelが出すほぼそのままのコードだそうだ.実際には,もっと適切に編集したり,コードを追加するなども考えられる.
リスト11:AccessのテーブルをExcelの表形式で印刷
リスト12:チャートをプレビュー
このようにして,Visual BasicからボタンひとつでExcelの表やチャートなどの豊富な機能を使った印刷ができるようになる.
身近にある意外に便利な印刷ツールとして,Microsoft Officeを使ってみた.
2)適当に設定して
3)マクロを選択し,[編集]ボタンをクリックする
4)適切な操作をする
5)操作を終了したらマクロ記録を終了する
6)[ツール]メニューの[マクロ]-[マクロ]を開く
7)マクロを選択し,[編集]ボタンをクリックする
8)マクロ内のマクロ名,ディレクトリ名とファイル名をなどを適切に編集する
ただし,クエリーの範囲選択などはあくまでもAccess側でやっておくべきことであり,ここではXLSの内容をそのまま印刷という形にしておくべきだ.そのほうがメンテナンスもデバッグもラクだからだ.
このマクロは,autoprnt.xlsというファイルに保存した.Visual Basicからこのマクロを実行するには,ファイルをMicrosoft FormにしてインスタンシングをするGetObject(CreateObjectではない!!)を使って,Excelのオブジェクトを作成する.なお,Excel97からは作成されるオブジェクトが異なっている.
Sub PrintSheet()
ChDir "F:\DevStudio\VB\test\VBACC"
Workbooks.Open FileName:= _
"F:\DevStudio\VB\test\VBACC\Orders.xls"
Range("A:A,B:B,D:D,H:H").Select
Range("H1").Activate
Selection.Copy
Sheets.Add
ActiveSheet.Paste
Selection.Columns.AutoFit
Application.CutCopyMode = False
Selection.Sort Key1:=Range("A2"), _
Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, SortMethod _
:=xlPinYin
Application.ScreenUpdating = False
With ActiveSheet.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
ActiveSheet.PageSetup.PrintArea = ""
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.78740157480315)
.RightMargin = Application.InchesToPoints(0.78740157480315)
.TopMargin = Application.InchesToPoints(0.984251968503937)
.BottomMargin = Application.InchesToPoints(0.984251968503937)
.HeaderMargin = Application.InchesToPoints(0.511811023622047)
.FooterMargin = Application.InchesToPoints(0.511811023622047)
.PrintHeadings = False
.PrintGridlines = True
.PrintComments = xlPrintNoComments
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = True
.Zoom = 100
End With
ActiveWindow.SelectedSheets.PrintPreview
' ActiveWindow.SelectedSheets.PrintOut _
' Copies:=1, Collate:=True
ActiveWorkbook.Close (False)
End Sub
以前のバージョンのExcelではオブジェクトの型にSheetを指定したときには,Worksheetオブジェクトが,Chartを指定したときにはChartオブジェクトだったが,いずれもExcel 97ではWorkbookに変更された.迷惑な話だ.VB3時代から動かしてきたプログラムが動かなくなってしまった.
さて,ここでひとつ注意が必要だ.マクロを実行するには,Applicationオブジェクトが可視状態になっていなくてはならない.そこで,Application.VisibleプロパティをTrueにしておく.
マクロを実行するには,
obj.Application.run _
"autoprnt.xls!PrintSheet"
のように,「(xls名)!(マクロ名)」をrunメソッドの引数として実行すればOKだ.
Private Sub cmdPrSheet_Click()
Dim obj As Object
Set obj = GetObject _
("F:\devstudio\vb\test\vbacc\autoprnt.xls")
obj.Application.Visible = True
obj.Application.run "autoprnt.xls!PrintSheet"
obj.Application.Visible = False
End Sub
同様にして,チャートをプレビューするマクロおよび,それをキックするVisual Basic側のコードを示す(リスト12).ここでは,Nwind.MDB内にあるクエリー「Category Sales for 1995」をCat95.Xlsというファイルにコンバートして使っている.
Sub PrintChart()
' Add
Dim Cels As Object
ChDir "F:\DevStudio\VB\test\VBACC"
Workbooks.Open FileName:= _
"F:\DevStudio\VB\test\VBACC\Cat95.xls"
Set Cels = ActiveCell.CurrentRegion
Charts.Add
ActiveChart.ChartType = xlColumnClustered
' ActiveChart.SetSourceData Source:=Sheets _
' ("CatSales").Range("A1:B9"), PlotBy _
' :=xlColumns
' Add
ActiveChart.SetSourceData Source:=Cels, PlotBy _
:=xlColumns
ActiveChart.Location Where:=xlLocationAsNewSheet
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "CategorySales"
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = False
End With
With ActiveChart.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0.78740157480315)
.RightMargin = Application.InchesToPoints(0.78740157480315)
.TopMargin = Application.InchesToPoints(0.984251968503937)
.BottomMargin = Application.InchesToPoints(0.984251968503937)
.HeaderMargin = Application.InchesToPoints(0.511811023622047)
.FooterMargin = Application.InchesToPoints(0.511811023622047)
.ChartSize = xlFullPage
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlLandscape
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.BlackAndWhite = True
.Zoom = 100
End With
' ActiveWindow.SelectedSheets.PrintOut _
' Copies:=1, Collate:=True
ActiveWindow.SelectedSheets.PrintPreview
ActiveWorkbook.Close (False)
End Sub
Private Sub cmdPrChart_Click()
Dim obj As Object
Set obj = GetObject _
("F:\devstudio\vb\test\vbacc\autoprnt.xls")
obj.Application.Visible = True
obj.Application.run "autoprnt.xls!PrintChart"
obj.Application.Visible = False
End Sub
図12:マクロを呼び出すアプリケーション

図14:Excelチャート形式での印刷プレビュー
Wordの差し込み印刷
最後に,Wordへの差し込み印刷を紹介しておこう.
図15:Wordでの差し込み印刷の例
これはまったく難しいことはない.先に述べたように,[ツール]-[差し込み印刷ヘルパー]メニューを選べば,誰でも使うことができるハズだ.ただし,ここではAccessなどのクエリーでなくても,XLSやCSVも指定することができる.したがって,Excelのときと同じような手順で実行することができるハズだ.
残念ながら,今回はあまり時間がなかったので,Visual Basicからキックする部分はないが,やってみればそんなに難しいことはないだろう.
図15は,実際に使っているセミナー受講票の印刷プログラムの例である.Webから申し込まれたセミナー情報は,SQL Serverに入っている.これとローカルにあるAccessのセミナー会場などのMDBなどと組み合わせたクエリーをし,Wordで書いた文書の適当な部分にそれらのデータを差し込んでいるのである.
左側にドロップダウンしているのは,差し込み可能なフィールド一覧である.
Officeを印刷ツールとして使うポイント
何度も書いたように,実は私自身はそんなにOfficeのパワーユーザーではない.そのため,もっと効率的な使い方や,よいアイデアはもっとありそうな気がしてならない.とはいえ,指針だけは示すことができたと思う.以前に書いたものと内容的にほぼ同じ部分があるが,このような事情だからご勘弁いただきたい.
それにして,多少のモディファイで以前に作ったコードがほぼそのまま走るのは素晴らしい.どうせなら,まったくいじらなくても同じように走って欲しいところではあるが…
ともあれ,もしかしたらあまり活用されていないかもしれない方にとっても,Microsoft Office製品の使い道がひとつ増えたことは間違いないだろう.
最後に念を押しておくと,くれぐれも,使おうと思うのはOutLook以外にしておこう.
int21 ホームページ | PCDN ホームページ
Copyright (c) 1998 int21 Corporation All Rights Reserved.
For questions or comments, please send mail to: pcdn@int21.co.jp