DoCmd- und RunCommand-Anweisungen

Aktionen, die Sie über die Oberfläche von Access durchführen, lassen sich fast alle auch über VBA anstoßen. Für die hinter Menüs, Kontextmenüs und Ribbon liegenden Befehle gibt es Pendants, welche sich in zahlreichen Methoden vor allem des DoCmd-Objekts und der RunCommand-Anweisung verstecken. über diese VBA-Funktionen lassen sich komplexe Aufgaben mit wenig Aufwand erledigen. Das ist Grund genug für eine ausführlichere übersicht.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1511_DocmdAnweisung.accdb

Unterschiede zwischen DoCmd und RunCommand

Zunächst handelt es sich bei RunCommand um eine direkte Methode der Access.Application-Instanz. DoCmd hingegen ist ein Eigenschaftsobjekt von Application, das generell verfügbar ist:

Application.RunCommand acCmd-Konstante
Application.DoCmd.

RunCommand nimmt grundsätzlich nur einen einzigen Parameter entgegen, der aus der Enumeration acCommand stammen muss. Das sind Konstanten, die bestimmten Aktionen entsprechen. Wollen Sie etwa ein Fenster, sei es ein Formular oder ein Bericht, maximieren, so lautet die entsprechende Konstante acCmdDocMaximize:

RunCommand acCmdDocMaximize

Die Zahl dieser Konstanten in den aktuellen Access-Versionen liegt bei etwa 600.

Beim DoCmd-Objekt sind es deutlich weniger Methoden, circa 70 nämlich, die dafür aber eine variable Zahl an Parametern aufweisen, mit denen die Aktionen gesteuert werden können. Ein Beispiel für eine Anweisung ohne Parameter wäre

DoCmd.Maximize

Auch dieser Befehl maximiert ein Formular- oder Berichtsfenster, welches aktuell den Fokus besitzt. Eine Methode mit mehreren Parametern wäre

DoCmd.Close acForm, _
    "frmAdressen", acSaveYes

Dies schließt das Formular frmAdressen und und speichert seinen Zustand, also vor allem seine Abmessungen, explizit. Auch ein im Entwurfsmodus befindliches Formular wird damit geschlossen und die änderungen abgespeichert. Ohne den optionalen Parameter acSaveYes würden Sie mit dem Bestätigungsdialog zum Speichern konfrontiert.

Sowohl RunCommand-, wie DoCmd-Anweisungen spiegeln das wieder, was Sie auch über Schaltflächen der Oberfläche erreichen. Es handelt sich deshalb auch immer um Sub-Prozeduren, die keinen Rückgabewert haben. Generell könnte man formulieren, dass RunCommand Anweisungen entspricht, die keine weitere Interaktion erfordern, während die DoCmd-Methoden eher mit den Access-Assistenten zu vergleichen wären, die über mehrere Schritte Angaben abfragen, bevor die eigentliche Aktion ausgeführt wird. Diese vom Assistenten gesammelten Informationen entsprechen dann den Parametern, die die DoCmd-Methode erwartet. Ein Beispiel hierfür wäre der Text-Export-Assistent, der sein Spiegelbild in der Anweisung DoCmd.TransferText hat.

Während die DoCmd-Anweisungen in der Hilfe von Access alle hinreichend dokumentiert sind, sind Sie bei den RunCommand-Konstanten auf den sprechenden Namen oder Experimente angewiesen.

Microsoft selbst hat über alle Versionen von Access hinweg keine übersicht über die Bedeutung der Konstanten veröffentlicht. Im Zweifel finden Sie Im Internet auf Seiten Dritter weitere Erläuterungen.

Im Folgenden geht es in erster Linie um die Möglichkeiten, die DoCmd eröffnet. Nicht alle Methoden sind aufgeführt, da viele nicht wirklich relevant sind oder nur im Umfeld von Access-Projekten (SQL-Server) Bedeutung haben. Die Methoden sind thematisch zusammengefasst.

Objekte öffnen

Dass sich ein Formular über die DoCmd-Anweisung OpenForm laden lässt, ist Ihnen sicher schon untergekommen. Aber für alle anderen Access-Objekte gibt es ebenfalls äquivalente Methoden, deren wesentliche Vertreter Sie in Listing 1 finden. Interessant sind dabei vor allem die Parameter, welche das Laden steuern.

Sub TestOpenObjects()
     DoCmd.OpenModule "mdlDoCommands", "TestOpenObjects"
         Msg "Modul und Prozedur geöffnet"
     DoCmd.OpenQuery "qryAdressenG", acViewNormal, acReadOnly
         Msg "Abfrage geöffnet"
     DoCmd.OpenReport "rptAdressen", acViewPreview, "Vorname Like 'B*'", acDialog
         Msg "Bericht geöffnet"
     DoCmd.OpenForm "frmAdressen", , , , acFormReadOnly, acDialog, "Test1"
         Msg "Formular war geöffnet"
     DoCmd.OpenTable "tblLaender", acViewNormal, acReadOnly
         Msg "Tabelle geöffnet"
End Sub

Listing 1: Die relevanten öffnen-Methoden des DoCmd-Objekts

OpenModule ist für den Laufzeitbetrieb einer Datenbank überflüssig. Die Anweisung öffnet ein VBA-Modul, das Sie namentlich angeben. Zusätzlich kann mit weiterem Parameter auch eine Prozedur des Moduls spezifiziert werden, auf die beim öffnen der Cursor positioniert wird. Die Beispieldatenbanken von Access Basics verwenden den Befehl etwa hin und wieder im Intro-Formular, um beim Start sogleich ein Modul und damit den VBA-Editor zu öffnen, welches von besonderem Interesse sein kann.

OpenQuery öffnet eine Abfrage. über den View-Parameter steuern Sie dabei, in welcher Gestalt die Abfrage erscheinen soll. Möchten Sie die normale Datenblattansicht, so setzen Sie acViewNormal ein. Für den Entwurfsmodus steht acViewDesign. Weniger bekannt ist, dass acViewPreview die Abfrage in die Seitenansicht für den Druck bringt, womit etwa kontrolliert werden kann, ob das Ergebnis auf eine Seite passt. Diese View-Parameter teilt sich die Anweisung mit den anderen öffnungsmethoden. Nur sind bei Abfragen die Konstanten acViewReport (Berichtsansicht) und acViewLayout (Layout-Ansicht) nicht erlaubt und führen zum Fehler.

Handelt es sich bei der Abfrage um eine Aktionsabfrage, so hat der View-Parameter keinerlei Bedeutung, denn ein Fenster öffnet sich hier nicht.

Interessant ist der letzte optionale Parameter DataMode, mit dem Sie bestimmen können, ob das Abfrageergebnis editierbar sein soll. acReadOnly führt nämlich zu einer schreibgeschützten Ansicht, während ein acEdit (Vorgabe) die Datensätze bearbeitbar macht, falls die Abfrage selbst das unterstützt.

Die gleichen Parameter, wie für OpenQuery, finden Sie auch bei der Anweisung OpenTable, mit der Sie eine Tabelle öffnen. Auch hier können Sie über DataMode entscheiden, ob die Ansicht schreibgeschützt oder editierbar sein soll.

Umfangreich sind die Parameter, die die zum Laden eines Formulars dienende Anweisung OpenForm erwartet. Bis auf den Namen des Formulars sind diese allerdings alle optional und deshalb auch nicht so bekannt.

Die Ansichtsart steuern Sie wie bei OpenQuery und OpenTable, nur, dass nun auch acViewLayout gestattet ist. Standardmäßig ist acViewNormal voreingestellt. Als zweiten Parameter, im Listing nicht verwendet, können Sie den Namen einer Filterabfrage angeben, die die angezeigte Datensatzmenge einschränkt. Dieses Verfahren ist weitgehend obsolet. Verwenden Sie besser den dritten Parameter für die WhereCondition. Hier können Sie einen SQL-Ausdruck einsetzen, der als Filter dient, etwa:

..., "Nachname LIKE 'H*''

Das führte dazu, dass nur Datensätze im Formular erschienen, die im Nachnamenfeld mit H beginnen. Die Verwendung dieses Parameters entspricht damit dem Setzen der Formulareigenschaft Filter inklusive dem Aktivieren von FilterOn.

Auch beim Formular kann das Editieren ausgeschaltet werden, indem Sie die Konstante acFormReadOnly für DataMode einsetzen. Und schließlich lässt sich über WindowMode angeben, wie das Formular geladen wird. Der Standard ist acWindowNormal. Nehmen Sie acIcon, so öffnet es sich minimiert. Mit acHidden bleibt es sogar unsichtbar. Schließen können Sie es dann nur noch über VBA. Am interessantesten aber ist der über acDialog festgelegte Dialog-Modus. In diesem zeigt sich das Formular auf den ersten Blick in normalem Gewand. Tatsächlich aber ist es modal, was bedeutet, dass der Rest der Access-Anwendung gesperrt ist. Nur das geöffnete Dialogformular lässt sich bearbeiten. Zudem stoppt auch VBA nach dem Ausführen der aufrufenden Code-Zeile. Erst nach dem Schließen fährt es mit den weiteren Zeilen der Prozedur fort. Man kann sich dies etwa zunutze machen, um Eingaben im Formular auszulesen. Denn auch dann, wenn das Formular über die Visible-Eigenschaft im Formular-Code unsichtbar gemacht wird, übergibt VBA die Kontrolle an die aufrufende Prozedur. Nun könnte diese etwa Felder des Formulars auslesen, da es inzwischen zwar noch existiert, aber nicht mehr sichtbar ist. Das bedeutet allerdings auch, dass die Routine selbst das Formular über eine Close-Anweisung schließt, denn sonst irrt es auf Ewigkeiten im Speicher umher.

Als letzten Parameter finden Sie für OpenArgs im Listing den String „TEST1“. Hier können Sie beliebige Daten, also auch Zahlenvariablen oder Objekte einsetzen. Das hat auf die Gestalt des geladenen Formulars keinen Einfluss. über dessen Eigenschaft OpenArgs kann aber an beliebiger Stelle im Formular-Code auf diese Angabe Bezug genommen werden. So etwa im Beim Laden-Ereignis des Formulars:

Sub Form_Load()
     Msgbox Me.OpenArgs
End Sub

Hier würde TEST1 in einem Meldungsfenster erscheinen, sobald das Formular gestartet wurde.

Die Parameter für die Anweisung OpenReport zum Laden eines Berichts gleichen jenen von OpenForm. Hier ist zusätzlich die Ansichtsart acViewReport (Berichtsansicht) möglich. Ansonsten lassen sich hier ebenfalls Filter setzen, der WindowMode einstellen und OpenArgs übergeben. Es ist jedoch eine Besonderheit zu beachten: acViewNormal öffnet den Bericht nicht etwa in der normalen Ansicht, sondern schickt ihn zum Drucker! Wenn Sie also bei OpenReport lediglich den Namen des Berichts angeben und auf weitere Parameter verzichten, so wundern Sie sich nicht, dass scheinbar nichts passiert! Erst im Taskbar von Windows stellen Sie dann fest, dass ein Drucker in Aktion gesetzt wurde. Für die normale Ansicht unter Access setzten Sie daher acViewPreview ein.

über VBA mit DoCmd geöffnete Objekte schließen Sie mit einer weiteren DoCmd-Anweisung:

DoCmd.Close acForm, "frmAdressen"
DoCmd.Close acModule, "mdlDoCommands"
DoCmd.Close acQuery, "qryAdressenG"

Formular- und

Datensatzsteuerung

Ist ein Formular erst über OpenForm geöffnet, dann können Sie es über zahlreiche DoCmd-Methoden steuern. Oder genauer gesagt: dessen Datensätze steuern.

Listing 2 zeigt eine gekürzte Version der Prozedur, welche Sie in der Beispieldatenbank finden. In der Originalversion ist nach jeder DoCmd-Zeile eine Msgbox eingebaut, die ausgibt, was gerade vonstattenging. Ohne diese Meldungsfenster würde der Code der Prozedur ja in Sekundenbruchteilen durchlaufen sein, ohne dass Sie die Auswirkungen der Anweisungen begutachten könnten.

Sub TestFormObject()
     DoCmd.OpenForm "frmAdressen"
     DoEvents
     DoCmd.SelectObject acForm, "frmAdressen"
     DoCmd.ApplyFilter , "Nachname LIKE 'Wag*'"
'    DoCmd.SetFilter , "Nachname LIKE 'Wag*'","
     DoCmd.GoToRecord acDataForm, "frmAdressen", acLast
     DoCmd.FindRecord "Gudrun", acEntire, False, acSearchAll, False, acAll, True
     DoCmd.SetOrderBy "Vorname", "sfmKinder"
     DoCmd.FindRecord "Gisela", acEntire, False, acSearchAll, False, acAll, True
     DoCmd.FindNext
     DoCmd.SetProperty "txtNachname", acPropertyForeColor, RGB(64, 64, 255)
     DoCmd.Requery "txtVorname"
     DoCmd.ShowAllRecords
     DoCmd.Echo False
     DoCmd.GoToRecord acDataForm, "frmAdressen", acLast
     DoCmd.GoToRecord acDataForm, "frmAdressen", acFirst
     DoCmd.Echo True
     DoCmd.SearchForRecord acDataForm, "frmAdressen", acFirst, "Nachname='Hückmann'"
     If MsgBox("Formular schließen", vbYesNo) = vbYes Then
         DoCmd.Save acForm, "frmAdressen"
         DoCmd.Close acForm, "frmAdressen", acSaveYes
     End If
End Sub

Listing 2: DoCmd-Anweisungen für verschiedene datensatzbezogene Aktionen

SelectObject setzte den Fokus auf ein Access-Objekt und/oder markiert dieses. In unserem Fall handelt es sich um das Formular frmAdressen. Sinn der Angelegenheit ist es, das entsprechende Objekt zu aktivieren. Denn die folgenden Anweisungen wirken immer auf das geöffnete aktive Objekt. Sind etwa mehrere Formulare gleichzeitig geöffnet, so steuern Sie mit diesem Befehl, welches den Fokus bekommen soll.

Nach dem Aktivieren kann per ApplyFilter eine Filterbedingung auf die angezeigten Datensätze angewandt werden. Das entspricht dem Vorgang, wenn Sie manuell über das Menüband oder über einen Spaltenkopf in Datenblattansicht einen Filter bestimmen. Hier werden nur jene Datensätze angezeigt, die im Nachnamefeld mit Wag beginnen. In der Navigationsleiste wird das deutlich, weil sich hier die Zahl der Datensätze verringert hat und vom Ausdruck (Gefiltert) begleitet wird. Statt ApplyFilter können Sie auch die Anweisung SetFilter mit gleicher Syntax benutzen. Der Unterschied besteht darin, dass beim Schließen des Formulars und gleichzeitigem Speichern der Filterausdruck dann in der Eigenschaft Filter verewigt bleibt.

Einen gesetzten Filter entfernen Sie einfach wieder mit einem Aufruf von DoCmd.ShowAllRecords.

GotoRecord erlaubt das Springen zu einem bestimmten Datensatz. Hier kann dezidiert angegeben werden, welches Formular zu steuern ist. Für den letzten Parameter gibt es verschiedene Steuerkonstanten. acLast springt zum letzten Datensatz, acFirst zum ersten, und so weiter. Interessanter ist da schon acGoto. In diesem Fall muss noch ein weiterer Parameter angehängt werden, der den Offset zum aktuellen Datensatz angibt. Möchten Sie etwa zum genau fünften Datensatz des Formulars springen, so verwenden Sie zwei Zeilen:

DoCmd.GoToRecord  , , acFirst
DoCmd.GoToRecord  , , acGoto, 4

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar