[Gelöst] - [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 13:41

Hi,

ich steh gerade auf den Schlauch...

So war ich doch der Annahme das :
Code:
locSalesHeader.SETCURRENTKEY("Document Type","No.");
locSalesHeader.SETRANGE("Document Type", locSalesHeader."Document Type"::Order);
locSalesHeader.SETRANGE("Cash Registration Order",TRUE);
locSalesHeader.SETRANGE(Status,locSalesHeader.Status::Open);

IF locSalesHeader.FINDSET THEN BEGIN
  REPEAT
  IF (locSalesHeader.DELETE(TRUE) = TRUE ) THEN BEGIN
    Message('deleted');
  END ELSE BEGIN
    MESSAGE('could not delete');
  END;
  UNTIL locSalesHeader.NEXT = 0;
END;


ich ein OK oder nicht Ok von IF DELETE zurück bekomme,
wenn nicht gelöscht werden kann kommt die passende Meldung (Gelieferte Verkaufszeilen vorhanden, Verknüpfte Bestellung vorhanden oder was auch immer)

Kann man das irgendwie handlen ohne den ganzen Code aus dem OndeleteTrigger von SalesHeader zu übernehmen?

Danke
gruß
Peter
Zuletzt geändert von elTorito am 25. Oktober 2012 15:33, insgesamt 1-mal geändert.

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 13:56

Ein Test-Löschen ist nicht möglich, ohne tatsächlich den gesamten Code aus dem OnDelete-Trigger separat auszuführen oder anderweite Objektanpassungen vorzunehmen.




Wenn du jedoch bezweckst, mit deinem Code einen Stapel an Verkaufsköpfen zu löschen:

Siehe C/SIDE Reference Guide (Onlinehilfe) zum Rückgabewert von DELETE:
true if the record was deleted. false if the record was not deleted because it could not be found in the table or if the user did not have the correct permissions. If the C/AL code terminates, false is returned


IF DELETE ist also nicht geeignet, die Löschungen bei Nichtgelingen abzufangen (wenn es nicht gerade an einem fehlenden Recht liegt).
Was du allerdings tun kannst: eine Codeunit die Löschung durchführen lassen.
Hierzu die Codeunit-Eigenschaft mit TableNo = 36 pflegen und diese Codezeile in den OnRun-Trigger packen:
Code:
DELETE(TRUE);


Dein o.g. Code muss nur noch auf diese Codeunit umgeswitcht werden (bitte deine Codeunit dort als Variable deklarieren:

Code:
...
IF locSalesHeader.FINDSET THEN BEGIN
  REPEAT
  IF DeineCodeunit.RUN(locSalesHeader) THEN BEGIN
    Message('deleted');
  END ELSE BEGIN
    MESSAGE('could not delete');
  END;
  UNTIL locSalesHeader.NEXT = 0;
END;


Du könntest dir mit diesem Gerüst sogar die Fehlermeldung ausgeben lassen, an der die Löschung gescheitert ist:
Code:
...
IF locSalesHeader.FINDSET THEN BEGIN
  REPEAT
  IF DeineCodeunit.RUN(locSalesHeader) THEN BEGIN
    Message('deleted');
  END ELSE BEGIN
    MESSAGE(GETLASTERRORTEXT); // <--- Neu
  END;
  UNTIL locSalesHeader.NEXT = 0;
END;


Diese Konstrukt verhindert jedenfalls, dass der Durchlauf nach dem ersten Fehler komplett abgebrochen wird.

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 14:14

Natalie hat geschrieben:Ein Test-Löschen ist nicht möglich, ohne [...] anderweite Objektanpassungen vorzunehmen.


Damit meinte ich, eine Codeanpassung in Tabelle 36, falls du darauf die Berechtigungen hast.
Dort neue Funktion zum Setzen einer globalen Variablen schreiben. Wenn diese Variable gesetzt ist, im OnDelete-Trigger ganz unten (wenn also kein Fehler vorher ausgegeben worden wäre), ein ERROR('wäre gelöscht worden') ausgeben.

In deinem Quelltext müsste dann vor dem eigentlichen locSalesHeader.DELETE(TRUE) diese neue Funktion zum Setzen der Variablen aufgerufen werden.

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 15:01

Hallo Natalie,

die Variante mit der Codeunit funktioniert.

Ich fände es allerdings schade dafür ein CU Objekt zu opfern *geiz ist geil * :twisted:

Würde daher die Variante mit der Sales Header Tabelle favorisieren, Zugriff ist vorhanden, habe dich aber glaube ich nicht ganz verstanden :-? .

Habe dort nun eine Funktion eingefügt und Globale Variable:

Code:
CheckIfDelByJobQueueIsPossible {
    DeleteByJobQueuePossible = TRUE;
}


Als letzte Zeile im OnDeleteTrigger dann:

Code:
IF (DeleteByJobQueuePossible = TRUE) THEN BEGIN
  ERROR('Wäre durch Job Queue gelöscht worden');
END;


In Meiner Codeunit dann:
Code:

IF locSalesHeader.FINDSET THEN BEGIN
  REPEAT
  locSalesHeader.CheckIfDelByJobQueueIsPossible;
   
    IF locSalesHeader.DELETE(TRUE) THEN BEGIN
      MESSAGE(locSalesHeader."No." + ' ' + 'DELETED');
    END ELSE BEGIN
      MESSAGE(locSalesHeader."No." + ' ' + GETLASTERRORTEXT);
    END;
 
  UNTIL locSalesHeader.NEXT = 0;
END;


Feuert nach wie vor Fehler wenn löschen nicht geht, was ja auch logisch ist, weil der ja erst gar nicht bis zum Ende des OnDeleteTrigger kommt .

Setze ich ein
Code:
NoErrorsWhileDelete := TRUE;

Am Ende des OnDeleteTrigger und in der FUnktion weise ich :

Code:
CheckIfDelByJobQueueIsPossible {
         DeleteByJobQueuePossible := NoErrorsWhileDelete;
       EXIT(DeleteByJobQueuePossible);
}

zu. Bringt das auch nichts , läuft auch nicht durch.

Hmm. Meintest du das denn so ? Oder anders?

Danke.
Gruß
Peter

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 15:15

Lieber eine Codeunit verballern als in Prozesse eingreifen, die man evtl. gar nicht versteht ;-)
Auch so kann man sparen ;-)

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 15:28

Das geht nur über eine Zusatz-Codeunit. Nur wenn du darüber mit IF RUN den Error abfängst, läuft es weiter durch.
Hier hast Du im IF einen Error erzeugt und dann bricht er den Prozess ab.
Du machst ja mit der Codeunit ja auch nicht ein IF DELETE, sondern ein IF RUN.
Das sind 2 Paar Schuhe.

Wenn man Deinen Code zusammendampft kommt dabei raus

Code:
REPEAT
  IF NOT DELETE THEN
     ERROR();
until next = 0;


Nun läuft die schleife aber nicht weiter wenn da ein error auftritt. Es bricht komplett ab mit roleback.

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 15:28

Nur mit der zusätzlichen Codeunit kannst du alle SalesHeader in einer Schleife durchlaufen und erfolgreich ja/nein abfangen.
Die Lösung mit dem Sales Header bezog sich nur auf die Frage, ob man quasi zum Test löschen kann.
Um die Codeunit wirst du also nicht herum kommen.

Re: [CC] - IF Record.DELETE .. mach was..

25. Oktober 2012 15:33

Ahso. Hab verstanden.

Spätestens nach
Lieber eine Codeunit verballern als in Prozesse eingreifen, die man evtl. gar nicht versteht

War die Codeunit am Drücker ;-)

Ich machs jetzt mit der Codeunit. Vielen Dank euch beiden.

Und Danke das es das Forum gibt, wüßte manchmal nicht wie ich Ohne klar kommen würde :mrgreen: