Back Home Next

A1:DBを構成するテーブルを調べる。

AcsTbBkでは他のAccessファイルに含まれるテーブル名をリストにする処理があります。
データベースに含まれるテーブル名を調べる方法はTablesDefsコレクションを調べるか、ContainersコレクションのテーブルDocumentsコレクションを調べる方法があります。
コレクションとは同じ種類のオブジェクトが集まったものを言います。どちらともデータベースオブジェクトの子になります。

1) DataBase-TableDefs-TableDef

2) DataBase-Containters-Container-Documents-Document

Documentオブジェクトの場合、Queryも同じDocumentとして扱われていますので、テーブルのリストを作成するとしたらTabledefsの方が便利です。Countプロパティを使えばいくつのテーブルが含まれるか判りますので整数インデックスで識別してNameプロパティを取得します。

テーブルの名前を全部メッセージで表示するプログラムです。

with Currentdb
  for i=0 to .TableDefs.Count - 1
   If Not ( .TableDefs(i).Attributes And (dbSystemObject Or dbHiddenObject)) Then
     msgbox  .TableDefs(i).Name
   end if
  next i
end with

TableDefs(i)で全部ダンプするとシステムおよび隠しテーブルも表示されますのでAttributesを調べてこの二つのテーブルを除きます。3行目のIf文がそれに当たります。リンクテーブルも除外したければConnectプロパティが設定されているか調べて判定します。

if .TableDefs(i).Connect <> "" then
    
end if

では外部のデータベースのテーブルをダンプするにはどうすればよいでしょうか?TableDefsオブジェクトはDataBaseオブジェクトの子ですから、DataBaseオブジェクトに調べたい外部データベースを設定すればよいのです。

調べたい外部データベースのパスを"C:\MyDucument\Test.mdb"とすれば、Set文でオブジェクトを作成すれば、その下位オブジェクトをすべて同じように扱うことができます。

Dim DB As DataBase
Set DB = OpenDatabase("C:\MyDucument\Test.Mdb")
with DB
  for i=0 to .TableDefs.Count - 1
    If Not( .TableDefs(i).Attributes And (dbSystemObject Or dbHiddenObject)) Then
      msgbox .TableDefs(i).Name
    end if
  next i
end with
DB.Close

注意:変数定義は省略してiいるものもあります。


A2:データベースオブジェクトとは

データベースオブジェクトには多数のメソッド、プロパティが準備されていて、AccessのVBAと言えばこのオブジェクトの使い方の説明のようなものになります。
解説本にはデータベースオブジェクトとしてそのまま説明されています。しかし何かは気になりますね。
データベースオブジェクトとはDBEngineという、複数種のアプリケーション(Officeファミリ、VisualBasic等)から共通に利用できるデータベース用のオブジェクトです。

DBEngine−WorkSpaces−WorkSpace−DataBases−DataBase

sがついているのはオブジェクトが複数入ったコンテナです。Accessアプリケーションが開くと、ワークスペースコンテナに規定のワークスペースとしてWorkSpaces(0)が自動的に作成され、ApplicationのDBEngineプロパティでDBEngineを取得できるようになります。そして上位オブジェクトの指定が無ければ、データベースオブジェクトは、規定のワークスペースの下位オブジェクトとして扱われるのです。
そして自分自身のデータベースにはCurrentDBという予約語が割り振られます。データベースはコンテナですから他のAccessデータベースを開いてデータベースオブジェクトを追加することができます。そしてA1で説明したように、そのデータベースの中のデータベースオブジェクトに含まれるオブジェクト、プロパティにアクセスできるようになります。

Dim DB as Database
Set DB = OpenDatabase("C:\AccessProgram\Test.mdb")

これをすべてのオブジェクトを書くと

Set DB = Application.DBEngine.WorkSpaces(0).OpenDatabase("C:\AccessProgram\Test.mdb")

と言うことですが、解説本にあるように省略形で書くことが普通です。

DBEngineは他のOfficeファミリでも使う事ができます。これを解説している本はそんなに多くはありません。HelpでApplicationオブジェクトを検索すると、ほんの少し載っています。

ではサンプルとしてExcelからデータベースオブジェクトを扱う方法を示します。

Dim MyAccess As Object
Dim MyDB As Object

Sub Auto_open()
On Error GoTo ERR_Auto_Open
 Set MyAccess = CreateObject("Access.application")
 Set MyDB = MyAccess.DBEngine.workspaces(0).Opendatabase(dbPath)
 Exit Sub
ERR_Auto_Open:
 MsgBox DBPath & "のAccessを開けることができません。"
End Sub

この例はExcelのワークブックのオープンでdbPathのデータベースを開いてデータベースオブジェクトMyDBを作成しています。

詳しく言うと、アプリケーションのオブジェクト変数MyAccessとデータベースオブジェクト変数MyDBを定義してAccess.Applicatioクラス名でアクセスのオブジェクトを作成します。この場合はAccessのように暗黙のワークスペースはありませんので、MyAccess.DBEngine.Workspaces(0)ワークスペースのOpenDatabaseメソッドを使ってMyDBのデータベースオブジェクトを作成します。これでMyDBを使ってAccessの中と同じようにデータベースオブジェクトを使うことができます。ExcelのVBAエディタで参照設定の中の”Miocrosoft Access 8.0 Object Libraly”と"Microsoft DAO 3.51 Object Library"にチェックを入れるのを忘れないようにしましょう。


A3:テーブルをコピーする。

AcsTbBkでは外部のAccessデータベースからテーブルをコピーをしています。手操作では

ファイル(F)−外部データの取り込み−インポート

の操作ですが、プログラムでそれを行うには2つの方法があります。1つはDoCmdオブジェクトのTansferDatabaseメソッドを使う方法と、SQLでテーブル作成Queryを実行する方法です。DoCmdを使う方が一般的です。

DoCmdとはAoolicationオブジェクトの子オブジェクトでAccessのメニュー、ツールバーの処理の実行に使われているオブジェクトです。手操作やマクロを構成する基本単位のアクションを実行できます。

Application−DoCmd

ではテーブルをコピーするには

DoCmd.TransferDataBase acImport,"Microsoft Access",DBPath,acTable,inTableName,OutTableName

DBPathはコピーするデータベースのフルパスが必要です。
さらに、acImportをacExportにすればコピーの向きが逆になりますし、acTableをacQueryにすればクエリーをコピーできます。HelpをTransferDatabaseで検索すればもっとパラメータの詳しい情報が得られ、これ以外にもいろいろな事ができることが判ると思います。
SQLで行う方法は別途説明する予定です。


A4:AccessからExcelを使う

まず、参照設定で”Microsoft Excel 8.0 Object Library”のチェックが入っているかを確認しておきましょう。

簡単に言えば、ExcelのApplicationオブジェクトを作成すれば、Applicationオブジェクトが持つすべてのメソッド、プロパティを扱えるようになります。

ではExcelのApplicationオブジェクトをAccessから作成するにはどうすればよいのでしょうか?Excel内ではExcelのApplicationは既に暗黙に指定されていますので、解説本ではあまり解説されていません。ExcelのVBAのHelpをApplicationオブジェクトで検索しても、少し説明してありますが、ちょっと混乱するような書き方がしてあります。
理解しやすいように素直に書くと、Excelのクラス名でオブジェクトを作成すればよいのです。作成されたオブジェクトはVisibleプロパティがFalseですので表示させるにはTrueを設定する必要があります。

Dim MyExcell as Object
MyExcel = CreateObject("Excel.Application")
MyExcel.Visible = True

MyExcelを作成するにはCreateObjectの代わりにNewを使うこともできます。

Set MyExcel = New Excel.application

これでMyExcelはExcelのApplicationオブジェクトになりますのでMyExcelを指定すればExcelの中に居るようにExcelを扱えるようになります。たとえば作成済みのExcelファイルのフルパスをMyBookPathとして、それを開くには

Dim MyWorkBook as Object
Set MyWorkBook = MyExcel.WorkBooks.Open(MyBookPath)

新しいExcelのBookを作成するには

Set MyWorkBook = MyExcel.WorkBooks.Add

となります。MyExcelのオブジェクトを指定するだけで後はすべて同じに扱えます。まさにオブジェクト指向プログラミングの御蔭です。v(^.^)v

終了したら MyExcel.Quit  を忘れずに。


A5:テーブルを入れ替える

A3でテーブルをコピーする方法は説明しましたが、拙作AcsTbBkにはバックアップしたテーブルをリストアする処理があります。リストアするにはリストア先のテーブルを削除して、バックアップしたテーブルを送り込まなければなりません。

テーブル等のオブジェクトを削除したり、転送するにはDocmdオブジェクトのDeleteObject、TransferDatabaseメソッドでできますが、リストア先のデータベースのDoCmdオブジェクトを使うのは少々面倒な問題(別の機会に紹介します)があり、データベースオブジェクトとSQLで実行するスマートな方法を紹介します。

データベースオブジェクトにはSQLを実行するExecuteという強力なメソッドがあります。引数にはSQLを文字列として設定します。

 DB.Execute ”SQL文”

リストア先のデータベースオブジェクトはデータベースのフルパスをRestoreDbPathとして、

 Dim DB as Database
 Set DB = OpenDatabase(RestoreDbPath)

で得られます。自分のデータベースオブジェクトはCurrentDbです。入れ替えるには2つの方法があります。ひとつはリストア先のテーブルを消去して、バックアップテーブルをコピーする方法とテーブルのデータを消してデータを転送する方法です。リストア先のテーブル名をTargetTb、バックアップされたテーブル名をBackUpTbとして

テーブルを消去転送する方法は、

 DB.Tabledefs.Delete "TargetTb"
 DB.Execute "Select * into TargetTb from BackUpTb in '" & CurrentDb.Name & "'"

2行目はCurrentDbで書くこともできます。

 CurrentDb.Execute "Select * into TargetTb in '" & RestoreDbPath & "' from BackUpTb"

1行目がTabledefsオブジェクトのDeleteメソッドを使ってテーブルを削除、2行目がテーブルを作成するSQLです。では2番目の方法は

 DB.Execute "delete from TagetTb"
 DB.Execute "insert into TargetTb select * from BackUpTb in '" & CurrentDb.name & "'"

1,2行ともCurrentDbを使うこともできます。

 CurrentDb.Execute "Delete from TargetTb in '" & RetoreDbPath & "'"
 CurrentDb.Execute "insert into TargetTb in '" & RestoreDbPath & "' select * from BackUpTb"

1行目がデータを削除、2行目がデータを転送するSQLです。


Back Home Next


Copy Right 2001- Ken