Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

aus Access heraus bestimmte Access-DB-Instanz identifizieren

Begonnen von Doming, März 24, 2026, 13:26:55

⏪ vorheriges - nächstes ⏩

Doming

Hallo,

Public Sub DBOeffnen()
 Dim accApp As Object
    Set accApp = CreateObject("Access.Application")
    accApp.OpenCurrentDatabase "C:\TestDB.accdb"
    set accApp as Nothing
End Sub

Wie bekomme ich im Nachhinein die aufgerufene DB per VBA wieder geschlossen?
Ich möchte die aufrufende DB nicht beenden, auch keine andere Db, die evtl. noch offen sein könnte.
Kann man die bestimmte Access-Instanz irgendwie identifizieren um sie später explizit wieder zu schließen?
accApp.CloseCurrentDatabase bezieht sich doch dann auf die aufrufende, weil aktive Instanz, oder?

Gruß
 Doming

Knobbi38

Hallo Doming,

hast du eigentlich schon einmal in der Dokumentation nachgelesen, welche Aktion bei "Application.CloseCurrentDatabase" ausgeführt wird? Ich denke, damit sollte deine Frage beantwortet sein.

Noch ein Hinweis:
Wenn du Automation verwendest, solltest du unbedingt darauf achten, alle verwendeten Ressourcen in der richtigen Reihenfolge wieder freizugeben. Andernfalls kann es zu Problemen kommen. In diesem Zusammenhang vermisse ich beispielsweise ein Application.Quit.

Knobbi38

PhilS

Zitat von: Doming am März 24, 2026, 13:26:55Kann man die bestimmte Access-Instanz irgendwie identifizieren um sie später explizit wieder zu schließen?

accApp.CloseCurrentDatabase bezieht sich doch dann auf die aufrufende, weil aktive Instanz, oder?
Am einfachsten wäre es, wenn du deine accApp-Variable nicht in der Prozedur deklarierst, sondern außerhalb, so dass sie erhalten bleibt (auch kein Set accApp = Nothing). Da accApp genau die Access-Instanz meint, die du wieder schließen willst, kannst du dich dann direkt darauf beziehen.

Es könnte/sollte auch funktionieren die gesuchte Instanz zu erhalten, wenn du GetObject mit dem Dateipfad verwendest.
Set accApp = GetObject("C:\TestDB.accdb")

Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Doming

#3
Der Hintergrund zu diesem vorgehen ist folgender:
Ich habe eine Datenbank (TestDB), deren einziger Zweck ist, Daten für andere Datenbanken aufzubereiten. Sie checkt Tabellen auf Vollständigkeit und ergänzt sie. Die Db habe ich ausgelagert, weil der Job teilweise zeitintensiv ist und der Nutzer nicht auf die Ausführung warten soll. Die Datenbank schreibt ihre Tätigkeit in die Protokolltabelle und die Datenbanken, die die aufbereiteten Daten nutzen, starten diese ext. DB zyklisch, wenn Bedarf besteht. Die TestDB beendet sich selbst nach dem Durchlauf.

Nun möchte ich, dass die aufrufende DB, wenn sie beendet wird, checkt, ob die TestDB noch läuft oder ob sie sich evtl aufgehangen hat. Nicht, dass sie noch im Hintergrund einen Task blockiert. Deswegen die Prüfung des letzten Zeitstempels (siehe anderer thread).

@Knobbi38 CloseCurrentDatabase übersetze ich nach Wortlaut mit ,,Schließe laufende DB", das ist für mich die aufrufende DB und die soll ja weiterlaufen. Aber ich habe es jetzt eingebaut.

       Set rs = CurrentDb.OpenRecordset("SELECT * " _
                                      & "FROM tbl_Wartungsprotokoll " _
                                      & "WHERE Autor = '" & Environ("Username") _
                                      & "' ORDER BY tID")
        If Not rs.EOF Then
            rs.MoveLast
            If DateDiff("s", rs!Zeit, Now) > 300 Then 'Wenn 5 Min nichts passiert ist -> Ende
                accApp.CloseCurrentDatabase
                Set accApp = Nothing
            End If
        End If

Es will offenbar funktionieren, denn die TestDb fragt nach, ob sie sich beenden soll.
Ich habe in meine DB eine Abmeldeprozedur eingebaut. Es gibt eine Tabelle, die protokolliert, wann welche DB geöffnet wird. Dort sollen sich die DB auch wieder abmelden (ihren Datensatz löschen). Deswegen ist das stumpfe Abmelden mit Beenden-X unterbunden.

Edit: Mit accApp.Run "Abmelden" wird die Abmeldeprozedur der TestDb eingeleitet, so funktioniert es also. Allerdings bleibt die Frage:

Wenn sich die DB aufgehangen hat, würde sie auf den Abmeldebefehl nicht reagieren, müsste also mit taskkill beendet werden. Nur, wie finde ich den richtigen Task heraus?

Gruß
Doming

Knobbi38

Hallo Doming,

schau dir nochmal die "Remarks" zu CloseCurrentDatabase, dann wird die Verwendung deutlicher als nur bei einer wörtlichen Übersetzung.

Laut deiner Beschreibung sollte aber die aufrufende DB gar nicht in die TestDB schließen, sondern diese beendet sich ja offensichtlich selber. Diese TestDB unabhängig vom aktuellen Status einfach zu "killen" halte ich für keine gute Idee und ist, wie bereits ausgeführt, nicht notwendig. Warum sollte sich die TestDB denn aufhängen? Im Übrigen würde ich hier nicht einfach nur einen Timestamp verwenden, sondern einen Status inkl. Timestamp in einer Logdatei fortschreiben, möglicherweise sogar in einer externen Logdatei, falls die TestDB doch mal nicht mehr reagiert.

Wenn du trotzdem genau die TestDB identfizieren möchtest, solltes die ihre eigene PID ermitteln und als Property für die aufrufende DB bereitstellen. Dann kannst du in der aufrufenden DB per Shell/Tasklist prüfen, ob diese PID noch existiert oder ob sich die TestDB beendet hat.

Knobbi38

PhilS

Zitat von: Doming am Heute um 07:13:07CloseCurrentDatabase übersetze ich nach Wortlaut mit ,,Schließe laufende DB", das ist für mich die aufrufende DB und die soll ja weiterlaufen.
Das ist zwar richtig, muss aber ausgehend vom Objekt der Methode, also accApp, gesehen werden. Du schließt die aktuelle offene DB in der anderen Access-Instanz.


Zitat von: Doming am Heute um 07:13:07Wenn sich die DB aufgehangen hat, würde sie auf den Abmeldebefehl nicht reagieren, müsste also mit taskkill beendet werden. Nur, wie finde ich den richtigen Task heraus?
Das (gewaltsame) Beenden einer Access-Instanz hatte ich mal in diesem Video behandelt: https://youtu.be/nlux9J8nWxk
Du musst dann die Logik trennen, so dass dein Worker-DB die Informationen nach Aussen liefert, um ihren Prozess zu identifizieren. Das dann direkt nach dem Start, weil es nicht mehr funktionieren dürfte, wenn sie erstmal hängt.

Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor