クラスの見直し_3(ExcelでRDBその26)

ExcelRDB(リレーショナルデータベース)を操作してみようという連載のその26です。前回の記事はこちらです。

hirocom777.hatenadiary.org

参照先カラム名の取得

前回まででデータ入力ツールの開発は、終了です。お疲れ様でした。

その際にクラスモジュールに機能を追加しました。外部キーが参照しているテーブルのカラムにアクセスする必要があったんです。今回はその部分の解説です。

修正点の解説

前回の見直しで、ADOXを取り込んでテーブルが決定した場合にテーブルの各カラムのキー情報(キーのタイプとリレーションテーブル名)をプロパティーで取得できるようにしました。今回はさらにリレーションテーブルのリレーションカラム名を取得できるようにしました。まず、冒頭にリレーションカラムのプロパティー(dbRelatedColumn_)を設定しました。

Option Explicit
'Accessファイルのデータベースコントロールのクラスです

Private dbFileName_ As String 'データベースファイル名
Private dbTableList_() As Variant 'テーブルリスト
Private dbTrans_ As Boolean 'トランザクション状態

Private dbTableName_ As String 'テーブル名

Private dbFieldList_() As Variant 'フィールドリスト
Private dbFieldType_() As Variant 'フィールドタイプ
Private dbKeyType_() As Variant 'キータイプ
Private dbRelatedTable_() As Variant 'リレーションテーブル
Private dbRelatedColumn_() As Variant 'リレーションカラム(追加部分)

Private adoCn As New ADODB.Connection
Private adoRs As New ADODB.Recordset
Private adoSelectRs As New ADODB.Recordset
Private catalogObject As New ADOX.Catalog

次にテーブルプロパティーを設定したときにリレーションカラムのプロパティーを設定するようにしました。

'テーブル名を設定します
Public Property Let dbTableName(ByVal tableName As String)
Dim keyObject As Object
Dim columnObject As Object
Dim i As Long
  If Dir$(dbFileName_) = "" Then
    MsgBox "データベースファイルを指定してください"
    Exit Property
  End If
  'テーブル変更時の処理
  If dbTableName_ <> "" Then
    Me.dbTrans = False
    If adoRs.State = adStateOpen Then adoRs.Close
    If adoSelectRs.State = adStateOpen Then adoSelectRs.Close
  End If
  'レコードセットオジェクトを開きます
  adoRs.Open tableName, adoCn, adOpenKeyset, adLockOptimistic
  dbTableName_ = tableName
  'フィールドリストを設定します
  ReDim dbFieldList_(adoRs.Fields.Count - 1)
  ReDim dbFieldType_(adoRs.Fields.Count - 1)
  For i = 0 To adoRs.Fields.Count - 1
    dbFieldList_(i) = adoRs.Fields(i).Name
    dbFieldType_(i) = adoRs.Fields(i).Type
  Next
  'キー情報を取得します
  ReDim dbKeyType_(adoRs.Fields.Count - 1)
  ReDim dbRelatedTable_(adoRs.Fields.Count - 1)
  ReDim dbRelatedColumn_(adoRs.Fields.Count - 1)
  For Each keyObject In catalogObject.Tables(tableName).Keys
    For Each columnObject In keyObject.Columns
      For i = 0 To adoRs.Fields.Count - 1
        If dbFieldList_(i) = columnObject.Name Then
          dbKeyType_(i) = keyObject.Type
          dbRelatedTable_(i) = keyObject.RelatedTable
          dbRelatedColumn_(i) = columnObject.RelatedColumn(追加部分)
          Exit For
        End If
      Next
    Next
  Next
End Property

ややこしいのは、リレーションカラム名の情報はキーオブジェクトの下にうるカラムオブジェクトの下のRelatedColumnに格納されているということです。テーブル名と一緒にキーオブジェクトの直下においてくれればいいのに・・・

そして、カラム名を取得できるようにしておきます。

'リレーションカラムを取得します
Public Property Get dbRelatedColumn() As Variant
  dbRelatedColumn = dbRelatedColumn_
End Property

以上が今回の修正です。クラスモジュールを使ってスマートに機能追加できました。

次回はインデックス

いかがでしょうか?ここまで通してキーの関係やリレーションなど色々学ぶことができました。次回はインデックスです。今まで学んだことを応用してインデックスの内容に迫りたいと思います。お楽しみに!!

hirocom777.hatenadiary.org

ExcelVBAでAccessファイルを操作する連載はコチラから