ExcelVBA-Excelファイルをデータベースとして使う-その10です。 前回の記事はこちらになります。
hirocom777.hatenadiary.org
メソッドを追加
折角作成したクラスモジュールですが、今のところ出来ることはデータの追加だけ。もっとほかの機能も盛り込みたいところです。簡単に機能追加できるのはクラスの良いところ(だと勝手に思っている)ですからね。さて、どういう機能を追加しましょうか・・・
検索機能
とりあえず、SQLを使った検索機能をつけましょう。その3で作ったプロシージャを参考に作ればいいですかね。以下のようなコードでした。
Public Function SelectRecord(strFileName As String, strSQL As String, Optional rngRange As Range = Nothing) As Long On Error GoTo HrrorHandler Dim adoCn As Object Set adoCn = CreateObject("ADODB.Connection") With adoCn .Provider = "Microsoft.ACE.OLEDB.12.0" .Properties("Extended Properties") = "Excel 12.0" .Open strFileName End With Dim adoRs As Object Set adoRs = CreateObject("ADODB.Recordset") adoRs.CursorLocation = adUseClient adoRs.Open strSQL, adoCn If Not rngRange Is Nothing Then rngRange.CopyFromRecordset adoRs SelectRecord = adoRs.RecordCount adoRs.Close adoCn.Close HrrorHandler: If Err.Number <> 0 Then MsgBox "データベース接続に失敗しました" End Function
う、このプロシージャでは Recordsetオブジェクトを開く際にSQLコマンドを指定していますね。前回作ったクラスモジュールでは初期化(Class_Initialize)時に Recordsetオブジェクトを開いてしまっています。これではSQLコマンドが指定できません。困りましたね・・・
Recordsetオブジェクトを追加する
そこで、検索用のRecordsetオブジェクトを追加しようと思います。具体的な変更内容は以下の通りです。
・検索用のRecordsetオブジェクトを追加
・初期化(Class_Initialize)時にCreateObject("ADODB.Recordset")をセット
・検索メソッドを追加する。
・検索メソッド内でSQL文とConnectionオブジェクトを指定してオープンする
検索メソッドでは、SQL文とConnectionオブジェクトを指定してオープンします。引数に設定するSQLコマンドですがテーブル名はクラスモジュールのプロパティーとして設定してあるのでWHERE句の後のみとします。また、先のプロシージャにあった指定したたRangeを起点に取得したRecordsetを表示できる機能も残しておきましょう。
変更後のクラスモジュール
と、言う訳で変更後のクラスモジュールは以下になります。(2021/1/11修正しました)
Option Explicit 'Excelファイルのデータベースコントロールのクラスです。 Private dbFileName_ As String 'データベースファイル名 Private dbTableName_ As String 'テーブル名 Private dbFieldList_() As Variant 'フィールドリスト Private adoCn As Object Private adoRs As Object Private adoSelectRs As Object '初期化 Private Sub Class_Initialize() Set adoCn = CreateObject("ADODB.Connection") adoCn.Provider = "Microsoft.ACE.OLEDB.12.0" adoCn.Properties("Extended Properties") = "Excel 12.0" Set adoRs = CreateObject("ADODB.Recordset") adoRs.CursorLocation = adUseClient Set adoSelectRs = CreateObject("ADODB.Recordset") adoSelectRs.CursorLocation = adUseClient End Sub '終了処理 Private Sub Class_Terminate() If Err.Number <> 0 Then MsgBox "データベース接続に失敗しました-" & Err.Number If dbTableName_ <> "" Then adoCn.RollbackTrans Else adoCn.CommitTrans End If If adoRs.State = adStateOpen Then adoRs.Close If adoSelectRs.State = adStateOpen Then adoSelectRs.Close If adoCn.State = adStateOpen Then adoCn.Close End Sub 'ファイル名を設定します Public Property Let dbFileName(ByVal fileName As String) Select Case True Case dbFileName_ <> "" MsgBox "ファイル名は途中で変更できません" Case Dir$(fileName) = "" MsgBox "ファイルが見つかりません" Case Else dbFileName_ = fileName End Select End Property 'ファイル名を取得します Public Property Get dbFileName() As String dbFileName = dbFileName_ End Property 'テーブル名を設定します Public Property Let dbTableName(ByVal tableName As String) Select Case True Case Dir$(dbFileName_) = "" MsgBox "データベースファイルを指定してください" Case dbTableName_ <> "" MsgBox "テーブル名は途中で変更できません" Case Else adoCn.Open dbFileName_ adoRs.Open "[" & tableName & "$]", adoCn, adOpenKeyset, adLockOptimistic dbTableName_ = tableName adoCn.BeginTrans 'フィールドリストを取得します Dim adoField As ADODB.Field Dim i As Long ReDim dbFieldList_(adoRs.Fields.Count - 1) For i = 0 To UBound(dbFieldList_) dbFieldList_(i) = adoRs.Fields.Item(i).Name Next End Select End Property 'テーブル名を取得します Public Property Get dbTableName() As String dbTableName = dbTableName_ End Property 'フィールドリストを取得します Public Property Get dbFieldList() As Variant dbFieldList = dbFieldList_ End Property 'Excelデータベースにレコードを追加します Public Sub AddRecord(recordData() As Variant) adoRs.AddNew dbFieldList_, recordData adoRs.Update End Sub 'SQLのWHERE句指定でレコードを抽出して指定のセルに表示します Public Function SelectRecord(cmdSql As String, Optional foundRecord As Range = Nothing) As Long adoSelectRs.Open "SELECT * FROM [" & dbTableName_ & "$] WHERE " & cmdSql, adoCn If Not foundRecord Is Nothing Then foundRecord.CopyFromRecordset adoSelectRs SelectRecord = adoSelectRs.RecordCount adoSelectRs.Close End Function
動かしてみる
それでは動かしてみましょう。まず、上記クラスモジュールを実装したExcelファイルを用意します。からのシートモジュールには以下のコードを入力してください。
Option Explicit 'zenkoku.xlsxから静岡県のデータを取り出す(ADO_Class版) Sub ADO_Class_Test() Dim sqlCmd As String Debug.Print Now Dim db As clsExcelDbase Set db = New clsExcelDbase db.dbFileName = ThisWorkbook.Path & "\zenkoku.xlsx" db.dbTableName = "zenkoku" Me.Range(Me.Range("A1"), Me.Range("A1").Offset(0, UBound(db.dbFieldList))) = db.dbFieldList sqlCmd = "都道府県 = '静岡県' ORDER BY 郵便番号 ASC;" db.SelectRecord sqlCmd, Me.Range("A2") Debug.Print Now End Sub
このファイルと同じフォルダにその5で使用したzenkoku.xlsxファイルを配置してADO_Class_Testを実行してみてください。ちなみに、今回は郵便番号でソートしています。
hirocom777.hatenadiary.org
郵便番号でソートされた静岡県のデータがシートに表示されたと思います。大分実用的になってきたんじゃないでしょうか?
次回は、クラスモジュールをさらに実用的に改善していきます。お楽しみに!!
hirocom777.hatenadiary.org