Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!
Wenn Du per VBA auf eine Datenbank zugreifst, stellt sich manchmal die Frage: Welche Tabellen gibt es eigentlich? Welche Spalten hat eine bestimmte Tabelle und welche Datentypen verwenden diese? Gibt es Indizes oder Primärschlüssel? Die OpenSchema-Methode der Connection-Klasse aus der ADODB-Bibliothek liefert genau solche Metadaten – und zwar unabhängig davon, ob Du mit einer Access-Datenbank oder einem SQL Server arbeitest. In diesem Artikel zeigen wir, wie Du mit OpenSchema die Struktur einer Datenbank abfragen kannst. Dabei stellen wir die wichtigsten Schema-Typen vor und zeigen für jeden ein praktisches Beispiel.
Beispieldatenbank
Die Beispiele dieses Artikels findest Du in der Beispieldatenbank ADODB_OpenSchema.accdb. Diese enthält ein Modul mdlOpenSchema mit allen hier vorgestellten Prozeduren. Die Datenbank enthält außerdem einige Beispieltabellen, auf deren Struktur wir mit OpenSchema zugreifen.
Was ist OpenSchema?
OpenSchema ist eine Methode des Connection-Objekts von ADODB. Sie liefert ein Recordset zurück, das Metadaten über die Struktur der verbundenen Datenbank enthält. Das können Informationen über Tabellen, Spalten, Indizes, Primärschlüssel, gespeicherte Prozeduren und vieles mehr sein.
Der Aufruf sieht grundsätzlich so aus:
Dim rst As ADODB.Recordset Set rst = cnn.OpenSchema(SchemaTyp)
Der Parameter SchemaTyp ist ein Wert der Enumeration SchemaEnum. Dieser bestimmt, welche Art von Metadaten abgerufen wird.
Optional können wir einen zweiten Parameter Criteria übergeben, um die Ergebnisse einzuschränken – dazu kommen wir weiter unten.
Voraussetzungen
Für die Verwendung von OpenSchema benötigst Du einen Verweis auf die Bibliothek Microsoft ActiveX Data Objects 6.1 Library. Diesen fügst Du im VBA-Editor über Extras|Verweise hinzu (siehe Bild 1).

