- Code: Alles auswählen
ImportData.SETRANGE("Processed at", 0DT);
IF ImportData.FINDSET(TRUE, FALSE) THEN BEGIN
REPEAT
ProcessSingleImportData(ImportData);
ImportData.VALIDATE("Processed at", CREATEDATETIME(TODAY, TIME));
ImportData.MODIFY(TRUE);
COMMIT;
UNTIL ImportData.NEXT = 0;
END;
Die Funktion ProcessSingleImportData enthält dabei ein IF Codeunit.Run (mit GETLASTERRORTEXT schreibe ich dabei was in eine Protokoll-Tabelle).
Das ist denke ich im Grunde eine relativ übliche Aufgabe - man hat eine große Menge Daten und man möchte sie verarbeiten und weil man nicht möchte, dass der ganze Job abbricht, nur weil in einem einzigen Datensatz ein Fehler auftritt, arbeitet man mit IF Codeunit.RUN und speichert Fehler ggf. weg.
Allerdings bekomme ich folgende Fehlermeldung bei AusfĂĽhrung der IF Codeunit.RUN - Zeile:
Die unten aufgeführten C/AL-Funktionen sind während Schreibtransaktionen eingeschränkt, da mindestens eine Tabelle gesperrt wird. Form.RunModal ist in Schreibtransaktionen nicht zulässig. Codeunit.Run ist in Schreibtransaktionen nur zulässig, wenn der Rückgabewert nicht verwendet wird. OK := Codeunit.Run() ist z. B. nicht zulässig. Report.RunModal ist in Schreibtransaktionen nur zulässig, wenn RequestForm = FALSE. Report.RunModal(...,FALSE) ist z. B. zulässig. XmlPort.RunModal ist in Schreibtransaktionen nur zulässig, wenn RequestForm = FALSE gilt. XmlPort.RunModal(...,FALSE) ist z. B. zulässig. Verwenden Sie die COMMIT-Funktion, um die Änderungen vor dem Aufruf zu speichern, oder strukturieren Sie den Code anders.
Die Ursache ist der TRUE-Parameter in ImportData.FINDSET(TRUE, FALSE). Dabei passiert ein Locktable und deswegen kann man kein IF Codeunit.Run verwenden.
In der Hilfe zu FINDSET steht zum TRUE-Parameter:
Set this parameter to true if you want to modify any field value within the current key.
This parameter only applies if the ForUpdate parameter is true.
If you set this parameter to false, then you can still modify the records in the set, but these updates will not be performed optimally.
The default value is false.
Ich möchte schon, dass die Updates optimally performed werden. Aber ich möchte auch IF Codeunit.Run nutzen. Was soll ich tun?
Ich vermute mal fast, dass es in diesem Fall, bei dem ich ein Commit nach jedem Datensatz mache, sinnlos ist, den True-Parameter zu setzen und ich einfach mit Findset(False, False) arbeiten sollte (Lösung A)? Ansonsten könnte ich das Commit auch an den Anfang setzen, das würde dann auch mit Findset(TRUE, FALSE) funktionieren, nur ist der TRUE-Parameter in dem Fall dann witzlos, weil ich das Locktable durch das Commit direkt wieder aufhebe (Lösung B)?
Ich tendiere momentan zu Lösung A. Oder sollte man es komplett anders machen? Verbirgt sich hinter dem "will not be performed optimally" noch irgendwas, sodass der True-Parameter außer dem Locktable noch ein weiteres Feature bietet?
Vielen Dank euch!