Probleme mit Sendkeys unter Windows Vista

Problem:

Wir haben eine Anwendung in Access 2003 entwickelt, die lange Zeit problemlos unter Windows 2000 und Windows XP lief. Wenn wir die Anwendung nun auf einem neuen Rechner mit Windows Vista einsetzen, bekommen wir bei der ersten SendKeys-Anweisung einen Laufzeitfehler 70, „Zugriff verweigert“. Wenn wir diesen einen SendKeys-Fehler umgehen, wird die Fehlermeldung beim nächsten SendKeys erneut angezeigt.

Lösung:

„SendKeys“ in VBA (und Visual Basic 6) ist den neuen Sicherheitsfunktionen von Windows Vista (und dem Internet Explorer 7.0) zum Opfer gefallen. Auf diese Weise soll verhindert werden, dass Viren, Würmer und Trojaner durch eine per „SendKeys“ realisierte „Fernbedienung“ von Windows oder unter Windows laufenden Anwendungen Schaden an richten.

Sie müssen also für die momentan per „SendKeys“ gelösten Probleme andere Lösungen finden. Als Alternative bieten sich beispielsweise API-Funktionen wie „SendInput()“, „SendMessage()“ oder „Keyb_Event()“ an, die allerdings recht komplex in der Umsetzung sind, weil z. B. per „Keyb_Event()“ Tastenzustände wie „KeyDown“ und „KeyUp“ einzeln und synchronisiert simuliert werden müssen. In Betracht käme eventuell noch eine kommerzielle Lösung, die per Modul oder DLL eingebunden wird.

Zum Beispiel:

http://m8software.com/developer/keysend/sendkey.htm

Feldnamen

Wenn Feldnamen Leerzeichen enthalten,
müssen eckige Klammern [ ] gesetzt werden

Fehler durch defekte Verweise

Nachdem Sie eine Datenbank fertig gestellt und z. B. an einen Kollegen oder an Kunden ausgeliefert haben, erscheint unter Umständen eine Fehler meldung, die Sie auf einen unbekannten Befehl hinweist. Nach Bestätigung der Meldung erscheint dann das Fenster der VBA-Entwicklungsumgebung und zeigt die Fehler verursachende Routine mit einer markierten Anweisung wie „Left$(<Ausdruck>)“ oder „Val(<Ausdruck>)“ an.

Da es sich hier um ganz normale VBA-Anweisungen handelt und sich der Fehler auf dem Entwicklungsrechner nicht reproduzieren lässt, ist zunächst nicht nach vollziehbar, warum diese Anweisung plötzlich unbekannt sein soll.

Die Neuinstallation als Standardmethode zur Beseitigung des Problems hilft nicht weiter, denn es gibt eine ganz andere Ursache: Wenn eine Access-Datenbank geöffnet wird und dabei VBA-Anweisungen ausgeführt werden sollen, übersetzt Access die benötigten VBA-Module in einen schneller ausführbaren Code. Stößt es dabei auf irgendeinen Fehler, bleibt die VBA-Umgebung uninitialisiert und ein fache Anweisungen wie „Left$(<Aus druck>)“ oder „Val(<Ausdruck>)“ wer den als unbekannt bemängelt. Einer der möglichen Fehler ist ein Verweis, der auf dem Zielrechner nicht aufgelöst werden kann.

Ein Beispiel: Auf dem Entwicklungsrechner setzen Sie ActiveX-Kom po nen ten oder benutzerdefinierte Steuerelemente wie das „TreeView“-Steuerelement ein oder verwenden Anweisungen für Office Automation, um Adressen aus Access in ein Word-Dokument einzufügen. Sobald Sie eine dieser ActiveX-Komponenten in einem Formular oder in einem Bericht verwenden, setzt Access automatisch im Hintergrund einen Verweis auf die dazugehörige Objektbibliothek. Wird die Datenbank nun auf dem Zielrechner gestartet, versucht Access, die zum Verweis gehörenden Bibliotheken zu laden.

Ist dort jedoch zum Beispiel das „TreeView“-Steuerelement nicht installiert, bricht Access die Initialisierung mit der erwähnten Fehlermeldung ab.

Um das Problem zu lösen, gehen Sie wie folgt vor:

  1. Öffnen Sie ein beliebiges Modul und wählen Sie das Menü EXTRAS-VERWEISE an.
  2. Prüfen Sie die einzelnen Einträge in der Liste VERFÜGBARE VERWEISE. Sie werden einen oder mehrere Einträge vorfinden, denen der Hinweis „NICHT VORHANDEN:“ vorangestellt ist.
  3. Prüfen Sie, ob die referenzierte Komponente in der Datenbank benötigt wird. So werden ActiveX-Komponenten häufig testweise in ein Formular eingebunden, dann aber später wieder gelöscht – die Referenz darauf bleibt aber trotzdem gesetzt!
  4. Wird die ActiveX-Komponente/das Steuerelement nicht in der Datenbank verwendet, deaktivieren Sie das Kontrollkästchen vor dem entsprechen den Eintrag und bestätigen mit OK. Wenn die Komponente jedoch in der Datenbank verwendet wird, muss sie auf dem Zielrechner installiert werden, damit Access die Referenz auflösen kann.

In Access 2007 und 2003 erhalten Sie übrigens bereits beim Öffnen der Datenbank einen Hinweis auf einen oder mehrere fehlende Verweise.

Häufig wird dies e Meldung allerdings einfach weggeklickt und wird dann mit den weiteren Problemen bei der Ausführung von Prozeduren nicht mehr in Verbindung gebracht.

Sollten Sie Access 2007 oder 2003 einsetzen und die Fehlermeldung erhalten, gehen Sie am besten sofort wie oben beschrieben vor, um den Verweis zu korrigieren.

Download ohne Internet-Explorer

Frage: Kann man aus Access heraus eine Datei aus dem Internet herunterladen, ohne den Internet Explorer manuell zu starten?

Der Anwender soll aber trotzdem die Möglichkeit haben, die Datei in einem beliebigen Ordner zu speichern.

Antwort: Dazu können Sie die APIFunktion „ShellExecute()“ nutzen.

Wird ihr als zweiter Parameter ein Link auf eine Datei übergeben, reicht sie die An frage an den Internet Explorer weiter, der dann den „Speichern unter“-Dialog anzeigt und die Datei herunterlädt.

Kopieren Sie zunächst die folgende Deklaration in ein neues oder in ein vorhandenes Modul:

Private Declare Function
ShellExecute Lib „shell32.dll“ Alias „ShellExecuteA“
(ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long)
As Long

Anschließend können Sie dann eine Anweisung wie die folgende verwenden, um eine Datei herunterzuladen:

ShellExecute 0&, vbNullString, „http://www.server.de/Downloads/Datei.exe“, vbNullString, vbNullString,vbHidden)

Die wichtigsten Grundlagen zur VBA-Steuerung von Oulook

Datenbank

Alle Office-Anwendungen sind programmierbar, sodass sich fehlende Funktionen per VBA (=Visual Basic for Applications, Programmiersprache Basic für Anwendungen) nachrüsten lassen. Besonders interessant dabei ist die Möglichkeit, andere Anwendungen als Objekte in VBA einzubinden. So können Sie mit wenigen Mausklicks auch Outlook in den Dienst von Access stellen. Diese Kombination mit Access wird häufig genutzt, um beispielsweise Notizen, Termine und Aufgaben zu verwalten oder um Informationen per E-Mail und Anhang zu verschicken. In dieser Ausgabe vermitteln wir dazu alle wichtigen Grundlagen und stellen fertige Lösungen für den Einsatz von Outlook mit Access vor, die Sie mit wenig Aufwand in Ihre Datenbankenanwendungen integrieren können.

Um eine Anwendung wie Outlook in Access zu nutzen, binden Sie zunächst ein entsprechendes „Objektmodell“ in VBA ein. Ein Objektmodell gibt Auskunft darüber, welche Eigenschaften, Auflistungen und Methoden die Anwendung zur Verfügung stellt und welche Parameter und Konstanten für den Aufruf einzelner Methoden anzugeben sind. Die Einbindung erfolgt in der VBA-Entwicklungsumgebung (Alt + F11) über das Menü EXTRAS-VERWEISE. Hier finden Sie neben den Office-Anwendungen von Microsoft eine umfangreiche Liste anderer Anwendungen und Objekte, die Sie theoretisch in Access nutzen können. Um mit Outlook zu arbeiten, aktivieren Sie das Kontrollkästchen vor dem Eintrag „Microsoft Outlook x.x Object Library“, wobei „x.x“ durch 14.0 für Outlook 2010, 12.0 für Outlook 2007, 11.0 für Outlook 2003, 10.0 für Outlook 2002/XP und 9.0 für Outlook 2000 zu ersetzen ist.

Nachdem Sie auf OK geklickt haben, ist Access das Objektmodell von Outlook bekannt und Sie können dessen Funktionen nutzen.

Eine Verbindung zu Outlook aufbauen
Für den Zugriff auf Outlook-Funktionen benötigen Sie eine Verbindung zwischen Access und Outlook. Dazu gibt es zwei Möglichkeiten: Sie können entweder eine bereits laufende Instanz von Outlook nutzen oder eine neue Instanz von Outlook starten.

In der Praxis hat es sich bewährt, eine bereits laufende Instanz zu nutzen und nur, wenn Outlook noch nicht läuft, eine neue Instanz zu starten. Die Verbindung erfolgt über eine Objektvariable vom Datentyp „Outlook.Application“, die in einem globalen Modul deklariert und entsprechend initialisiert wird:

Public objOutlApp As Outlook.Application

In einer globalen Funktion „InitOutlook“ erfolgt die Initialisierung dieser Objektvariablen vor der Nutzung von Outlook- Funktionen wie folgt:

Function InitOutlook() As Boolean
On Error Resume Next
InitOutlook = False ‚Default: Keine Verbindung
Set objOutlApp = GetObject(, „Outlook.Application“)
If Err <> 0 Or objOutlApp Is Nothing Then
Err = 0
Set objOutlApp = CreateObject(„Outlook.Application“)
If Err <> 0 Or objOutlApp Is Nothing Then
Beep
MsgBox „Verbindung zu Outlook kann nicht aufgebaut werden: “ & _
Err.Description, vbOKOnly + vbCritical, „Problem:“
Exit Function
End If ‚Err<> 0…
End If ‚Err<> 0…
InitOutlook = True
End Function

Um eine Verbindung zu einer bereits laufenden Instanz von Outlook herzustellen, wird zunächst versuchsweise die VBAFunktion „GetObject()“ aufgerufen, die im Erfolgsfall eine Referenz auf Outlook in der Objektvariablen „objOutlApp“ speichert. Ist Outlook nicht gestartet, hat das einen Laufzeitfehler zur Folge, der jedoch durch das eingangs abgesetzte „On Error Resume Next“ und die Abfrage „If Err <> 0 Then…“ entsprechend abgefangen wird. Der Aufruf der Funktion „CreateObject()“ versucht dann, eine neue Instanz von Outlook zu starten. Kommt es dabei wieder zu einem Laufzeitfehler („Err <> 0“) oder wurde die Objektvariable nicht initialisiert (Is „Nothing“), konnte Outlook nicht gestartet werden. Es erfolgen die Anzeige einer entsprechenden Meldung und das Verlassen der Funktion. Grund für einen Fehler in dieser Phase kann beispielsweise ein gar nicht oder nur unvollständig installiertes Outlook oder ein fehlerhaftes Outlook-Add- In sein, das sich nicht sauber initialisiert. Nachdem die Objektvariable „objOutlApp“ initialisiert ist, kann sie wie in den folgenden Beiträgen erläutert für die Nutzung von Outlook-Funktionen verwendet werden. Wichtig ist jedoch, dass Sie vor dem Beenden von Access die Verbindung zu Outlook unbedingt wieder trennen! Geschieht das nicht, kann Access nicht beendet werden: Das Access-Fens ter bleibt sichtbar, ein Klick auf das SCHLIEßEN Symbol oder der Aufruf von BEENDEN sind wirkungslos und es bleibt nur das Beenden des Prozesses MSACCESS.EXE über den Task-Manager. Sie müssen also nach der Nutzung von Outlook-Funktionen die Verbindung immer wie folgt trennen:

Function ResetOutlook()
On Error Resume Next
If Not objOutlApp Is Nothing Then
Set objOutlApp = Nothing
End If
End Function

 

Fertiges Modul nutzen

Sie finden die hier vorgestellten Funktionen „InitOutlook()“ und „ResetOutlook()“ sowie die Deklaration der globalen Objektvariablen „objOutlApp“ in der Beispieldatenbank zu diesem Beitrag im Modul „modOutlSubs“. Für die Nutzung in eigenen Datenbanken setzen Sie wie oben erläutert eine Referenz auf Outlook und übertragen dieses Modul über das Menü DATEI-EXTERNE DATEN-IMPORTIEREN (Access 2003, 2002/ XP und 2000) bzw. das Register „Externe Daten“, Gruppe „Importieren“, Symbol ACCESS in Ihre Datenbank (Access 2010 und 2007). Anschließend können Sie die Funktionen testen, indem Sie im Direktbereich der VBA-Entwicklungsumgebung (Strg + G) folgende Anweisungen eingeben:

? InitOutlook()
? objOutlApp.Version
ResetOutlook

Mit diesen Anweisungen wird zunächst eine Verbindung zu Outlook aufgebaut, dann die Version des laufenden Outlooks ausgegeben und schließlich die Verbindung wieder getrennt. Sie haben damit erfolgreich Outlook in Access eingebunden und eine Eigenschaft von Outlook ausgelesen. Die Nutzung weiterer nützlicher Outlook-Funktionen erläutern die weiteren Beiträge in dieser Ausgabe.

 

Dokumentation des Objektmodells

Bei der Eingabe der zweiten Anweisung „? objOutlApp.Version“ werden Sie festgestellt haben, dass Ihnen die VBA-Entwicklungsumgebung nach Eingabe des Punktes „.“ ein Dropdown-Menü mit verfügbaren Eigenschaften, Auflistungen und Methoden anzeigt. Nach Auswahl eines Eintrages erhalten Sie per Quick Info weitere Informationen wie z.B. den Datentyp bei Deklarationen oder erwartete Parameter bei Methoden. Diese Dokumentationstechnik nennt sich „IntelliSense“ und wird Ihnen eine große Hilfe bei der Programmierung Ihrer Outlook-Funktionen sein.

Außerdem können Sie einmal F2 für den Aufruf des Objekt-Browsers drücken. Hier finden Sie nach Einstellung der Bibliothek „Outlook“ alle verfügbaren Eigenschaften, Auflistungen, Methoden, Klassen und Konstanten grob dokumentiert.

Speichern Sie das Modul unter den Namen „modOutlSubs“ ab.


Option Compare Database
Option Explicit

Public objOutlApp As Outlook.Application
Function InitOutlook() As Boolean

On Error Resume Next
InitOutlook = False ‚Default: Keine Verbindung
Set objOutlApp = GetObject(, „Outlook.Application“)
If Err <> 0 Or objOutlApp Is Nothing Then
Err = 0
Set objOutlApp = CreateObject(„Outlook.Application“)
If Err <> 0 Or objOutlApp Is Nothing Then
Beep
MsgBox „Verbindung zu Outlook kann nicht aufgebaut werden: “ & _
Err.Description, vbOKOnly + vbCritical, „Problem:“
Exit Function
End If ‚Err<> 0…
End If ‚Err<> 0…

InitOutlook = True

End Function

Function ResetOutlook() As Boolean

On Error Resume Next
ResetOutlook = False ‚Default: Keine Verbindung
If Not objOutlApp Is Nothing Then
Set objOutlApp = Nothing
ResetOutlook = True
End If

End Function

Datenbanken und Formulare automatisch schließen

Datenbank

Es ist das klassische Problem in jeder Mehrbenutzerumgebung: Wichtige Anpassungen oder die regelmäßige Komprimierung können nicht vorgenommen wer den, weil irgendein Anwender die Datenbank einfach geöffnet lässt, während er vielleicht schon nach Hause gegangen ist oder für mehrere Stunden in einem Meeting sitzt. Wir haben die Lösung für genervte Datenbankadministratoren: Erweitern Sie Ihre Anwendungen um einen Mechanismus, der automatisch überwacht, ob noch Ein gaben in einem Formular erfolgen. Nach einer bestimmten Zeit ohne Aktionen wird Access vollautomatisch beendet.

Die Ursache für das Problem: Wenn Sie in Access ein Formular geöffnet haben, ist der aktuell bearbeitete Datensatz für jeden anderen Zugriff gesperrt. Außer dem sind mindestens eine oder (bei einem Formular, das auf einer Abfrage basiert) auch gleich mehrere Tabellen für Änderungen gesperrt. Diese Sperrungen werden erst aufgehoben, wenn der Datensatz gewechselt bzw. das Formular geschlossen wird. Access stellt so einerseits sicher, dass in Mehrbenutzerumgebungen und Front-End-/Back-End-Lösungen nicht verschiedene Anwender den gleichen Datensatz bearbeiten und sich so die Änderungen gegenseitig überschreiben.

Außerdem verhindert Access, dass Änderungen an Tabellen vorgenommen werden, während sich noch Datensätze in Bearbeitung befinden und eventuell aufgrund von Strukturänderungen nicht mehr gespeichert werden können.

Diese eigentlich sehr sinnvolle Einrichtung hat auch einen Nachteil: Verlässt beispielsweise ein Mitarbeiter den Arbeitsplatz, um in die Mittagspause zu gehen oder gar Feierabend zu machen, ohne die Datenbank mit ein oder mehreren geöffneten Formularen wieder zu schließen, bleibt nicht nur der aktuelle Datensatz gesperrt; an den entsprechenden Tabellen sind keine Änderungen möglich und auch eine dazugehörige Back-End-Datenbank, lässt sich beispielsweise nicht komprimieren oder reparieren.

Im Folgenden möchten wir Ihnen eine pfiffige Lösung für dieses immer wieder auftauchende Problem zeigen. Dabei überwachen Sie die Aktivität in einem Formular und schließen es dann zusammen mit der kompletten Datenbank, wenn eine gewisse Zeit keine Tastatureingaben oder Mausbewegungen zu verzeichnen sind.

Im ersten Schritt müssen Sie dafür sorgen, dass bei jedem Tastendruck und jeder Mausbewegung sozusagen ein „Aktivitätskennzeichen“ gesetzt wird. Dieses Kennzeichen wird in bestimmten Abständen geprüft. Wurde es eine Zeit lang nicht aktualisiert, hat der Anwender keine Eingaben vorgenommen und das Formular wird geschlossen bzw. die Datenbank beendet.

So nutzen Sie den Formular-Timer

Access stellt für Formulare einen Zeitgeber (Timer) zur Verfügung, der in bestimmten Abständen ein Ereignis auslöst. Dieser Zeitraum ist über die Eigenschaft „Zeitgeberintervall“ des Formulars in Tausendstelsekunden (Millisekunden) einstellbar. In der dazugehörigen Ereignisprozedur des Timers können Sie das erwähnte „Aktivitätskennzeichen“ abfragen und bei Bedarf entsprechende Maßnahmen ergreifen.

Wie können Sie nun feststellen, ob der Anwender mit einem Formular tatsächlich arbeitet? Zu diesem Zweck werden die Ereignisse „Bei Taste“ und „Bei Mausbewegung“ aller Steuerelemente und des Formulars eingesetzt. Wann immer der Anwender eine Taste drückt oder die Maus bewegt, kann über diese Ereignisprozeduren festgehalten werden, dass ei ne Aktion stattgefunden hat. Wir verwenden dazu eine Funktion „TimeOut()“, die eine globale Variable „TimeoutFlag“ auf „1“ setzt und so signalisiert, dass eine Aktion statt gefunden hat. Diese Variable kann der Timer des Formulars regelmäßig prüfen und auf „0“ zurücksetzen. Steht die Variable beim nächsten Auslösen des Timer- Ereignisses immer noch auf „0“, hat der Anwender weder eine Taste gedrückt noch die Maus bewegt, das Formular wird geschlossen und die Datenbank verlassen.

Der Timer eines Formulars ist Dreh- und Angelpunkt der Lösung. Dementsprechend muss es in Ihren Datenbanken ein Formular geben, das die Aktivitäten des Anwenders registriert!

Individuelle Erweiterung Ihrer Datenbanken

Um die Lösung in Ihren Datenbanken ein zusetzen, müssen Sie die Steuerelemente in jedem Formular anpassen, das Datensätze oder Tabellen blockieren könnte.

Das hört sich zunächst nach viel Auf wand an, aber glücklicherweise können Sie die meisten Einstellungen für mehrere markierte Steuerelemente auf einmal vornehmen:

  1. Öffnen Sie das gewünschte Formular im Entwurfsmodus, starten Sie den VBA-Editor und deklarieren Sie hier zunächst im allgemeinen Teil die globale Variable „TimeoutFlag“:

    Dim TimeoutFlag As Integer

  2. Geben Sie dann die folgende Funktion ein:Function TimeOut ()
    TimeoutFlag = 1
    End Function
  3. Diese Funktion ordnen Sie nun allen Steuerelementen in den Eigenschaften „Bei Taste“ und „Bei Mausbewegung“ zu. Markieren Sie alle Steuerelemente gemeinsam und rufen Sie den Eigenschaftendialog auf. An dieser Stelle können Sie die Ereignisprozeduren für alle Steuerelemente gemeinsam setzen, indem Sie hier jeweils „=TimeOut()“ eingeben.
  4. Öffnen Sie anschließend das Eigenschaftenfenster für das Formular, in – dem Sie einen Doppelklick in den grauen Bereich unter dem Detail – bereich ausführen. Die Eigenschaft „Tastenvorschau“ setzen Sie zunächst auf „Ja“. Tragen Sie dann in den Eigenschaften „Bei Taste“ und „Bei Mausbewegung“ ebenfalls „=TimeOut()“ ein.
  5. Danach markieren Sie der Reihe nach Seiten-/Formularkopf und -fuß so wie Detailbereich und stellen hier die Eigenschaft „Bei Mausbewegung“ auf „=TimeOut()“.

Auf diese Weise haben Sie nun sichergestellt, dass alle Anwenderaktionen entdeckt und über die Funktion „TimeOut() in der globalen Variablen „TimeoutFlag“ festgehalten werden. Klickt der Anwender in ein Feld, nimmt er eine Eingabe vor oder bewegt er die Maus über Felder und Formular, wird diese Aktion protokolliert. Beim Aufruf der Timer-Routine steht al so jeweils eine „1“ in der globalen Variablen „TimeoutFlag“.

Dazu gleich noch etwas mehr. Zu nächst muss aber die Timer-Routine aktiviert werden:

  1. Stellen Sie die Eigenschaft „Zeitgeberintervall“ des Formulars auf „180000“ (entspricht drei Minuten). Das bedeutet, dass die Ereignisprozedur des Timers alle drei Minuten aufgerufen wird.
  2. Markieren Sie bei der Eigenschaft „Bei Zeitgeber“ den Eintrag „Ereignisprozedur“ und klicken Sie auf die Schaltfläche mit den drei Punkten, um den VBA-Editor zu starten. Hier geben Sie folgende Anweisungen ein:Private Sub Form_Timer()
    If TimeoutFlag = 0 Then
    DoCmd.Close acForm,
    Me.Name, acSaveNo
    End If
    TimeoutFlag = 0
    End Sub

Die Ereignisprozedur des Timers prüft hier zunächst, ob die Variable „TimeoutFlag“ auf „0“ steht. Ist das der Fall, hat der Anwender drei Minuten nichts getan, das Formular wird geschlossen. Ansonsten wird „TimeoutFlag“ wieder auf „0“ zurückgesetzt. Bis zum nächsten Aufruf der Ereignisprozedur des Timers vergehen nun drei Minuten, in denen eventuell eine Aktion erfolgt und „TimeoutFlag“ wieder auf „1“ gesetzt wird.

Wir haben für Sie eine Beispieldatenbank vorbereitet, in der wir diese Technik bereits umgesetzt haben. Testen Sie den Mechanismus im Formular „Kunden“. Das Timer-Intervall haben wir zum schnelleren Testen auf zehn Sekunden eingestellt, sodass das Formular nach dieser Zeit ohne Ein gaben automatisch geschlossen wird.

Access automatisch beenden

Auf Wunsch können Sie aber nicht nur das aktuelle Formular schließen, sondern auch die komplette Datenbank bei Inaktivität beenden. Hier könnte man das Menüformular nutzen, das automatisch beim Start der Datenbank geöffnet wird:

  1. Setzen Sie die Eigenschaft „Zeitgeberintervall“ des Formulars auf „1.800.000“. Dieser Wert entspricht 30 Minuten. Bleibt das Menü also 30 Minuten ohne Aktivität des Anwenders angezeigt, wird die Datenbank verlassen bzw. Access beendet.
  2. Stellen Sie die Eigenschaft „Bei Deaktivierung“ des Formulars auf „[Ereignisprozedur]“ ein und geben Sie dort folgende Anweisung ein:Private Sub Form_Deactivate()
    Me.TimerInterval = 0
    End Sub
    Diese Anweisung sorgt dafür, dass beim Aufruf eines anderen Formulars der Timer des Menüformulars ausgeschaltet wird. Andernfalls würde das Menü nach drei Minuten wegen Inaktivität die Datenbank schließen und so die Arbeit in anderen Formularen sabotieren.
  3. Stellen Sie die Eigenschaft „Bei Aktivierung“ des Formulars auf „[Ereignisprozedur]“ ein und geben Sie die folgende Anweisung ein:Private Sub Form_Activate()
    Me.TimerInterval = 1800000
    End Sub
    Diese Prozedur sorgt dafür, dass nach dem Schließen des anderen Formulars und damit bei der Aktivierung des Menüformulars der Timer wieder eingeschaltet wird und damit alle 30 Minuten auf Inaktivität prüfen kann.
  4. Die Timer-Prozedur ändern Sie folgendermaßen ab:Private Sub Form_Timer()
    If TimeoutFlag = 0 Then
    DoCmd.Quit
    End If
    TimeoutFlag = 0
    End Sub
    Anstelle von „DoCmd.Close“ zum Schließen eines Formulars führen wir hier ein „DoCmd.Quit“ zum Verlassen aus.

In unserer Beispieldatenbank wird diese Technik im Formular „Hauptmenü“ demonstriert. Das Timer-Intervall wurde auf 60 Sekunden eingestellt, da mit Sie das Ergebnis schneller testen können.

Daten löschen (Tabellen, Abfragen, Formulare, usw.)

Als Entwickler stehen Sie immer wieder vor der Aufgabe, Objekte in externen Datenbanken löschen zu müssen. Für Objekte wie Tabellen oder Abfragen, deren Definition direkt als Auflistung des Database-Objektes vorhanden ist, können Sie dazu die folgende Routine einsetzen:

Sub DelTable(strDB As String, strTable as String)
Dim db As DAO.Database
Set db = DBEngine.Workspaces(0).
OpenDatabase(strDB)
db.TableDefs.Delete strTable
db.Close
Set db = Nothing
End Sub

Die Prozedur erwartet als ersten Parameter „strDB“ Laufwerk, Pfad und Dateiname der Datenbank, in der eine Tabelle gelöscht werden soll. Der zweite Parameter „strTable“ definiert die zu löschende Tabelle. Über die Methode „Delete“ der Auflistung „TableDefs“ wird dann die gewünschte Tabelle in der angegebenen Datenbank gelöscht. Ein Aufruf kann beispielsweise wie folgt aussehen:

DelTable, „Z:\Test\ Nordwind.mdb“, „Personal/Alt“

Mit dieser Zeile wird beispielsweise die Tabelle „Personal/Alt“ in der Datenbank „Z:\Test\Nordwind.mdb“ gelöscht. Eine Routine zum Löschen von Abfragen in externen Datenbanken ist nahezu identisch aufgebaut:

Sub DelQuery(strDB As String, strQuery as String)
Dim db As DAO.Database
Set db = DBEngine.Workspaces(0).OpenDatabase(strDB)
db.QueryDefs.Delete strQuery
db.Close
Set db = Nothing
End Sub

Als zweiten Parameter geben Sie hier den Namen der zu löschenden Abfrage an, die dann über die Methode „Delete“ der Auflistung „QueryDefs“ gelöscht wird.


Für Formulare, Berichte, Makros oder Module verwenden Sie die folgende Routine:

Sub DelObject(strDB As String, strObjectName As String, intObjectType As Integer)
Dim objAcc As
Access.Application
Set objAcc = New
Access.Application
objAcc.OpenCurrentDatabase strDB
objAcc.DoCmd.DeleteObject
intObjectType, strObjectName
objAcc.Quit
Set objAcc = Nothing
End Sub

Erster und zweiter Parameter, „strDB“ und „strObjectName“, legen Laufwerk, Pfad und Dateiname sowie den Namen des zu löschenden Objektes fest. Mit dem dritten Parameter geben Sie den Objekttyp über die Konstanten „acTable“, „acQuery“, „acForm“, „acReport“, „acMacro“ oder „acModule“ an. Diese Zusatzangabe ist notwendig, da zum Beispiel Berichte, Formulare und andere Objekte durchaus unter dem gleichen Namen in der Datenbank gespeichert sein können. Zum Löschen verwenden wir mit „DoCmd.DeleteObject“ eine Methode, die das Löschen beliebiger Objekte erlaubt. Sie können diese Routine also alternativ auch zum Löschen von Tabellen und Abfragen einsetzen. Ein Aufruf könnte z.B. so aussehen:

DelObject „Z:\Test\Nordwind.mdb“,“Umsatz“, acReport

Diese Anweisung löscht den Bericht „Umsatz“ in der Datenbank „Z:\Test\ Nordwind.mdb“.

Automatisches Backup beim Verlassen der Datenbank

Viele Anwender suchen nach einer Möglichkeit, die aktuelle Datenbank nach dem Verlassen per VBA-Prozedur automatisch in ein Backup-Verzeichnis zu kopieren.

Das ist aber leider nicht ohne Weiteres möglich, weil ab dem Moment, wo eine Datenbank geschlossen wird, keine Prozeduren mehr ausgeführt werden können.

Auch der Trick, entsprechende Anweisungen (FileCopy…) in einem versteckt angezeigten Formular in dessen Ereignisprozedur „Beim Schließen“ auszuführen, scheitert, da Access die Datenbank sperrt.

Lösen lässt sich diese Aufgabe jedoch in einer Kombination aus Batch-Datei und Verknüpfung wie folgt:

  1. Öffnen Sie ein Fenster mit einer Eingabeaufforderung und geben Sie dort die folgende Anweisung ein:

    edit Name.bat
    „Name“ ersetzen Sie dabei durch einen Namen für die Batch-Datei, also beispielsweise dem Namen der Datenbank. Achtung! Der Name darf nur maximal acht Zeichen lang sein!
  2. Geben Sie in Edit die folgenden Anweisungen ein:

    @echo off
    cls
    start /w msaccess.exe „Z:\Test\Name.mdb“
    copy „Z:\Test\Name.mdb“ „Z:\Datsi\Name.mdb“
    exit
    Pfad und Dateinamen passen Sie entsprechend Ihrer Umgebung an. Auch hier dürfen Dateinamen nicht länger als acht und Verzeichnisnamen nicht länger als elf Zeichen sein!
  3. Speichern Sie die Batch-Datei und verlassen Sie den Editor.
  4. Legen Sie auf dem Desktop eine Verknüpfung zu der eben erstellten Batch- Datei an. Über diese Verknüpfung wird die Datenbank künftig per Doppelklick und einem kleinen Umweg über die Batch-Datei geöffnet.

Der DOS-Befehl „start“ führt eine Anwendung, hier „msaccess.exe“, aus, wo – bei der Parameter „/w“ (wait, warten…) dafür sorgt, dass die weiteren Anweisungen erst ausgeführt werden, wenn die Anwendung beendet wurde.

Nach dem Beenden von Access wird dann per DOS-Befehl „copy“ eine Kopie angelegt.

Möchten Sie vor der Bearbeitung der Datenbank eine Sicherungskopie anlegen, so drehen Sie die Anweisungen einfach um:

@echo off
cls
copy „Z:\Test\Name.mdb“
„Z:\Datsi\Name.mdb“
start msaccess.exe
„Z:\Test\Name.mdb“
exit

Der Parameter „/w“ ist hier nicht mehr nötig, da die Kopie ja schon erstellt wurde und auf eine Beendigung von Access nicht mehr gewartet werden muss.

Der DOS-Befehl „start“ steht normalerweise ab Windows XP nicht mehr zur Verfügung. Er wurde von Microsoft aus Windows NT, 2000 und XP verbannt, ob wohl er dort einwandfrei funktioniert. Kopieren Sie „start.exe“ einfach aus einer alten Windows 9x-Installation (zu finden beispielsweise in C:\Windows\Command) in das Windows-Verzeichnis der NT-, 2000- oder XP-Installation, damit die oben gezeigte Lösung auch unter diesen Systemen funktioniert!

Allgemein

Allgemein
ÖffnenAutomatisches Backup beim Verlassen der Datenbank
ÖffnenDaten löschen (Tabellen, Abfragen, Formulare, usw.)
ÖffnenDatenbanken und Formulare automatisch schließen
ÖffnenDie wichtigsten Grundlagen zur VBA-Steuerung von Oulook
ÖffnenDownload ohne Internet-Explorer
ÖffnenEcho (Abläufe im Hintergrund ausführen)
ÖffnenFehler durch defekte Verweise
ÖffnenFeldnamen
ÖffnenProbleme mit Sendkeys unter Windows Vista
ÖffnenSQL-Anweisungen im Überblick
ÖffnenSQL-Server kostenlos für Access (PDF-Datei)
ÖffnenSummen zusammenzählen (DSUM)
ÖffnenVersteckte Objekte wieder sichtbar machen