Bild 1: Verweis auf die ADODB-Bibliothek
Außerdem benötigst Du ein geöffnetes Connection-Objekt. Innerhalb einer Access-Datenbank kannst Du dafür einfach CurrentProject.Connection verwenden. Für eine Verbindung zum SQL Server erstellst Du ein eigenes Connection-Objekt mit der passenden Verbindungszeichenfolge, wie wir es im Artikel ADODB: Die Connection-Klasse (www.vbentwickler.de/446) beschrieben haben.
Übersicht der wichtigsten Schema-Typen
Die Enumeration SchemaEnum enthält eine große Anzahl von Konstanten. Die folgenden sind in der Praxis besonders relevant:
- adSchemaTables (20): Listet alle Tabellen und Sichten (Views) der Datenbank auf.
- adSchemaColumns (4): Liefert alle Spalten aller Tabellen mit Datentyp, Länge und weiteren Informationen.
- adSchemaIndexes (12): Zeigt alle Indizes der Datenbank mit den zugehörigen Spalten und Eigenschaften an.
- adSchemaPrimaryKeys (28): Liefert die Primärschlüssel aller Tabellen.
- adSchemaForeignKeys (27): Zeigt alle Fremdschlüsselbeziehungen zwischen den Tabellen.
- adSchemaProcedures (16): Listet gespeicherte Prozeduren auf. Bei Access sind dies die gespeicherten Abfragen.
- adSchemaViews (23): Zeigt die Sichten (Views) der Datenbank an.
In den folgenden Abschnitten stellen wir die wichtigsten dieser Schema-Typen mit je einem vollständigen Codebeispiel vor.
Tabellen einer Datenbank auflisten
Der wohl häufigste Anwendungsfall ist das Auflisten aller Tabellen einer Datenbank. Dazu verwenden wir die Konstante adSchemaTables. Das zurückgegebene Recordset enthält unter anderem die folgenden Felder:
- TABLE_CATALOG: Name der Datenbank
- TABLE_SCHEMA: Schema der Tabelle (bei Access meist leer, bei SQL Server zum Beispiel dbo)
- TABLE_NAME: Name der Tabelle
- TABLE_TYPE: Art des Objekts, zum Beispiel TABLE, VIEW, SYSTEM TABLE oder ACCESS TABLE
Die Prozedur in Listing 1 gibt alle Tabellen der aktuellen Access-Datenbank im Direktbereich aus.
Public Sub TabellenAuflisten() Dim cnn As ADODB.Connection Dim rst As ADODB.Recordset Dim strConnection As String Dim strServer As String Dim strDatabase As String strServer = "amvDesktop2023" strDatabase = "Mitarbeiterverwaltung" Set cnn = New ADODB.Connection strConnection = "Provider=MSOLEDBSQL;Data Source=" _ & strServer & ";Initial Catalog=" & strDatabase _ & ";Integrated Security=SSPI;" cnn.Open strConnection Set rst = cnn.OpenSchema(adSchemaTables) Do While Not rst.EOF Debug.Print rst!TABLE_NAME, rst!TABLE_TYPE rst.MoveNext Loop rst.Close Set rst = Nothing cnn.Close Set cnn = Nothing End Sub
Listing 1: Alle Tabellen der Datenbank auflisten
Im Direktbereich erscheint dann eine Auflistung aller Tabellen mit dem jeweiligen Typ. Dabei wirst Du feststellen, dass neben den von Dir angelegten Tabellen auch Systemtabellen erscheinen, die Access intern verwendet, und Views.
Ergebnisse filtern mit Criteria
Oft benötigst Du nicht alle Informationen, die OpenSchema liefert. In diesem Fall kannst Du den optionalen Parameter Criteria verwenden. Dieser erwartet ein Array mit Filterwerten, wobei die Anzahl und Bedeutung der Array-Elemente vom jeweiligen Schema-Typ abhängt.
Für adSchemaTables akzeptiert Criteria ein Array mit vier Elementen in der folgenden Reihenfolge:
- TABLE_CATALOG: Datenbankname (oder Null für alle)
- TABLE_SCHEMA: Schemaname (oder Null für alle)
- TABLE_NAME: Tabellenname (oder Null für alle)
- TABLE_TYPE: Tabellentyp (oder Null für alle)
Wenn wir beispielsweise nur die regulären Tabellen anzeigen wollen und keine Systemtabellen oder Sichten, können wir das wie in Listing 2 formulieren.
Public Sub NurTabellen() ... cnn.Open strConnection Set rst = cnn.OpenSchema(adSchemaTables, Array(Null, Null, Null, "TABLE")) Do While Not rst.EOF Debug.Print rst!TABLE_NAME, rst!TABLE_TYPE rst.MoveNext Loop rst.Close Set rst = Nothing End Sub
Listing 2: Nur benutzerdefinierte Tabellen anzeigen
Hier übergeben wir für die ersten drei Elemente des Arrays den Wert Null, da wir keine Einschränkung für Katalog, Schema oder Tabellenname vornehmen möchten. Das vierte Element setzen wir auf den Wert TABLE, wodurch nur reguläre Tabellen zurückgegeben werden.
Spalten einer Tabelle ermitteln
Mit adSchemaColumns können wir die Spalten einer Tabelle samt Datentyp, Länge und weiteren Eigenschaften abfragen. Das ist besonders nützlich, wenn Du zur Laufzeit die Struktur einer Tabelle analysieren musst – zum Beispiel für einen generischen Export oder eine dynamische Formularerstellung.
Das zurückgegebene Recordset enthält unter anderem diese Felder:
- COLUMN_NAME: Name der Spalte
- DATA_TYPE: Numerischer Wert für den Datentyp (entspricht den ADODB-Typkonstanten wie adInteger, adVarWChar und so weiter)
- CHARACTER_MAXIMUM_LENGTH: Maximale Zeichenlänge bei Textspalten
- IS_NULLABLE: Gibt an, ob die Spalte Null-Werte erlaubt
- ORDINAL_POSITION: Position der Spalte in der Tabelle
Der Criteria-Parameter für adSchemaColumns akzeptiert ein Array mit vier Elementen:
TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME und COLUMN_NAME.
In Listing 3 filtern wir die Ergebnisse auf eine bestimmte Tabelle.
Public Sub SpaltenErmitteln() ... Set rst = cnn.OpenSchema(adSchemaColumns, Array(Null, Null, "tblKunden", Null)) Do While Not rst.EOF Debug.Print rst!COLUMN_NAME, rst!DATA_TYPE, rst!CHARACTER_MAXIMUM_LENGTH rst.MoveNext Loop rst.Close Set rst = Nothing End Sub
Listing 3: Spalten einer Tabelle ermitteln
Die Ausgabe zeigt für jede Spalte den Namen, den numerischen Datentyp und die maximale Zeichenlänge. Bei numerischen Spalten ist die Zeichenlänge Null (siehe Bild 2).

Bild 2: Tabellen einer Datenbank
Datentyp-Nummern lesbar machen
Die Spalte DATA_TYPE liefert numerische Werte, die den Konstanten der Enumeration DataTypeEnum entsprechen.
Um die Ausgabe lesbarer zu gestalten, können wir eine Hilfsfunktion erstellen, die den numerischen Wert in einen lesbaren Namen umwandelt (siehe Listing 4).
Public Function DatentypName( _ ByVal lngTyp As Long) As String Select Case lngTyp Case 2: DatentypName = "SmallInt" Case 3: DatentypName = "Integer" Case 4: DatentypName = "Single" Case 5: DatentypName = "Double" Case 6: DatentypName = "Currency" Case 7: DatentypName = "Date" Case 11: DatentypName = "Boolean" Case 17: DatentypName = "Byte" Case 72: DatentypName = "GUID" Case 130: DatentypName = "Text (WChar)" Case 202: DatentypName = "VarWChar" Case 203: DatentypName = "LongVarWChar" Case 205: DatentypName = "LongVarBinary" Case Else DatentypName = "Typ " & lngTyp End Select End Function
Listing 4: Hilfsfunktion zum Umwandeln der Datentypen
Diese Funktion kannst Du in der Prozedur SpaltenErmitteln verwenden, indem Du die Zeile mit rst!DATA_TYPE wie folgt anpasst:
Debug.Print rst!COLUMN_NAME,
DatentypName(rst!DATA_TYPE),
rst!CHARACTER_MAXIMUM_LENGTH
Damit erhalten wir das Ergebnis aus Bild 3.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo
