[Gelöst] Codeunitverarbeitung stoppen

2. August 2010 15:38

Hallo zusammen,

ist es möglich eine Codeunit ähnlich wie einen Report stoppen zu lassen?
In der Codeunit 11 gibt es folgende Abfrage:
Code:
IF GenJnlLine.Fehler > 0 THEN
  FIELDERROR(Fehler,Text50000);


Ich möchte den FIELDERROR nun abfangen, mir die Fehlermeldung in einer Tabelle merken und das verbuchen beenden wie es der FIELDERROR tut.
Allerdings klappt dies nicht mit EXIT. Mein Code sieht folgendermaßen aus:

Code:
IF GenJnlLine.Fehler > 0 THEN BEGIN
  ParamVerw.HoleInteger(LfdNr);
  ParamVerw.HoleBoolean(AutoStapel);
  IF AutoStapel THEN BEGIN
    BelStapeleingelesen.GET(LfdNr);
    BelStapeleingelesen.Fehler := TRUE;
    BelStapeleingelesen.Fehlertext := FORMAT(Fehler) + Text50000;
    BelStapeleingelesen.MODIFY(TRUE);
    EXIT;
  END ELSE
    FIELDERROR(Fehler,Text50000);
END;


Gibt es da eine andere Möglichkeit??

Viele Grüße
Herdi
Zuletzt geändert von Herdi am 20. September 2010 13:45, insgesamt 1-mal geändert.

Re: Codeunitverarbeitung stoppen

2. August 2010 15:42

EXIT wirkt sich nur auf die aktuelle Funktion aus, in der sich der Quelltext befindet. Wenn auch andere Funktionen stoppen sollen, so musst du das EXIT an die aufrufenden Funktionen hochreichen.

Re: Codeunitverarbeitung stoppen

2. August 2010 15:45

Macht das denn überhaupt Sinn, dass du entweder deine eigene Fehlerverarbeitung startest oder in den Fielderror springst?

Re: Codeunitverarbeitung stoppen

2. August 2010 15:49

Wie meinst du das?

Mein Code wird in der Funktion RunCheck(Rec,TempJnlLineDim) ausgeführt.
Diese Funktion wird im OnRun-Trigger der Codeunit aufgerufen.
Muss ich dann den Aufruf von

Code:
RunCheck(Rec,TempJnlLineDim);

zu

Code:
IF NOT RunCheck(Rec,TempJnlLineDim) THEN
  EXIT;


umbauen?

edit:
Allerdings ist um meinen Code noch ein
Code:
WITH GenJnlLine DO BEGIN

gebaut. Wirkt sich das Exit nur auf diese Schleife aus?

Re: Codeunitverarbeitung stoppen

2. August 2010 16:03

Herdi hat geschrieben:edit:
Allerdings ist um meinen Code noch ein
Code:
WITH GenJnlLine DO BEGIN

gebaut. Wirkt sich das Exit nur auf diese Schleife aus?

Nein, auch auf die Funktion, in der der das EXIT verwendet wird.
Der Funktions-Quelltext nach EXIT wird ignoriert.

Edit:
EXIT Statement
An EXIT statement is used to interrupt the execution of a C/AL trigger. The interruption takes place even when the code is executed inside a loop or a similar structure. The EXIT statement is also used when a local function should return a value.

Re: Codeunitverarbeitung stoppen

2. August 2010 16:16

Herdi hat geschrieben:Ich möchte den FIELDERROR nun abfangen, mir die Fehlermeldung in einer Tabelle merken und das verbuchen beenden wie es der FIELDERROR tut.
Allerdings klappt dies nicht mit EXIT.

Genau, weil ein EXIT mit deiner Anforderung nichts zu tun hat :-)
Ich glaube, du meintest das hier:

Code:
IF GenJnlLine.Fehler > 0 THEN BEGIN
  ParamVerw.HoleInteger(LfdNr);
  ParamVerw.HoleBoolean(AutoStapel);
  IF AutoStapel THEN BEGIN
    BelStapeleingelesen.GET(LfdNr);
    BelStapeleingelesen.Fehler := TRUE;
    BelStapeleingelesen.Fehlertext := FORMAT(Fehler) + Text50000;
    BelStapeleingelesen.MODIFY(TRUE);
    COMMIT; // siehe Bemerkung unten!
  END;
  FIELDERROR(Fehler,Text50000);
END;

Denn FIELDERROR soll deiner obigen Beschreibung nach in jedem Fall weiter ausgeführt werden.
Nur: Nach dem FIELDERROR wird die Änderung in Record BelStapeleingelesen verworfen. Von daher könntest du ein COMMIT nach dem MODIFY ausführen.

Aber wofür nun das Ganze ...?

Re: Codeunitverarbeitung stoppen

2. August 2010 19:18

Natalie hat geschrieben:
Code:
IF GenJnlLine.Fehler > 0 THEN BEGIN
  ParamVerw.HoleInteger(LfdNr);
  ParamVerw.HoleBoolean(AutoStapel);
  IF AutoStapel THEN BEGIN
    BelStapeleingelesen.GET(LfdNr);
    BelStapeleingelesen.Fehler := TRUE;
    BelStapeleingelesen.Fehlertext := FORMAT(Fehler) + Text50000;
    BelStapeleingelesen.MODIFY(TRUE);
    COMMIT; // siehe Bemerkung unten!
  END;
  FIELDERROR(Fehler,Text50000);
END;

Denn FIELDERROR soll deiner obigen Beschreibung nach in jedem Fall weiter ausgeführt werden.
Nur: Nach dem FIELDERROR wird die Änderung in Record BelStapeleingelesen verworfen. Von daher könntest du ein COMMIT nach dem MODIFY ausführen.

Aber wofür nun das Ganze ...?
Oftmals benötigt man für (automtische) Verarbeitungen ein Log in dem fehlerhafte Aufrufe dokumentiert sind. Oftmals begibt man sich aber auch mit der von Natalie - aufgrund des benötigten Rückgabewertes völlig korrekten COMMIT - in eine Hölle aus der es kein Entkommen mehr gibt :)
Ein COMMIT jagt das andere und an Stelle X passt ein COMMIT nicht, da eine Transaktion dann nur halb im System liegt und inkonsistente Daten vorhält. Will sagen: Ich kann obige oder auch allgemein EINE Lösung unter Zuhilfenahme von COMMIT nur in wirklich eindeutigen, geplanten und sehr gründlich recherchierten Ausnahmesituationen empfehlen!

Ich bin mir bewusst, dass dieser Post unter NAV 4.x abgelegt ist, aber ich empfehle bei einer solchen Anforderung mindestens ein (technisches) Update auf NAV 5.0 SP1 (Update 2). In der Version gibt es die zwei Befehle GETLASTERRORTEXT und CLEARLASTERROR mit denen man in einem CODEUNIT.RUN-Konstrukt super Fehler abfangen und auch protokollieren kann.

Re: Codeunitverarbeitung stoppen

5. August 2010 11:04

SilverX hat geschrieben:Oftmals benötigt man für (automtische) Verarbeitungen ein Log in dem fehlerhafte Aufrufe dokumentiert sind. Oftmals begibt man sich aber auch mit der von Natalie - aufgrund des benötigten Rückgabewertes völlig korrekten COMMIT - in eine Hölle aus der es kein Entkommen mehr gibt :)


Genau dieses Vorgehen habe ich im Sinn gehabt. Der Standard bricht bei dem Fielderror mit einer Fehlermeldung ab. Da ich aber alle Zeilen automatisch Buchen möchte, wenn kein Fielderror vorliegt kommt mir ein Abbruch ungelegen.

SilverX hat geschrieben:Ich bin mir bewusst, dass dieser Post unter NAV 4.x abgelegt ist, aber ich empfehle bei einer solchen Anforderung mindestens ein (technisches) Update auf NAV 5.0 SP1 (Update 2). In der Version gibt es die zwei Befehle GETLASTERRORTEXT und CLEARLASTERROR mit denen man in einem CODEUNIT.RUN-Konstrukt super Fehler abfangen und auch protokollieren kann.


Der Update lässt bei uns noch ein wenig auf sich warten. Aktuell wird im Zuge eines neuen WMS geprüft ob sich die WebServices von NAV 2009 für unsere Zwecke eignen, dann würden wir ein technisches Update auf diese Version machen. Darauf kann ich aber nicht warten ;-)

Natalie hat geschrieben:Denn FIELDERROR soll deiner obigen Beschreibung nach in jedem Fall weiter ausgeführt werden.
Nur: Nach dem FIELDERROR wird die Änderung in Record BelStapeleingelesen verworfen. Von daher könntest du ein COMMIT nach dem MODIFY ausführen.

Aber wofür nun das Ganze ...?


Das Ganze soll mir ein LOG füllen und nur die Buchung der aktuellen, fehlerhaften Zeile(n) überspringen.
Der Fielderror bricht aber die komplette Verarbeitung ab und das möchte ich umgehen, deswegen schreibe ich mir die Fehlermeldung ins LOG. Aber die restliche Verarbeitung soll, für Zeilen ohne Fehler weiterlaufen...
Ich hoffe das klappt überhaupt...

Re: Codeunitverarbeitung stoppen

20. September 2010 13:45

So, nach langer Abstinenz von diesem Thema (Urlaub und Co.) habe ich auch eine simple Lösung für das Problem gefunden!

Und zwar habe ich in der Tabelle, die durch die Codeunit verarbeitet weren soll, einen Kenner eingefügt in dessen Abhängigkeit die Verarbeitung der Codeunit gestartet wird oder eben nicht. Damit muss ich mir keine Gedanken mehr machen, wie ich die Codeunit abfange.

Viele Dank für eure Hilfe!

Gruß Herdi