Discussion:
Schließen der Datenbank erzwingen
(zu alt für eine Antwort)
Gernot Adams
2003-11-20 13:46:57 UTC
Permalink
Hallo Allerseits,
ich habe in mehreren Datenbanken, die auf einem Server liegen, die
Möglichkeit eingebaut, sie zentral zu schließen (im Falle von
Verwaltungsarbeiten u.ä.). Dazu startet in jedem Datenbank-Frontend
automatisch ein ausgeblendetes Formular, welches in bestimmten Abständen
(Zeitgeber) ein Kontrollkästchen in einer Tabelle abfragt. Ist das
Kontrollkästchen markiert, wird die Datenbank über DoCmd.Quit geschlossen.
Code-mäßig sieht das so aus:

Private Sub Form_Timer()
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
End If
End Sub

Ich habe ebenfalls in jedem Formular der Datenbank eine Standardabfrage, die
im Falle von Datenänderungen abfragt, ob die Änderungen gespeichert werden
sollen. Das sieht so aus:

Dim strMsg As String
strMsg = "Data has changed."
strMsg = strMsg & "@Do you wish to save the changes?"
strMsg = strMsg & "@Click Yes to Save or No to Discard changes."
If MsgBox(strMsg, vbQuestion + vbYesNo, "Save Record?") = vbYes Then
'do nothing
Else
DoCmd.RunCommand acCmdUndo
End If

Jetzt mein Problem: wenn ich versuche, eine geöffnete Datenbank über das
Aktivieren des o.g. Kontrollkästchens zu schließen während in diese
Datenbank gerade ein neuer Datensatz eingetragen oder ein bestehender
geändert wird, dann wird die Datenbank natürlich nicht geschlossen, sondern
es erscheint erst noch die Sicherungsabfrage. Und wird Diese nicht
beantwortet, bleibt die Datenbank offen.

Eigentlich ist das ja auch völlig korrekt und das "Abschießen" einer DB
nicht gerade gentlemen-like. Aber ich hätte halt doch gerne die Möglichkeit,
in der gerade geschilderten Situation die Datenbank zu schließen und dabei
automatisch die die Sicherungsabfrage mit "Nein" zu beantworten.

Falls es keine Möglichkeit gibt, eine Datenbank so zu schließen, daß alle
wie auch immer gearteten anderen Anweisungen, Ereignisse oder Rückfragen
übergangen werden, dann denke ich, müßte der Code der Sicherungsabfrage so
erweitert werden, daß das "DoCmd.RunCommand acCmdUndo"-Ereignis entweder auf
Knopfdruck oder nach Ablauf einer Eingabefrist ausgelöst wird.

Kann mir jemand verraten, wie ich das anstellen könnte?

Danke für die Hilfe und Gruß
Gernot
Stefan Menner
2003-11-20 14:29:47 UTC
Permalink
Post by Gernot Adams
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
DoCmd.Quit kennt einen (optionalen) Parameter, der einen der folgenden Werte
annehmen kann:
-acQuitPrompt
-acQuitSaveAll
-acQuitSaveNone
Ich denke, die Namen sind selbsterklärend.
HTH,
Stefan
Gernot Adams
2003-11-20 14:38:20 UTC
Permalink
Hallo Stefan,
Post by Stefan Menner
Post by Gernot Adams
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
DoCmd.Quit kennt einen (optionalen) Parameter, der einen der folgenden Werte
-acQuitPrompt
-acQuitSaveAll
-acQuitSaveNone
Ich denke, die Namen sind selbsterklärend.
HTH,
Stefan
--------

-acQuitSaveNone habe ich natürlich auch probiert aber das funktioniert
nicht! Wenn ich das Quit-Ereignis auslöse, während ein anderes Formular
geöffnet ist und in diesem Formular gerade ein neuer Datensatz eingetragen
oder ein bestehender Datensatz verändert und noch nicht gespeichert worden
ist, dann erscheint zuerst die Sicherungsabfrage "Wollen Sie die Änderungen
speichern". Die Datenbank wird NICHT geschlossen - egal mit welchem
Parameter.

Gruß Gernot
Karl Günther
2003-11-20 14:49:57 UTC
Permalink
Hallo Gernot,

