30. April 2020 08:57
vandyke hat geschrieben:...Speichere doch das Flag in der Singleinstanz CU in einem TempRec. Sollte doch beim Rollback rückgängig gemacht werden....
30. April 2020 09:04
Mein erster Versuch war natürlich, die eigentliche Synchronisation in eine eigene Codeunit auszulagern und diese in dem EventSubscriber mit IF Codeunit.RUN zu starten.m_schneider hat geschrieben:indem du die Function SynchronizeFields in eine eigene CU ausgliederst
Weil nur bei diesem Feld eine Synchronisation mit Validate in das Zielfeld erfolgt, welches im OnValidate der Zieltabelle eine Prüfung hat, die einen Error auslösen kann.m_schneider hat geschrieben:Was ich mich frage, warum funktioniert es bei dem einen Feld und bei dem anderen nicht?
Es werden Feldwerte von der Verkaufszeile in die Arbeitsauftragszeile synchronisiert, aber auch (andere Feldwerte) von der Arbeitsauftragszeile in die Verkaufszeile.vandyke hat geschrieben:Also wird doch in beide Richtungen synchronisiert? Oder von der Zieltabelle in eine weitere Zieltabelle, ..., die dann irgendwann wieder zur Herkunftstabelle synchronisieren will?
Das mache ich ja so schon von Anfang an (siehe Screenshot1.png). Leider wird der Eintrag für 'SYNCHRONIZATION' in der TempTabelle bei einem Rollback nicht rückgängig gemacht und verbleibt dort somit mit seinem zugewiesenen Wert 'ACTIVE'.vandyke hat geschrieben:Speichere doch das Flag in der Singleinstanz CU in einem TempRec. Sollte doch beim Rollback rückgängig gemacht werden.
m_schneider hat geschrieben:Oder eventuell mit meinen angesprochenen Try-Functions.
Ihr habt das böse Wort (TryFunction) gesagt!vandyke hat geschrieben:Oder halt, wie hier schon erwähnt, mit der TryFunction.
30. April 2020 09:49
Timo Lässer hat geschrieben:Anscheinend gilt der Rollback nicht für Daten in temporären Tabellen.
....
SyncTable.Reset;
....
IF SyncTable.FINDSET(FALSE) THEN BEGIN
IF GlobalVarMgt.GETSYNC() THEN BEGIN
GlobalVarMgt.SETSYNC(FALSE);
EXIT;
END
ELSE
GlobalVarMgt.SETSYNC(TRUE);
REPEAT
//doSomeThings
UNTIL SynCTable.NEXT = 0;
END;
30. April 2020 10:39
Anfangs (im Jahr 2006) hatte ich in meiner SI-Codeunit für jede "anwendungsglobale" Variablesweikelt hat geschrieben:darf ich fragen, warum du den Wert, ob eine Synchro ausgeführt wird, oder nicht, in einem Feld einer tempTable speicherst, oder habe ich das total falsch verstanden?
Ich habe gerade versucht, ob sich etwas ändern würde, wenn ich für diesen konkreten Fall den Wert nicht über die universelle Set-/Get-Funktion in der temporären Tabelle, sondern "klassisch" in einer eigenständigen Variable in der SI-Codeunit ablege.sweikelt hat geschrieben:korrekt -> http://www.tharangac.com/2017/02/unders ... ction.htmlTimo Lässer hat geschrieben:Anscheinend gilt der Rollback nicht für Daten in temporären Tabellen.
Nein, durch das Rollback wird der OnAfterOnDatabaseModify nicht erneut ausgelöst. Der Anwender bleibt nur auf dem ungespeicherten Datensatz stehen.sweikelt hat geschrieben:Kommt es zum Fehler, findet das Rollback statt - was ja auch wieder OnDataBaseModify anstößt, oder?
Klingt leider nur im ersten Moment nach einer möglichen Lösung.sweikelt hat geschrieben:Wenn also in deiner Sync-Function geprüft wird, ob SyncActive, dann muss SyncActive vor dem EXIT wieder in der SI auf false gesetzt werden....
30. April 2020 10:52
Timo Lässer hat geschrieben:Nein, durch das Rollback wird der OnAfterOnDatabaseModify nicht erneut ausgelöst. Der Anwender bleibt nur auf dem ungespeicherten Datensatz stehen.
Erst, wenn er erneut versucht, den Datensatz zu verlassen (oder F5 drückt), möchte NAV diesen Datensatz speichern und löst OnAfterOnDatabaseModify aus.
--> ah, dann geht es natürlich nicht :'(Timo Lässer hat geschrieben:Das Problem ist, dass während der Synchronisation der Wert von dem Herkunftsdatensatz in mehrere Zieldatensätze in einer oder mehreren Zieltabelle(n) übertragen werden kann (und in der Realität auch wird).
Würde eine Abfrage auf SyncActive das Flag wieder zurücksetzen, dann würde der erste Modify auf einer Zieltabelle zwar keine weitere Synchronisation auslösen, aber schon ab dem zweiten Modify würde die Synchronisation eine Endlosschleife anstoßen.
30. April 2020 14:18
Timo Lässer hat geschrieben:Ich habe gerade versucht, ob sich etwas ändern würde, wenn ich für diesen konkreten Fall den Wert nicht über die universelle Set-/Get-Funktion in der temporären Tabelle, sondern "klassisch" in einer eigenständigen Variable in der SI-Codeunit ablege.sweikelt hat geschrieben:korrekt -> http://www.tharangac.com/2017/02/unders ... ction.htmlTimo Lässer hat geschrieben:Anscheinend gilt der Rollback nicht für Daten in temporären Tabellen.
Leider wird auch der Wert in der globalen Variable der SI-Codeunit bei einem Rollback nicht zurückgesetzt.
30. April 2020 14:40
Auch wenn es mir schwer fällt, "session-abhängige", kurzlebige Daten physikalisch in eine Tabelle zu schreiben, so ist das die einfachste und universellste Lösung für dieses Problem!m_schneider hat geschrieben:Dann bleibt ja eigentlich nur eine echte Tabelle mit echtem Datensatz. Der wird dann auch zurückgesetzt.
30. April 2020 14:50
Timo Lässer hat geschrieben:Auch wenn es mir schwer fällt, "session-abhängige", kurzlebige Daten physikalisch in eine Tabelle zu schreiben, so ist das die einfachste und universellste Lösung für dieses Problem!m_schneider hat geschrieben:Dann bleibt ja eigentlich nur eine echte Tabelle mit echtem Datensatz. Der wird dann auch zurückgesetzt.
Timo Lässer hat geschrieben:Michael, du hast dir beim nächsten Community-Treffen ein großes Bier verdient!
30. April 2020 17:29
4. Mai 2020 09:43
4. Mai 2020 13:20
LOCAL SetRecRefHeaderFromLine(VAR RecRefHeader : RecordRef;VAR RecRefLine : RecordRef;HeaderTableID : Integer)
RecRefLine.SETRECFILTER;
IF HeaderTableID = 0 THEN
HeaderTableID := RecRefLine.NUMBER - 1;
RecRefHeader.OPEN(HeaderTableID);
FOR i := 1 TO RecRefHeader.KEYINDEX(1).FIELDCOUNT DO BEGIN
FieldID := RecRefHeader.KEYINDEX(1).FIELDINDEX(i).NUMBER;
FldRef := RecRefHeader.FIELD(FieldID);
FldRef.SETRANGE(RecRefLine.FIELD(FieldID));
END;
RecordIsInFilterString(RecRef : RecordRef;FilterString: Text) : Boolean
IF FilterString = '' THEN
EXIT(TRUE);
RecRefCopy.SETRECFILTER;
ApplyFilters(RecRefCopy,FilterString);
IF RecRefCopy.ISEMPTY THEN
EXIT(FALSE);
EXIT(TRUE);
4. Mai 2020 13:37
8. Mai 2020 08:43
Timo Lässer hat geschrieben:Die "Header-Tabelle" ist aber nicht immer die Tabelle mit "Table No. - 1".
8. Mai 2020 08:52
Upps! Wer lesen kann, ist klar im Vorteil.vandyke hat geschrieben:Deswegen nimmt ja die gezeigte Funktion auch als Parameter die TableID auf :D