Excel VBAでオブジェクト指向プログラミング(ADO編)
■ActiveX Data Objects(ADO)とは
ActiveX Data Objects(ADO)はMicrosoftから提供されている、データベースへのアクセスに特化したオブジェクトで、さまざまなデータベースに対応していることが最大の特徴です。
Microsoftのドキュメントには「Microsoft ActiveX データオブジェクト (ADO) を使用すると、クライアントアプリケーションは、OLE DB プロバイダーを介してさまざまなソースからのデータにアクセスして操作できます」と記載されており、データベースに接続した後は、データベースの種類を意識することなく、共通のインターフェースで操作できます。
⇒詳細はMicrosoftのサイト(ActiveX Data Objects (ADO))を参照して下さい。
ADOのオブジェクト
ADOに含まれるオブジェクトは下表の通りですが、本稿ではConnectionオブジェクトとRecordsetオブジェクトに絞って説明します。
オブジェクト | 説明 | ||||||
---|---|---|---|---|---|---|---|
Connectionオブジェクト | データソースとの固有のセッション | ||||||
Errorsコレクション | Errorオブジェクトの集合体 | ||||||
Errorオブジェクト | データアクセスエラーの詳細情報を格納 | ||||||
Propertiesコレクション | Propertyオブジェクトの集合体 | ||||||
Propertyオブジェクト | ADOオブジェクトの動的特性(プロパティ) | ||||||
Commandオブジェクト | データソースに対して実行する特定のコマンド | ||||||
Parametersコレクション | Parameterオブジェクトの集合体 | ||||||
Parameterオブジェクト | Commandオブジェクトに関連付けられたパラメータ | ||||||
Propertiesコレクション | Propertyオブジェクトの集合体 | ||||||
Propertyオブジェクト | ADOオブジェクトの動的特性(プロパティ) | ||||||
Recordsetオブジェクト | データ操作の対象となるレコードの集合体 | ||||||
Fieldsコレクション | Fieldオブジェクトの集合体 | ||||||
Fieldオブジェクト | レコードに含まれる1つの列 | ||||||
Propertiesコレクション | Propertyオブジェクトの集合体 | ||||||
Propertyオブジェクト | ADOオブジェクトの動的特性(プロパティ) | ||||||
Recordオブジェクト | レコードセットに含まれる1つの行 | ||||||
Fieldsコレクション | Fieldオブジェクトの集合体 | ||||||
Fieldオブジェクト | レコードに含まれる1つの列 | ||||||
Streamオブジェクト | バイナリ データまたはテキストのストリーム |
■Connectionオブジェクトとは
Connectionオブジェクトは、データソースとの接続に関するオブジェクトで、提供されているメソッドおよびプロパティは以下の通りです。
Connectionオブジェクトのメソッド
項目 | 説明 |
---|---|
BeginTransメソッド | 新しいトランザクションを開始する |
Cancelメソッド | 非同期メソッド呼び出しの実行を終了する |
Closeメソッド | 開いているオブジェクトを閉じる |
CommitTransメソッド | 変更を保存し、現在のトランザクションを終了する |
Executeメソッド | クエリやストアドプロシジャを実行する |
Openメソッド | データソースへの接続を開く |
OpenSchemaメソッド | データベースに関するスキーマ情報を取得する |
RollbackTransメソッド | 変更を取消し、トランザクションを終了する |
Connectionオブジェクトのプロパティ
項目 | 説明 |
---|---|
Attributesプロパティ | オブジェクトの特性を設定/取得 |
CommandTimeoutプロパティ | コマンド実行中のタイムアウト時間を設定/取得 |
ConnectionStringプロパティ | データソースへの接続を確立するための情報を設定/取得 |
ConnectionTimeoutプロパティ | データソースへの接続時のタイムアウト時間を設定/取得 |
CursorLocationプロパティ | カーソルサービスの場所(位置)を設定/取得 |
DefaultDatabaseプロパティ | 既定のデータベースを設定/取得 |
Errorsプロパティ | Errorsコレクションを取得 |
IsolationLevelプロパティ | 分離レベルを設定/取得 |
Modeプロパティ | アクセスモードを設定/取得 |
Propertiesプロパティ | Propertiesコレクションを取得 |
Providerプロパティ | プロバイダ名を設定/取得 |
Stateプロパティ | 非同期メソッド実行時の状態を取得 |
Versionプロパティ | ADOのバージョン番号を取得 |
■Recordsetオブジェクトとは
Recordsetオブジェクトは、レコードセット(レコード(行)の集合)を扱うオブジェクトで、提供されているメソッドおよびプロパティは以下の通りです。
Recordsetオブジェクトのメソッド
項目 | 説明 |
---|---|
AddNewメソッド | 新しいレコードを作成する |
Cancelメソッド | 保留中の非同期メソッド呼び出しの実行を取消す |
CancelBatchメソッド | 保留中のバッチ更新をキャンセルする |
CancelUpdateメソッド | レコードの変更をキャンセルする |
Cloneメソッド | Recordsetオブジェクトの複製を作成する |
Closeメソッド | 開いているオブジェクトを閉じる |
CompareBookmarksメソッド | 2つのブックマークを比較し、相対的な位置を返す |
Deleteメソッド | レコードを削除する |
Findメソッド | 指定した条件を満たす行を検索する |
GetRowsメソッド | 複数のレコードを配列に取り込む |
GetStringメソッド | Recordsetを文字列として返す |
Moveメソッド | カレントレコードの位置を移動する |
MoveFirstメソッド | 最初のレコードをカレントレコードにする |
MoveLastメソッド | 最後のレコードをカレントレコードにする |
MoveNextメソッド | 次のレコードをカレントレコードにする |
MovePreviousメソッド | 前のレコードをカレントレコードにする |
NextRecordsetメソッド | 次のRecordsetを返す |
Openメソッド | カーソルを開く |
Requeryメソッド | クエリを再実行する |
Resyncメソッド | 基になるデータベースのデータで更新する |
Saveメソッド | Recordsetを保存する |
Seekメソッド | インデックスを検索し、一致する行をカレント行にする |
Supportsメソッド | 特定の種類の機能をサポートしているかどうかを調べる |
Updateメソッド | レコードの変更を保存する |
UpdateBatchメソッド | 保留中の一括更新を全てディスクに書き込む |
Recordsetオブジェクトのプロパティ
項目 | 説明 |
---|---|
AbsolutePageプロパティ | カレントレコードのページを設定/取得 |
AbsolutePositionプロパティ | カレントレコードの位置を設定/取得 |
ActiveCommandプロパティ | Recordsetオブジェクトを作成したCommandオブジェクトを取得 |
ActiveConnectionプロパティ | Connectionオブジェクトを設定/取得 |
BOFプロパティ | カレントレコードの位置が最初のレコードより前にあることを示す |
Bookmarkプロパティ | ブックマークを設定/取得 |
CacheSizeプロパティ | ローカルメモリにキャッシュされるレコード数を設定/取得 |
CursorLocationプロパティ | カーソルサービスの場所(位置)を設定/取得 |
CursorTypeプロパティ | カーソルの種類を設定/取得 |
DataMemberプロパティ | データメンバーの名前を設定/取得 |
DataSourceプロパティ | Recordsetオブジェクトを取得 |
EditModeプロパティ | レコードの編集ステータスを取得 |
EOFプロパティ | カレントレコードの位置が最後のレコードより後にあることを示す |
Fieldsプロパティ | Fieldsコレクションを取得 |
Filterプロパティ | フィルターを設定/取得 |
Indexプロパティ | インデックスを設定/取得 |
LockTypeプロパティ | レコード編集時のロックの種類を設定/取得 |
MarshalOptionsプロパティ | サーバーにマーシャリングされるレコードを設定/取得 |
MaxRecordsプロパティ | クエリからRecordsetに返す最大レコード数を設定/取得 |
PageCountプロパティ | Recordsetオブジェクトに含まれるデータのページ数を取得 |
PageSizeプロパティ | 1ページを構成するレコード数を設定/取得 |
Propertiesプロパティ | Propertiesコレクションを取得 |
RecordCountプロパティ | Recordsetオブジェクト内のレコード数を取得 |
Sortプロパティ | ソートに使用するフィールド名、順序を設定/取得 |
Sourceプロパティ | データソースを設定/取得 |
Stateプロパティ | オブジェクトの状態を取得 |
Statusプロパティ | 一括更新時、現在のレコードのステータスを取得 |
StayInSyncプロパティ | 階層的なRecordsetオブジェクトで、親行の位置が変更された場合に基になる子レコード(チャプター)への参照が変更されるかどうかを示す |
■ADOを使用するための事前準備
ADOを使用するための事前準備は、以下の3ステップです。
⇒オブジェクトを使用するための事前準備とオブジェクトブラウザによる調査方法については、Excel VBAでオブジェクト指向プログラミング(事前準備編)を参照して下さい。
①ライブラリの参照設定
Visual Basic Editor(VBE)のファイルメニューから[ツール]-[参照設定]を選択し、参照設定ダイアログでMicrosoft ActiveX Data Objects x.x Libraryのチェックボックスにチェックを入れ、[OK]ボタンを押下。
(補足説明)
『x.x』の部分だけ異なる項目が複数表示されます。
筆者は深く考えずに一番数字の大きいものを選んでいますが、Microsoftのドキュメントを見ると、ADOとWindowsの対応関係が下表のようになっているようなので、Windowsのバージョンに合ったライブラリを選択するのが本来の姿かと思います。
ADOのバージョン | Windowsのバージョン |
---|---|
ADO 2.8 | Windows XP |
ADO 6.0 | Windows Vista |
ADO 6.1 | Windows 7 |
②オブジェクト変数の定義
プログラムの宣言部でオブジェクト変数を定義。
- Dim cn, rs As Object
③インスタンスの生成
プログラムの処理部でインスタンスを生成。
- Set cn = New ADODB.Connection
- Set rs = New ADODB.Recordset
- 'ここにADOを使用した処理を記述
- Set rs = Nothing
- Set cn = Nothing
(参考)「Set cn = New ADODB.Connection」の部分を「Set cn = CreateObject(“ADODB.Connection")」、「Set rs = New ADODB.Recordset」の部分を「Set rs = CreateObject(“ADODB.Recordset")」と記述すれば、ステップ①(ライブラリの参照設定)は不要です。
■ADOの使用方法
ADOでデータソースに接続し、データソースからレコードを読み出す処理について、詳細な手順を説明します。
データソースへの接続
ConnectionオブジェクトのOpenメソッドを実行し、データソースに接続します。
引数として指定する「接続文字列(Connection String)」の中には色々な項目がありますが、必須項目はProviderとData Sourceの2つです。
- cn.Open “Provider=プロバイダ名;Data Source=’データソースのパス’;"
プロバイダ名はデータソースの種類毎に決っており、主なものは下表の通りです。
データソースの種類 | プロバイダ名 |
---|---|
Access | Microsoft.ACE.OLEDB.12.0 |
Excel | Microsoft.ACE.OLEDB.12.0(※1) |
CSV | Microsoft.ACE.OLEDB.12.0(※2) |
SQL Server | SQLOLEDB |
Oracle | OraOLEDB.Oracle |
(※1)「Extended Properties="Excel 12.0;HDR=Yes;IMEX=1″」のような記述を追加要。
(※2)「Extended Properties="text;HDR=Yes;FMT=Delimited"」のような記述を追加要。
レコードの読み出し
さまざまな方法がありますが、RecordsetオブジェクトのOpenメソッドおよびExecuteメソッドでSQL(SELECT文)を使用した例を次項で紹介します。
RecordsetオブジェクトのOpenメソッドによる読み出し
ExcelシートのA列に格納された氏名を基に、Accessの住所録を検索し、ExcelシートのB列に郵便番号、C列に住所をセットするツールです。
行番号10でRecordsetオブジェクトのOpenメソッドにSQLを指定し、SELECT文のWHERE句で条件式を指定しています。
引用符が入れ子になっていてわかり難いですが、WHERE句の部分は『WHERE 氏名=’○□ △☆’』といった形式です。
- Dim sht, cn, rs As Object
- Dim i As Integer
- Private Sub Sample1()
- Set sht = ActiveSheet
- Set cn = New ADODB.Connection
- cn.Open “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=’C:\work\住所録.mdb’;"
- Set rs = New ADODB.Recordset
- For i = 1 To sht.Cells(sht.Rows.Count, 1).End(xlUp).Row
- rs.Open “SELECT 氏名,郵便番号,住所 from 住所録 WHERE 氏名='" & sht.Cells(i, 1) & “'", cn, adOpenKeyset, adLockReadOnly
- If rs.EOF = False Then
- sht.Cells(i, 2) = rs.Fields(“郵便番号")
- sht.Cells(i, 3) = rs.Fields(“住所")
- End If
- Next i
- Set rs = Nothing
- cn.Close
- Set cn = Nothing
- End Sub
RecordsetオブジェクトのExecuteメソッドによる読み出し
単純にAccessの住所録を全件読み出し、Excelシートに出力するツールです。
行番号8でRecordsetオブジェクトのExecuteメソッドにSQLを指定し、全レコードを読み出しています。
行番号9はExcelの機能で、RangeオブジェクトのCopyFromRecordsetメソッドを使用しています。
- Dim sht, cn, rs As Object
- Private Sub Sample2()
- Set sht = ActiveSheet
- Set cn = New ADODB.Connection
- cn.Open “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=’C:\work\住所録.mdb’;"
- Set rs = New ADODB.Recordset
- Set rs = cn.Execute(“SELECT 氏名,郵便番号,住所 FROM 住所録")
- sht.Cells(1, 1).CopyFromRecordset rs
- Set rs = Nothing
- cn.Close
- Set cn = Nothing
- End Sub
ADOXを使用してテーブルとフィールドの一覧を表示するExcelツール
ADOX(ActiveX Data Objects Extensions for Data Definition Language and Security)はMicrosoftから提供されている、「ADOのオブジェクトとプログラミングモデルを拡張した」オブジェクトです。
⇒詳細はMicrosoftのサイト(ADOX(ActiveX Data Objects Extensions for Data Definition Language and Security))を参照して下さい。
ここではデータベースとフィールドの一覧を表示するためのサンプルプログラムをご紹介します。
①ライブラリの参照設定
Visual Basic Editor(VBE)のファイルメニューから[ツール]-[参照設定]を選択し、参照設定ダイアログで
Microsoft ADO Ext. x.x for DDL and Securityのチェックボックスにチェックを入れ、[OK]ボタンを押下。
(参考)サンプル・プログラムの行番号10「Set ct = New ADOX.Catalog」の部分を「Set ct = CreateObject(“ADOX.Catalog")]と記述すれば、ライブラリの参照設定は不要です。
②サンプル・プログラム
行番号13でCatalogオブジェクトのTablesプロパティでTablesコレクションを取得し、行番号15でTableオブジェクトのNameプロパティでテーブル名を取得しています。
また、行番号18でRecordsetオブジェクトのFieldsプロパティでFieldsコレクションを取得し、行番号19でFieldオブジェクトのNameプロパティでフィールド名を取得しています。
- Dim sht, ct, cn, rs, t, f As Object
- Dim strSQL As String
- Dim i As Integer
- Private Sub Sample3()
- Set sht = ActiveSheet
- Set cn = New ADODB.Connection
- cn.Open “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=’C:\work\住所録.mdb’;"
- Set ct = New ADOX.Catalog
- ct.ActiveConnection = cn
- Set rs = New ADODB.Recordset
- i = 1
- For Each t In ct.Tables
- If t.Type = “TABLE" Then
- sht.Cells(i, 1) = t.Name
- strSQL = “SELECT * FROM " & sht.Cells(i, 1)
- Set rs = cn.Execute(strSQL)
- For Each f In rs.Fields
- sht.Cells(i, 2) = f.Name
- i = i + 1
- Next f
- End If
- Next t
- Set rs = Nothing
- Set ct = Nothing
- cn.Close
- Set cn = Nothing
- End Sub
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ
ディスカッション
コメント一覧
まだ、コメントがありません