Access-Formulare leben traditionell von ihrer Datensatzquelle. Du weist dem Formular eine Tabelle oder eine Abfrage zu, und Access kümmert sich um alles Weitere – Navigieren, Bearbeiten, Speichern, Löschen. Das funktioniert hervorragend, solange die Daten in einer Access-Datenbank oder in verknüpften Tabellen liegen. Arbeitest Du jedoch mit einem SQL Server und möchtest den Datenzugriff ausschließlich über gespeicherte Prozeduren abwickeln – etwa, weil Du die Datenbanklogik serverseitig kapseln, Berechtigungen feingranular steuern oder die Performance optimieren willst -, stößt dieses Modell an seine Grenzen. Gespeicherte Prozeduren lassen sich nicht als Datensatzquelle eines Formulars zuweisen, und die klassischen Access-Mechanismen zum Speichern greifen nicht. In diesem Artikel zeigen wir Dir, wie Du ein vollständiges CRUD-Formular mit Übersicht und Detailansicht baust, das komplett ohne Datensatzquelle auskommt. Stattdessen füllen wir die Unterformular-Recordsets und die Detailfelder zur Laufzeit mit dem Ergebnis gespeicherter Prozeduren, die wir über den Wrapper aus dem Artikel “ADODB: Gespeicherte Prozeduren einfach aufrufen” (www.vbentwickler.de/505) aufrufen. Das Ergebnis ist eine Formularoberfläche, die sich vom Benutzer aus anfühlt wie ein klassisches Access-Formular, intern aber ausschließlich mit serverseitigen Prozeduren kommuniziert.
Beispieldatenbank
Die Beispiele dieses Artikels findest Du in der Beispieldatenbank ADODB_GespeicherteProzeduren.accdb. Die zugehörige SQL Server-Datenbank heißt Test_GespeicherteProzeduren und enthält die beiden Tabellen tblAbteilung und tblMitarbeiter.
Das Skript zum Anlegen der Tabellen, der Testdaten und der gespeicherten Prozeduren findest Du im Modul mdlSQLServerDB als auskommentierten T-SQL-Code, den Du direkt in ein Abfragefenster des SQL Server Management Studio kopieren kannst.
Praxiseinsatz im Übersichtsformular
Damit der Wrapper mehr sein kann als ein theoretisches Konstrukt, verbinden wir ihn nun mit einem vollständigen Access-Formular. Das Formular frmMitarbeiterUebersicht_Parameter enthält ein Unterformular in Datenblattansicht, das alle Mitarbeiter auflistet, sowie vier Schaltflächen zum Neuanlegen, Bearbeiten, Löschen und Aktualisieren (siehe Bild 1).

Bild 1: Formular zur Anzeige einer Mitarbeiter-Übersicht
Das Übersichtsformular selbst hat keine Datensatzquelle. Stattdessen bekommt das Unterformular sfmMitarbeiterUebersicht_Parameter das Recordset erst zur Laufzeit zugewiesen – nämlich aus dem Rückgabewert unserer Funktion ADODB_GetRecordset.
Diese Zuweisung passiert in der Prozedur MitarbeiterAktualisieren (siehe Listing 1).
Private Sub MitarbeiterAktualisieren() With Me.sfmMitarbeiterUebersicht.Form Set .cboAbteilungID.Recordset = ADODB_GetRecordset("spAbteilungenSelect") Set .Recordset = ADODB_GetRecordset("spMitarbeiterSelectNachMitarbeiterID") End With End Sub
Listing 1: Recordset des Unterformulars setzen
Zwei Zuweisungen – mehr ist nicht nötig. Die erste Zeile weist einem Kombinationsfeld cboAbteilungID im Datenblatt ein Recordset der Abteilungen zu, damit dort statt der nackten AbteilungID die entsprechende Abteilungsbezeichnung angezeigt werden kann.
Die zweite Zeile weist dem Unterformular das Recordset der Mitarbeiter zu. Weil wir ADODB_GetRecordset ohne Parameter aufrufen, werden alle Mitarbeiter zurückgeliefert.
An einer Stelle müssen wir vorsichtig sein: Wir können die Prozedur MitarbeiterAktualisieren nicht direkt im Form_Load– oder Form_Open-Ereignis aufrufen, weil das Unterformular zu diesem Zeitpunkt noch nicht vollständig initialisiert ist.
Stattdessen setzen wir im Form_Load-Ereignis das TimerInterval auf 100 Millisekunden und rufen die Aktualisierung dann im Form_Timer-Ereignis auf, wobei wir den Timer gleich wieder mit dem Wert 100 deaktivieren:
Private Sub Form_Load() Me.TimerInterval = 100 End Sub Private Sub Form_Timer() Me.TimerInterval = 0 Call MitarbeiterAktualisieren End Sub
Die Schaltfläche cmdAktualisieren ruft einfach wieder MitarbeiterAktualisieren auf und lädt so die Daten neu vom SQL Server.
Neuen Datensatz anlegen
Die Schaltfläche cmdNeu öffnet das Detailformular frmMitarbeiterDetail_Parameter als Dialog. Nach dem Schließen des Dialogs liest sie die ID des neu angelegten Datensatzes aus, aktualisiert die Liste und positioniert den Datensatzmarkierer auf dem neuen Eintrag (siehe Listing 2).
Private Sub cmdNeu_Click() Dim strForm As String Dim lngMitarbeiterID As Long strForm = "frmMitarbeiterDetail_Parameter" DoCmd.OpenForm strForm, WindowMode:=acDialog If IstFormularGeoeffnet(strForm) Then lngMitarbeiterID = Nz(Forms(strForm).Form.MitarbeiterID, 0) DoCmd.Close acForm, strForm Call MitarbeiterAktualisieren Me.sfmMitarbeiterUebersicht.Form .Recordset.Find "MitarbeiterID = " & lngMitarbeiterID End If End Sub
Listing 2: Neuen Mitarbeiter anlegen
Das WindowMode:=acDialog sorgt dafür, dass das Detailformular modal geöffnet wird und der Code an dieser Stelle stehenbleibt, bis das Formular entweder geschlossen oder unsichtbar gemacht wird. Die Hilfsfunktion IstFormularGeoeffnet, die im Modul mdlTools liegt, prüft über SysCmd, ob das Detailformular noch geöffnet ist – dann hat der Benutzer gespeichert (das Detailformular setzt in diesem Fall nur Me.Visible = False) und wir lesen die vergebene ID aus.
Bearbeiten und Löschen
Die Schaltfläche cmdBearbeiten arbeitet nach demselben Prinzip, übergibt dem Detailformular aber zusätzlich die zu bearbeitende ID als OpenArgs (siehe Listing 3).
Private Sub cmdBearbeiten_Click() Dim strForm As String Dim lngMitarbeiterID As Long lngMitarbeiterID = Me.sfmMitarbeiterUebersicht.Form.MitarbeiterID strForm = "frmMitarbeiterDetail_Parameter" DoCmd.OpenForm strForm, WindowMode:=acDialog, OpenArgs:=lngMitarbeiterID If IstFormularGeoeffnet(strForm) Then DoCmd.Close acForm, strForm Call MitarbeiterAktualisieren Me.sfmMitarbeiterUebersicht.Form.Recordset.Find "MitarbeiterID = " & lngMitarbeiterID End If End Sub
Listing 3: Mitarbeiter bearbeiten
Die Schaltfläche cmdLoeschen schließlich ist die kürzeste von allen, weil wir hier direkt unsere Wrapper-Funktion ADODB_ExecDelete einsetzen können (siehe Listing 4).
Private Sub cmdLoeschen_Click() Dim lngMitarbeiterID As Long lngMitarbeiterID = Me.sfmMitarbeiterUebersicht.Form.MitarbeiterID If ADODB_ExecDelete("spMitarbeiterDelete", lngMitarbeiterID) > 0 Then MsgBox "Mitarbeiter gelöscht.", vbOKOnly + vbInformation, "Mitarbeiter gelöscht" Call MitarbeiterAktualisieren End If End Sub
Listing 4: Mitarbeiter löschen
Ein einziger Funktionsaufruf, bei dem der Name der gespeicherten Prozedur sowie die zu löschende ID übergeben werden. Die Anzahl der betroffenen Datensätze kommt als Rückgabewert zurück. Ist sie größer 0, war das Löschen erfolgreich und wir aktualisieren die Liste.
Das Detailformular
Unser exklusives Angebot für Dich!
(Gilt für den Abschluss eines Jahres-Abonnements.)
Hier geht’s weiter →Die ersten 4 Wochen kostenlos testen – voller Zugriff auf alle Artikel, vollständigen Code und Beispieldatenbanken. Kein Risiko: Wenn es nicht passt, kündigst Du einfach innerhalb der ersten vier Wochen.
Oder hast Du eine konkrete Frage zu Deiner eigenen Access-Anwendung?
Vielleicht stellt Deine Anwendung Dich vor eine Herausforderung, zu der Du bisher keine Lösung findest. Schlechte Performance, kein ausreichender Zugriffsschutz, Du bist unsicher über Dein Datenmodell oder Dein Code liefert unerklärliche Fehler?
In unserem kostenlosen Access-Audit schaut sich André Minhorst persönlich gemeinsam mit Dir Deine Lösung per Zoom an – und zeigt Dir, wo Datenmodell, VBA-Code, Ergonomie und Sicherheit Optimierungspotenzial bieten.
Jetzt kostenloses Access-Audit anfordern →