ich hab es zwar noch nicht über mehrere Formulare hinweg
probiert, das kriegts Du aber noch hin, aber es müsst mit
Sendkeys {ESC} funktionieren (na, ob die schreibweise
jetzt richtig ist?). Das sollte die Eingaben zurücksetzen,
als sei nichts eingegeben. Eventl. muss das zweimal
ausgeführt werden (1. für das bearbeitete Datenfeld 2. für
den gesamten Datensatz).

Gruß Karl
-----Originalnachricht-----
Hallo Stefan,
Post by Stefan Menner
Post by Gernot Adams
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
DoCmd.Quit kennt einen (optionalen) Parameter, der
einen der folgenden
Werte
Post by Stefan Menner
-acQuitPrompt
-acQuitSaveAll
-acQuitSaveNone
Ich denke, die Namen sind selbsterklärend.
HTH,
Stefan
--------
-acQuitSaveNone habe ich natürlich auch probiert aber das
funktioniert
nicht! Wenn ich das Quit-Ereignis auslöse, während ein
anderes Formular
geöffnet ist und in diesem Formular gerade ein neuer
Datensatz eingetragen
oder ein bestehender Datensatz verändert und noch nicht
gespeichert worden
ist, dann erscheint zuerst die Sicherungsabfrage "Wollen
Sie die Änderungen
speichern". Die Datenbank wird NICHT geschlossen - egal
mit welchem
Parameter.
Gruß Gernot
.
Gernot Adams
2003-11-20 15:24:21 UTC
Permalink
Hallo Karl,

"Karl G�nther" <***@discussions.microsoft.com> schrieb im Newsbeitrag news:0e4b01c3af75$90bf33b0$***@phx.gbl...
Hallo Gernot,

ich hab es zwar noch nicht über mehrere Formulare hinweg
probiert, das kriegts Du aber noch hin, aber es müsst mit
Sendkeys {ESC} funktionieren (na, ob die schreibweise
jetzt richtig ist?). Das sollte die Eingaben zurücksetzen,
als sei nichts eingegeben. Eventl. muss das zweimal
ausgeführt werden (1. für das bearbeitete Datenfeld 2. für
den gesamten Datensatz).

Gruß Karl

--------
kannst Du mir das etwas genauer erklären? Ich habe jetzt mal in meinem
ausgeblendeten Formular in den Code zusätzlich die Sendkey-Anweisung
eingebaut. Das sieht so aus:

Private Sub Form_Timer()
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
SendKeys "N", True
End If
End Sub

So, und jetzt aktiviere ich die checkbox "KillApplication", der Timer wartet
10 Sekunden. Nach den 10 Sekunden wird obiger Code ausgeführt und in meinem
anderen geöffneten Formular, in welchem gerade ein neuer Datensatz
eingetragen wird, poppt die Nachfrage hoch, ob ich die Änderung speichern
will. Und das war's dann. So wie ich Dich verstehe, sollte die
sendkey-Anweisung in der Message-Box jetzt Nein anklicken. Aber das passiert
nicht. Ich denke, der sendkey geht ins leere.

Habt Ihr noch andere Ideen?
Gruß Gernot
Christian Kaupa
2003-11-20 18:01:45 UTC
Permalink
Hallo Gernot,

ich denke, Karl meinte, Du sollst per Sendkeys 2x ESC schicken BEVOR du
Quit machst, damit etwaige Änderungen rückgängig gemacht werden und
die Speicherabfrage gar nicht erst hochkommt.

Gruß
Christian
Post by Gernot Adams
Hallo Karl,
Hallo Gernot,
ich hab es zwar noch nicht über mehrere Formulare hinweg
probiert, das kriegts Du aber noch hin, aber es müsst mit
Sendkeys {ESC} funktionieren (na, ob die schreibweise
jetzt richtig ist?). Das sollte die Eingaben zurücksetzen,
als sei nichts eingegeben. Eventl. muss das zweimal
ausgeführt werden (1. für das bearbeitete Datenfeld 2. für
den gesamten Datensatz).
Gruß Karl
--------
kannst Du mir das etwas genauer erklären? Ich habe jetzt mal in meinem
ausgeblendeten Formular in den Code zusätzlich die Sendkey-Anweisung
Private Sub Form_Timer()
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
DoCmd.Quit
SendKeys "N", True
End If
End Sub
So, und jetzt aktiviere ich die checkbox "KillApplication", der Timer wartet
10 Sekunden. Nach den 10 Sekunden wird obiger Code ausgeführt und in meinem
anderen geöffneten Formular, in welchem gerade ein neuer Datensatz
eingetragen wird, poppt die Nachfrage hoch, ob ich die Änderung speichern
will. Und das war's dann. So wie ich Dich verstehe, sollte die
sendkey-Anweisung in der Message-Box jetzt Nein anklicken. Aber das passiert
nicht. Ich denke, der sendkey geht ins leere.
Habt Ihr noch andere Ideen?
Gruß Gernot
Gernot Adams
2003-11-21 08:28:08 UTC
Permalink
Hallo Christian,
Post by Karl Günther
Hallo Gernot,
ich denke, Karl meinte, Du sollst per Sendkeys 2x ESC schicken BEVOR du
Quit machst, damit etwaige Änderungen rückgängig gemacht werden und
die Speicherabfrage gar nicht erst hochkommt.
Gruß
Christian
Post by Gernot Adams
--------
daß ist unlogisch: durch den Quit-Befehl wird ja überhaupt erst in den
anderen Formularen die Abfrage zum Speichern ausgelöst: erst passiert das
Ereignis DoCmd.Quit und als Konsequenz daraus erscheint die Speicherabfrage
in einem Formular. Wohin sollte ich vor einem DoCmd.Quit denn die Keys
schicken? In diesem Moment ist die Speicherabfrage ja noch gar nicht offen.
Das kann nicht funktionieren.

Gruß Gernot
Gernot Adams
2003-11-21 08:46:30 UTC
Permalink
Hallo Christian, hallo Karl
mein letztes Posting war blödsinn, ich hab nicht richtig gelesen. Mein
Problem wird tatsächlich mit zweimal ESC gelöst. Vielen Dank an Euch Beide!

Gruß Gernot
Post by Gernot Adams
Hallo Christian,
Post by Karl Günther
Hallo Gernot,
ich denke, Karl meinte, Du sollst per Sendkeys 2x ESC schicken BEVOR du
Quit machst, damit etwaige Änderungen rückgängig gemacht werden und
die Speicherabfrage gar nicht erst hochkommt.
Gruß
Christian
Post by Gernot Adams
--------
daß ist unlogisch: durch den Quit-Befehl wird ja überhaupt erst in den
anderen Formularen die Abfrage zum Speichern ausgelöst: erst passiert das
Ereignis DoCmd.Quit und als Konsequenz daraus erscheint die
Speicherabfrage
Post by Gernot Adams
in einem Formular. Wohin sollte ich vor einem DoCmd.Quit denn die Keys
schicken? In diesem Moment ist die Speicherabfrage ja noch gar nicht offen.
Das kann nicht funktionieren.
Gruß Gernot
Steffen Transchel
2003-11-21 09:27:33 UTC
Permalink
Hallo Gernot,
also ich würde einen ganz anderen Ansatz machen, als bisher diskutiert.
Das Problem ist ja nicht, das Access speichern möchte, sondern das die
MsgBox nicht beantwortet wird.
D.h. du brauchst eine MsgBox, die nur eine gewisse Zeit stehenbleibt, und
sich danach selbst schließt. Ich würde das ganz simpel mit einem
Popup-Formular, einer Funktion die es aufruft und einer Funktion , die eine
globale Variable setzt realisieren.
also z.B.

global Schaltflaeche
Function MyMsgBox(Text)
Schaltflaeche=vbCancel
DoCmd.OpenForm "frm_MyMsgBox", acNormal, , , , acDialog,Text
MyMsgBox=Schaltflaeche
end Function

Function Setze_Schaltflaeche(SF)
Schaltflaeche=SF
end Function

Und im Formular:
Private Sub Form_Timer()
Setze_Schaltflaeche(vbCancel)
docmd.close acForm, me.Name
end sub

Private Sub SF_OK_Click()
Setze_Schaltflaeche(vbOk)
end sub

Private Sub SF_Cancel_Click()
Setze_Schaltflaeche(vbCancel)
end sub


Steffen
Gernot Adams
2003-11-21 14:12:19 UTC
Permalink
Hallo Steffen,
Post by Karl Günther
Hallo Gernot,
also ich würde einen ganz anderen Ansatz machen, als bisher diskutiert.
Das Problem ist ja nicht, das Access speichern möchte, sondern das die
MsgBox nicht beantwortet wird.
D.h. du brauchst eine MsgBox, die nur eine gewisse Zeit stehenbleibt, und
sich danach selbst schließt. Ich würde das ganz simpel mit einem
Popup-Formular, einer Funktion die es aufruft und einer Funktion , die eine
globale Variable setzt realisieren.
also z.B.
global Schaltflaeche
Function MyMsgBox(Text)
Schaltflaeche=vbCancel
DoCmd.OpenForm "frm_MyMsgBox", acNormal, , , , acDialog,Text
MyMsgBox=Schaltflaeche
end Function
Function Setze_Schaltflaeche(SF)
Schaltflaeche=SF
end Function
Private Sub Form_Timer()
Setze_Schaltflaeche(vbCancel)
docmd.close acForm, me.Name
end sub
Private Sub SF_OK_Click()
Setze_Schaltflaeche(vbOk)
end sub
Private Sub SF_Cancel_Click()
Setze_Schaltflaeche(vbCancel)
end sub
Steffen
-------
Danke für's mitmachen auch an Dich.
Gruß Gernot
Olaf Rabbachin
2003-11-21 09:48:43 UTC
Permalink
Hi,
Post by Gernot Adams
Jetzt mein Problem: wenn ich versuche, eine geöffnete Datenbank über das
Aktivieren des o.g. Kontrollkästchens zu schließen während in diese
Datenbank gerade ein neuer Datensatz eingetragen oder ein bestehender
geändert wird, dann wird die Datenbank natürlich nicht geschlossen, sondern
es erscheint erst noch die Sicherungsabfrage. Und wird Diese nicht
beantwortet, bleibt die Datenbank offen.
platziere Deine Sicherungsabfrage ganz einfach in einem allgemeinen Modul
(wenn nicht ohnehin bereits geschehen).
Danach reicht Dir doch ganz einfach ein weiteres Abfragen des kill-flags -
ist es gesetzt, schenkst Du Dir die Sicherungsabfrage.

function checkSave(byref frm as form) as boolean
Dim strMsg As String
strMsg = "Data has changed."
strMsg = strMsg & "@Do you wish to save the changes?"
strMsg = strMsg & "@Click Yes to Save or No to Discard changes."

if not frm.dirty then exit function

If (DLookup("KillApplication", "tbl_UID")) = -1 Then
checkSave=True
else
checkSave= (MsgBox(strMsg, vbQuestion + vbYesNo, _
"Save Record?") = vbYes)
End If
end function

In Deinen Formularen dann einfach ein ...

if not checksave(me) then me.undo

Bis dann,
Olaf [MVP]
--
Bitte keine emails auf NG-postings.

My .02: www.Resources.IntuiDev.com
AccessFAQ: www.donkarl.com
KnowHow.mdb: www.freeaccess.de
Gernot Adams
2003-11-21 14:10:23 UTC
Permalink
Hallo Olfa
Post by Olaf Rabbachin
Hi,
platziere Deine Sicherungsabfrage ganz einfach in einem allgemeinen Modul
(wenn nicht ohnehin bereits geschehen).
Danach reicht Dir doch ganz einfach ein weiteres Abfragen des kill-flags -
ist es gesetzt, schenkst Du Dir die Sicherungsabfrage.
function checkSave(byref frm as form) as boolean
Dim strMsg As String
strMsg = "Data has changed."
if not frm.dirty then exit function
If (DLookup("KillApplication", "tbl_UID")) = -1 Then
checkSave=True
else
checkSave= (MsgBox(strMsg, vbQuestion + vbYesNo, _
"Save Record?") = vbYes)
End If
end function
In Deinen Formularen dann einfach ein ...
if not checksave(me) then me.undo
Bis dann,
Olaf [MVP]
----------

das ist clever! Danke für den Tipp!

Gruß Gernot
Gernot Adams
2003-11-21 14:15:58 UTC
Permalink
Hallo Olaf,
Post by Gernot Adams
Hallo Olfa
und sorry für den Verschreiber ;-)
Gruß Gernot

Loading...