Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Berechnungen bei AfterUpdate abwarten

Begonnen von MaWi, November 24, 2017, 17:03:04

⏪ vorheriges - nächstes ⏩

MaWi

Hallo alle zusammen

ich habe ein tabularisches formular.
Im Formularfuss habe ich ein Textfeld mit einer Summe
Das funktioniert soweit wunderbar.

Wenn mein Anwender eine Zahl in der Tabelle ändert, dann möchte ich die neue Summe in eine andere Tabelle schreiben.
Dazu verwende ich das Ereignis AfterUpdate.
Wenn ich aber in AfterUpdate auf das Feld mit der Summe zugreife, dann ist diese noch nicht berechnet. Sie hat noch immer den Wert bevor der Anwender eine Zahl in der Tabelle geändert hat.
Setze ich einen Breakpoint in den Code von After Update und halte das Programm für einen Moment an, dann ist die Summe berechnet und stimmt.

Wie kann ich das lösen, dass meine Summe berechnet wird, bevor ich mit dem Code darauf zugreife?

Vielen Dank für Hilfe

MzKlMu

#1
Hallo,
Zitatdann möchte ich die neue Summe in eine andere Tabelle schreiben.
es gibt eine ganz einfache Lösung: Gar nicht machen.
In einer Datenbank speichert man keine Werte die sich jederzeit berechnen lassen.
Nur wenn der berechnete Wert nicht gespeichert wird, ist er zuverlässig immer stimmig.

Was wird denn da berechnet und wozu soll der Wert in einer anderen Tabelle gespeichert werden?
Gruß Klaus

MaWi

Es ist eine Zeitdatenbank in welche herausgefunden werden muss ob in einer bestimmten Zeitspanne ein bestimmter Wert überschritten wird. Dies ist von sehr vielen Faktoren abhängig.
Wenn ein bereits gespeicherter Wert nachträglich angepasst wird, dann wird der gespeicherte Wert entsprechend überschrieben.
Es nicht zu machen ist eine ungeschickte Lösung, weil es in den Folgeberechnungen dermassen viel Berechnungen ergeben würde, dass es eben Sinn macht, das zu etappieren. Zudem ist es auch aus zeitlichen Gründen nicht geschickt, die gesamte Berechnung immer neu zu machen wenn nur der letzte Teil ausgegeben werden soll.

Und darum suche ich nach technisch funktionierenden Lösungen.

MaWi

Ok, ich kann Dir ein anderes, besser verständliches Beispiel machen.

Nehmen wir an, wir erfassen Stunden. Dies in einem tabelarischen Formular. Ich möchte im Ereignis AfterUpdate eine Warnung ausgeben, wenn die Summe aller Stunden 548 übersteigt.
Die Summe habe ich im Formularfuss in der Textbox tbSummeZeit. Wenn ich im Formular im Ereignis AfterUpdate auf me.tbSummeZeit.value greife, dann ist die Summe nicht aktuell, sondern sie zeigt die alte Summe. Erst wenn das Ereignis AfterUpdate fertig abgearbeitet ist, wird die Summe nach berechnet. Somit kann ich nie, beim Erfassen einer neuen Stunde prüfen ob die Summe aller Stunden bereits 548 überstiegen hat um eine Warnung auszugeben.

Wie löse ich das Problem?

Vielen lieben Dank und beste Grüsse

MzKlMu

Hallo,
welches Ereignis "After Update" Formular oder Feld ?
Gruß Klaus

MaWi

Formular. Ich denke, es macht sinn, wenn die Felder eines Datensatz alle ausgefüllt sind und dieser fertig gespeichert wurde, die weiteren Berechnungen anzustellen.

Auf den Feldern wäre es auch möglich, allerdings wird der Benutzer innerhalb eines Datensatzes mehrere Felder verändern. Und diese wiederum verändern das Zeit Feld. Also anders ausgedrückt, wird in Feld a oder b oder c etwas eingegeben, wird beim Verlassen dieses Feldes das Zeitfeld verändert.
Erst beim verlassen des Datensatz möchte ich die Gesamtberechnung abschliessen. Also AfterUpdate...

Vielen Dank für Deine Unterstützung.

MzKlMu

Hallo,
füge mal in das Ereignis noch ein Me.Recal ein. Das führt zur Neuberechnung der Felder. Mit "After Update" wird nicht berechnet.
Eventuell musst Du auch Me.Requery verwenden. Was allerdings den 1.Datensatz aktiviert.
Gruß Klaus

PhilS

Zitat von: MzKlMu am November 24, 2017, 19:45:12Eventuell musst Du auch Me.Requery verwenden. Was allerdings den 1.Datensatz aktiviert.
Ein Me.Refresh sollte ziemlich sicher ausreichen und bringt nicht das Problem mit sich, dass der Datensatz gewechselt wird.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

MzKlMu

Hallo,
Me.Refresh aktualisiert aber keine berechneten Felder das macht wie gesagt Me.Recalc.
Gruß Klaus

Lachtaube

Die Recalc-Methode des Formulars wertet alle berechnenden Ausdrücke (das sind die, die mit = eingeleitet werden) in Steuerelementinhalten aus, ohne den Datensatz zu speichern und sollte demnach, wenn sich Feldinhalte, die an Rechenausdrücken beteiligt sind, in den Nach Aktualisierung Ereignissen dieser Steuerelemente ausgelöst werden, um die Berechnung korrekt anzuzeigen.

Die Notwendigkeit, die Refresh-Methode auf das Formular abzusetzen, wäre dann gegeben, wenn Daten, auf denen die Berechnung fußt, auch extern Änderungen erfahren können, ohne dass dabei Datensätze gelöscht oder hinzugefügt werden.

Können die beiden zuletzt genannten Gegebenheiten nicht ausgeschlossen werden, wäre sogar ein Requery erforderlich.

Sowohl bei der Requery- als auch bei Refresh-Methode erfolgt auch eine Neuberechnung von Ausdrücken in Steuerelementen des Formulars.

PS: ich bin kein Freund vom Speichern berechneter Daten, es sei denn, sie sind in Stein gemeißelt, was bei Deiner Anwendung nicht der Fall zu sein scheint.

Andererseits muss man natürlich auch die Performance berücksichtigen. Dabei gilt es, auch das Datenmodell, die Feldindizierungen, beteiligte Abfragen und die Rechenanweisungen auf den Prüfstand stellen. Auch die Bereitstellung der Berechnung(en) in einer lokalen temporären Datenbank sollte man in Erwägung ziehen. Wenn das alles nicht passt, würde ich zumindest auch noch einen Zeitstempel neben dem errechneten Wert ablegen, damit man die Aktualität des Werts prüfen kann. Denn was nützt eine noch so schnelle Abfrage, wenn das Resultat letztendlich falsch (oder nicht aktuell) ist.

PPS: ab Access 2010 würde ich ein oder mehrere Datenmakros mit dem Speichern der Berechnung beauftragen, welche auch wirken, wenn die Daten außerhalb eines Formulars Änderungen erfahren.
Grüße von der (⌒▽⌒)

MaWi

Zitat von: MzKlMu am November 24, 2017, 19:45:12
Hallo,
füge mal in das Ereignis noch ein Me.Recal ein. Das führt zur Neuberechnung der Felder. Mit "After Update" wird nicht berechnet.
Eventuell musst Du auch Me.Requery verwenden. Was allerdings den 1.Datensatz aktiviert.

Hallo Klaus,

vielen lieben Dank für Deine Antwort. Recalc war die Lösung meines Problemes.
Ich bedanke mich ganz herzlich. Du kannst Dir nicht vorstellen, wie lange ich diese Lösung gesucht habe. Auch in den Microsoft Foren hatte ich verschiedene Anläufe genommen. Und hier hat es mit einer Frage eine Antwort gebracht. Super vielen lieben Dank Dir Klaus.