【入門編】CurrentDb.Containersを活用したデータベース内のオブジェクト権限と所有者の管理 – Access VBA解析バイブル

スポンサーリンク

こんにちは! Access VBAの開発現場で、日々頭を悩ませていませんか?

「マクロの記録」ボタンをポチポチ押していた時代から一歩進んで、本格的なデータベース構築の世界へようこそ。ここをクリアすれば、あなたも立派なAccessプロフェッショナルです。

今回は、Accessの裏側でうごめく「オブジェクトの所有者と権限」を、DAO(Data Access Objects)の`CurrentDb.Containers`を使って美しく安全に監査する方法を伝授します。

システムテーブル(`MSysObjects`など)を直接叩くような野暮な真似はしません。公式が用意したエレガントな作法で、データベースのセキュリティを完全に掌握しましょう。ここをクリアすれば、Accessのオブジェクトモデルの基本はバッチリですよ!

なぜ `CurrentDb.Containers` なのか?

Access(Jet/ACEエンジン)の中身を覗き見るとき、初心者はつい `MSysObjects` というシステムテーブルをSQLでクエリしようとします。

しかし、ちょっと待ってください。
システムテーブルを直接触る行為は、Access界の「パンドラの箱」を開けるようなもの。バージョンアップで構造が変わるリスクがありますし、何よりセキュリティコンテキストの観点から推奨されません。

そこで登場するのが DAOの `Containers` コレクション です。

Accessデータベース内にある「テーブル(Tables)」「クエリ(QueryDefs)」「フォーム(Forms)」などのオブジェクト群は、それぞれ 「コンテナ(Container)」 という概念で綺麗に整理されています。このコンテナをVBAから巡回(ループ)させることで、各オブジェクトの「所有者(Owner)」や「アクセス権」を安全かつ確実に取得できるのです。

データベースの権限・所有者一覧を出力する実用コード

それでは早速、現在のデータベース内にある全テーブルとフォームの「所有者」をイミディエイトウィンドウにズラリと出力するスクリプトを見てみましょう。

開発画面(VBAエディタ)の標準モジュールに、以下のコードを貼り付けて実行してみてください。

Option Explicit

‘ =========================================================================
‘ プロシージャ名: AuditDatabaseOwners
‘ 概要: Containersコレクションを走査し、オブジェクトの所有者を監査する
‘ =========================================================================
Public Sub AuditDatabaseOwners()
Dim dbs As DAO.Database
Dim cnt As DAO.Container
Dim doc As DAO.Document

‘ 常に現在のデータベースを安全に指し示すCurrentDbを使用する
Set dbs = CurrentDb

Debug.Print “=== データベース オブジェクト所有者 監査レポート ===”

‘ 監査したいコンテナのリスト(今回はテーブルとフォームを例に)
‘ ※ Containersの主な種類: “Databases”, “Tables”, “Forms”, “Reports”, “Modules”
Dim targetContainers As Variant
targetContainers = Array(“Tables”, “Forms”)

Dim i As Long
For i = LBound(targetContainers) To UBound(targetContainers)

‘ 指定したコンテナが存在するか安全にチェックして取得
On Error Resume Next
Set cnt = dbs.Containers(targetContainers(i))
On Error GoTo 0

If Not cnt Is Nothing Then
Debug.Print vbCrLf & “【コンテナ名: ” & targetContainers(i) & “】”

‘ コンテナ内の個々のドキュメント(実際のテーブルやフォーム)を走査
For Each doc In cnt.Documents
Debug.Print ” – オブジェクト名: ” & doc.Name & ” / 所有者: ” & doc.Owner
End For
End If

Set cnt = Nothing
Next i

Debug.Print vbCrLf & “=== 監査完了 ===”
End Sub

コードのここが重要!

1. `CurrentDb` の正しい作法
コード内で `CurrentDb` を変数(`dbs`)に受けている点に注目してください。
実は `CurrentDb` を呼び出すたびに、Accessの内部では新しいデータベースオブジェクトのインスタンスが生成されます。ループの条件式などで直接 `CurrentDb.Containers(…)` と書くと、メモリリークや予期せぬパフォーマンス低下、さらにはポインタのズレによるエラーの原因になります。一度変数に格納してから使うのが、プロのエンジニアの鉄則です。

2. Container と Document の違い

  • Container(コンテナ): 「テーブル」や「フォーム」といったカテゴリの箱そのものです。
  • Document(ドキュメント): その箱の中に入っている個々の具体的なオブジェクト(例: `T_顧客マスタ` や `F_入力画面`)を指します。

この階層構造を理解していると、Accessのオブジェクトモデルは怖くありません。

陥りやすいエラーと初心者がハマる罠

このコードを書いて動かすとき、いくつかの「罠」に遭遇することがあります。先輩エンジニアからのアドバイスとして、事前に頭に入れておきましょう。

1. 「実行時エラー ‘3265’: 項目が見つかりません。」

  • 原因: 指定したコンテナ名が間違っている、またはシステム上アクセスできないコンテナを指定しています。
  • 対策: コンテナ名は正確に指定する必要があります(例: テーブルは `”Tables”` ですが、クエリは独立したコンテナではなく `”Tables”` の中に含まれています)。上記のサンプルコードのように、`On Error Resume Next` で安全にトラップするか、存在するコンテナ名だけを対象にしましょう。

2. 「システムテーブル(MSys…)が表示されない?」

  • 原因: `Containers(“Tables”)` で取得できるのは、ユーザーが作成したテーブルだけではありませんが、Accessのセキュリティモデルや隠し属性によってフィルタリングされる場合があります。
  • 対策: あくまで権限や所有者の管理・監査を目的とする場合、システム内部の管理用オブジェクトはいじる必要がほとんどありません。ビジネスロジックに必要なユーザーオブジェクトに絞って監査するのが安全です。

まとめ

今回は `CurrentDb.Containers` を使った、データベースのセキュリティ情報(所有者)の安全な取得方法について解説しました。

  • システムテーブルを直接叩くのは御法度。DAOを介して安全にアクセスする。
  • `CurrentDb` は必ず変数に格納して使い回す(パフォーマンスと安定性の鉄則)。
  • Container(箱)と Document(中身)の階層構造を意識する。

この基本さえ押さえておけば、Accessの裏側で何が起きているのかを完全に把握できるようになります。マクロの記録だけでは見えなかったAccessの深淵をコントロールできたときの快感は、エンジニアにとって格別なものです。

ぜひ、あなたの開発現場のセキュリティ監査やドキュメント自動生成ツールに応用してみてくださいね。それでは、また次の知見でお会いしましょう!

タイトルとURLをコピーしました