PDA

Vollständige Version anzeigen : Ereignis-Gerangel: Exit, Lost Focus & Co..


Struppi73
21.02.2008, 18:35
Hallo zusammen,

folgendes Problem: Ich habe ein Formular, in dem ich Sendungsdaten (Empfängeradresse, Sendungsgewicht, Sendungswert etc.) erfassen möchte. Für die Empfängeradresse gibt es eine Tabelle, in der bereits sehr viele Adressen gespeichert sind, die häufig benutzt werden. Abrufbar sind sie über die Adressnummer.

Das erste Eingabefeld im Formular ist nun die Adressnummer. Dieses Feld frage ich mit dem Exit-Ereignis ab: Wurde eine gültige Adressnummer eingegeben, holt er die Adresse aus der Tabelle und füllt die Adressfelder damit. Ist es keine gültige Nummer, gibt´s nen Hinweis, und man beginnt von vorne mit der Eingabe. Hat man das Feld ganz leer gelassen, gibt´s ne MsgBox, ob man die Adresse manuell eingeben möchte. Das funktioniert alles wunderbar.

Nun hab ich aber unten rechts eine Befehlsschaltfläche "Abbrechen". Die sollte JEDERZEIT erreichbar sein. Solange ich mich aber im o.g. Adressnummern-Eingabefeld befinde, kann ich nicht auf "Abbrechen" klicken. Der Exit-Ereignishandler fängt mir diesen Versuch sofort ab.

Ich grüble und grüble, aber irgendwie komme ich auf keine Lösung. Hat jemand einen Vorschlag? (Hinweis: DB besteht aus Front- und Backend, die Formulare sind nicht verknüpft, ich programmiere alles komplett in VBA mit DAO)

achtelpetit
21.02.2008, 22:49
Nimm doch nicht Exit sondern update als Ereignis

Struppi73
22.02.2008, 14:37
hallo achtelpetit,

danke für deinen tipp.

alle ereignisse, die ablaufen, wenn ich das Feld für die Adressnummer-Eingabe verlasse (exit, before update, after update, lostfocus), finden zeitlich VOR dem Klick-Ereignis statt, das abläuft, wenn ich auf die Befehlsschaltfläche "Abbrechen" klicke. Das heißt, die Prüfroutine wird auf jeden Fall aufgerufen, auch wenn ich das bei einem Klick auf Abbrechen gar nicht möchte.

im moment verfolge ich den Ansatz, alle Prüfroutinen in eine Sub zu packen. Für jedes Steuerelement im Formular rufe ich diese Sub im "Enter"-Ereignis auf. Anhand eines Flags, das jeweils für das Steuerelement gesetzt wird, in dem man sich gerade befindet, erkennt die Prüfroutine, aus welchem Steuerelement man gerade kommt (d.h. welches Steuerelement zuletzt den Focus hatte). Davon abhängig läuft dann ggf. eine Prüfroutine, und das flag wird wieder gelöscht. Klickt man auf Abbrechen, wird dann eben keine Prüfroutine aufgerufen.

das ganze wird funktionieren, wird aber auch ziemlich aufwändig. weiß vielleicht jemand noch eine alternative?

Anne Berg
22.02.2008, 15:45
Hallo,Anhand eines Flags, ... erkennt die Prüfroutine, aus welchem Steuerelement man gerade kommtDas liefert dir auch ohne weiteres Screen.PreviousControl.

Struppi73
22.02.2008, 17:10
*hmmmmpf*

bin gerade fertig geworden, die ganzen routinen für die flag-lösung zu schreiben.. :(

hilft nix, auch wenn´s super funktioniert, es ist überflüssiger schnickschnack und muss wieder raus. danke, Anne, für deinen hinweis! :)

gibt es irgendwelche einschränkungen für die verwendung von "screen.previouscontrol", von denen ich noch wissen sollte, bevor ich alles wieder umschreibe? :rolleyes:

Anne Berg
22.02.2008, 19:47
Hallo Dirk, das tut mir jetzt aber leid... ;)

Das "Problem", dass es evtl. kein Vorgängerfeld gibt, weil es das erste ist, wirst du ja so oder so berücksichtigen müssen - mehr fällt mir dazu so spontan nicht ein. Vielleicht noch, dass das Screen-Objekt im Debug-Modus nicht ausgewertet werden kann, da das aktive Fenster zu dem Zeitpunkt ja der VBA-Editor ist, aber auch damit lässt sich's leben.

Zu deinem Ausgangsproblem fällt mir leider auch nichts neues ein, ich wundere mich nur, dass ich es selbst offenbar noch nicht hatte. Ich bin in einem ähnlichen Fall folgendermaßen vorgegangen:
- Auswahl bestehender Datensätze über ein ungeb. Kombifeld im Formularkopf
- Eingabe neuer Datensätz über einen Button mit autom. Generierung eines neuen Zugriffsschlüssels
- Abbrechen über einen Button inkl. Löschen des neu erzeugten Datensatzes
Somit habe ich es vermieden, auf Feldereignisse reagieren zu müssen. Plausibilitäts- und Vollständigkeitsprüfungen mache ich im Form_Before/AfterUpdate-Ereignis.

Hoffe, das hilft dir weiter.

Struppi73
22.02.2008, 20:28
Vielen Dank für deine Mühe, Anne! :)

Mein größtes Problem derzeit ist, dass ich seit ca. einem Jahr kein VBA mehr programmiert habe und irgendwie "draussen" bin. Eigentlich schon peinlich, was ich hier für Fragen stellen muss.. *g*

Dein Lösungsansatz ist nachvollziehbar - klar, damit könnte ich auf die Ereignisse verzichten. Dafür muss ich aber für jeden neuen Datensatz einmal die Maus in die Hand nehmen, und genau das will ich vermeiden. Es geht hier um ein sehr spezielles Tool, mit dem manuell sehr schnell große Mengen von Wertsendungen erfasst werden sollen. Das Zeitfenster für die Sendungserfassung ist sehr klein. Deshalb versuche ich, das Verhalten des Eingabeformulars sehr intuitiv und vollständig per Tastatur bedienbar zu machen. Ich könnte ja auch einen Button für "Manuelle Adresseingabe" hinsetzen - werde ich auch. Aber man soll auf ihn verzichten können; lässt man das Feld für die Adressnummer leer, öffnet er automatisch ein Fenster für die manuelle Eingabe der Adresse usw.. Wenn alle Angaben für die Sendung eingegeben sind, "schluckt" er die Sendung automatisch und bietet einem eine neue leere Maske für die nächste Sendung an. Deshalb muss ich sehr viel im Hintergrund prüfen und valuieren.

Anne Berg
22.02.2008, 21:08
Ich habe das noch nie gebraucht, aber kann man Buttons nicht auch über Tastaturbefehle erreichen, mit Shortcuts?

Struppi73
22.02.2008, 21:33
Das wäre möglich, klar. Aber auch das will ich in dem speziellen Fall vermeiden. Sozusagen eine manuelle Stapelverarbeitung.. ;)

Johnny Loser
23.02.2008, 10:12
Hi Dirk,

meine Lagerverwaltung funktioniert vollständig Maus-frei. Für die Weiterbearbeitung der Eingabe im Textfeld bediene ich mich der KeyDown-Funktion:

Private Sub T_BARCODE_KeyDown(KeyCode As Integer, Shift As Integer)
On Error GoTo BARCODE_ERR
If KeyCode = 13 Then 'Aktion nur ausführen bei Return
Select Case T_BARCODE.text
...

Nur bei Return wird die Eingabe übernommen.

Den Button "Abbrechen" dann noch in der Eigenschaft Abbrechen auf Ja setzen, dann sollte es doch gehen, oder ?

Struppi73
23.02.2008, 12:01
Ich versuche im "GotFocus"-Ereignishandler der Steuerelemente auf meinem Formular "Screen.PreviousControl" abzufragen. Ergebnis ist grundsätzlich "Null" (Nz(Screen.PreviousControl) = "").

Ist mir unerklärlich, woran könnte das liegen?

Übrigens habe ich das für eines der Steuerelemente auch mit dem MouseUp-Ereignis getestet..
Private Sub Wert_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
MsgBox Nz(Screen.PreviousControl)
End Sub..Ergebnis ist genauso ein Leerstring :(

@Johnny Loser: So sollte es gehen.

Struppi73
23.02.2008, 12:17
bin mit Blindheit geschlagen...... :mad:

Screen.PreviousControl.Name liefert das gewünschte Ergebnis! Ist doch logisch, aahh..

Trotzdem Danke! :rolleyes: