[gelöst]Modify

15. November 2018 17:59

Hallo.

Habe ein Report programmiert.
Wollte auf Test in einer Bestellung ein Feld mit der Bestellnummer füllen.
Hab ein Modify gemacht und er hat die Nummer im Feld eingetragen, aber jetzt fehlen andere Daten in den Zeilen, wie Artikelnummer und Bezeichnung.
Was habe ich falsch gemacht?

Code:
IF purchHead.FIND('-') THEN REPEAT
  IF purchHead."No." = 'BE552890' THEN
  BEGIN
    purchLine.SETFILTER(purchLine."Document No.",purchHead."No.");
    purchLine.SETFILTER(purchLine.Type,'Artikel');
    IF purchLine.FIND('-') THEN     
      REPEAT
        IF purchLine."Document No." = 'BE552890' THEN
          BEGIN
            purchLine.INIT;
            purchLine."Req. Document No.":=purchLine."Document No.";
            purchLine.MODIFY;
          END;
      UNTIL purchLine.NEXT=0;
      //purchLine.MODIFY;
    END;
UNTIL purchHead.NEXT=0;
Zuletzt geändert von navCH am 16. November 2018 10:25, insgesamt 1-mal geändert.

Re: Modify

15. November 2018 23:25

Code:
Purchline.init

Weglassen!

Re: Modify

16. November 2018 09:42

Purchline.init weglassen

Ok.
Werde vorsichtshalber noch die Felder durch validieren.
Zuletzt geändert von navCH am 16. November 2018 10:09, insgesamt 1-mal geändert.

Re: Modify

16. November 2018 10:03

Werde vorsichtshalber noch die Felder durch validieren.


Kannst Du machen, solltest Du aber nicht.
Die Purchline ist ja eine bestehende Einkaufszeile. Du willst ja nur ein Feld mit einem neuen Wert ergänzen.
Mit dem Init, hast Du die Feldwerte gelöscht, lass das Init weg, dann passiert das nicht mehr.
Wenn Du jetzt wieder alle Felder validierst, werden die Daten in der Einkaufszeile wieder mit den Stammdaten überschrieben, das willst Du doch nicht?

Martin

Re: Modify

16. November 2018 10:13

Wenn Du jetzt wieder alle Felder validierst, werden die Daten in der Einkaufszeile wieder mit den Stammdaten überschrieben, das willst Du doch nicht?

Nein will ich nicht.
Hat ohne Init funktioniert.
Vielen Dank!

Gruß
Christian

Re: [gelöst]Modify

16. November 2018 12:59

Init leert alle Felder ausser die des Primärschlüssels. Ein anschließendes Modify schreibt die Felder dann wirklich mit Leer.
Es ist immer eine gute Idee den Code nochmal zu refaktorieren auf Einfachheit und Lesbarkeit.
Siehe https://clean-code-developer.de/die-grade/


Vorher:
Code:
IF purchHead.FIND('-') THEN REPEAT
  IF purchHead."No." = 'BE552890' THEN
  BEGIN
    purchLine.SETFILTER(purchLine."Document No.",purchHead."No.");
    purchLine.SETFILTER(purchLine.Type,'Artikel');
    IF purchLine.FIND('-') THEN     
      REPEAT
        IF purchLine."Document No." = 'BE552890' THEN
          BEGIN
            purchLine.INIT;
            purchLine."Req. Document No.":=purchLine."Document No.";
            purchLine.MODIFY;
          END;
      UNTIL purchLine.NEXT=0;
      //purchLine.MODIFY;
    END;
UNTIL purchHead.NEXT=0;


Nachher:
Code:
IF PurchaseHeader.FINDSET THEN
  REPEAT
    IF PurchaseHeader."No." = 'BE552890' THEN BEGIN
      PurchaseLine.SETFILTER("Document No.",PurchaseHeader."No.");
      PurchaseLine.SETFILTER(Type,'Artikel');
      PurchaseLine.Modifyall("Req. Document No.",PurchaseLine."Document No.");
    END;
  UNTIL PurchaseHeader.NEXT=0;


Erläuterung:
Findset ist Find('xyz') meistens (möglicherweise eben nicht immer) vorzuziehen. Willst du nur Lesen machst du Findset
Willst du ein Modify machen machst du Findset(True)
Willst du den Primärschlüssel ändern aka. Rename machst du ein Findset(true,true)

Da du den Header nur liesst für die Documentennummer ist der Header nur im lesenden Zugriff die Zeile aber im schreibenden mit Modifyall.

Modifyall braucht ebenso wie Deleteall keine Schleife weil alles innerhalb des Filters modifiziert / gelöscht wird.

Re: [gelöst]Modify

16. November 2018 13:46

Wie wär's mit:
Code:
IF PurchaseHeader.FINDSET THEN
  REPEAT
    IF PurchaseHeader."No." = 'BE552890' THEN BEGIN
      PurchaseLine.SETFILTER("Document No.",PurchaseHeader."No.");
      PurchaseLine.SETFILTER(Type,'Artikel');
      PurchaseLine.Modifyall("Req. Document No.",PurchaseHeader."No.");
    END;
  UNTIL PurchaseHeader.NEXT=0;

Man beachte den Unterschied beim 2. Parameter des MODIFYALL.

Re: [gelöst]Modify

16. November 2018 15:00

Wie wärs mit :

Code:
SetReqDocNo(DocumentNo : Code[20])
  WITH PurchaseLine DO BEGIN
    SETFILTER("Document No.",DocumentNo);
    SETFILTER(Type,Type::Item);
    MODIFYALL("Req. Document No.",DocumentNo);
  END;

Re: [gelöst]Modify

16. November 2018 15:04

@JM ja
@shove nein Never ever WITH DO ;) den rest schon

Re: [gelöst]Modify

16. November 2018 16:34

Es ist immer eine gute Idee den Code nochmal zu refaktorieren auf Einfachheit und Lesbarkeit.
Siehe https://clean-code-developer.de/die-grade/

Interessantes Paradigma! Nobody is perfect.
Automatisierung der Korrektheitsprüfung. Wo fängt sie an, wo hört sie auf?
:-)

Re: [gelöst]Modify

16. November 2018 17:51

@NavCH ich schreibe dir das ja genau weil du das besser machen kannst.
Mir wurde damals auch geholfen von jemandem der meinen Code stark reduzieren konnte und heute ist es so toll.
Du musst weniger mergen, du musst weniger lesen und kommst beim debuggen schneller zum Punkt.

Automatisierung der Korrektheitsprüfung. Wo fängt sie an, wo hört sie auf?

Eine ausgezeichnete Frage.

Es gibt seit NAV 2009 ein automatisches Testframework für Dynamics Nav.

Die Creme de la Creme der Solution Center erkennst du in der Regel daran das sie A eine Versionskontrolle(Git,TFS,Mercurial und SVN in der Regel) haben und B eine automatische Testumgebung.

https://www.youtube.com/watch?v=1XCJzRF3c8U

Die Idee ist das du:
1. eine leere DB/Standard DB erstellst gerne auch mit Docker (Einfacher)
2. Deine Objekte importierst -> Test 1 alles kompiliert ok
3. Deine Tests importierst -> Ok
4. Deine Testdaten generierst -> OK
5. Deine Tests abfährst. -> Ok
6. Alles was vorher ging, geht immer noch der Kunde kann das Release haben.

Angenommen du erstellst eine Rechnung mit 100 CHF an Debitor XY wäre ein einfacher Test das buchen und gucken ob die Mehrwertsteuer mit 107,7 korrekt ist.

Es gibt eine Rollback Funktion die dann deine Testdaten wieder auf Start zurückrollen.
Davon ausgehend baust du gleich den zweiten Test und gibst mal 10% Rabatt und prüfst auch hier ob das erwartete Ergebnis rauskommt.
Dann machst du das mal mit Fremdwährung oder nagelst die letzten Bugs die du gefixed hast gleich mit einem Test fest das sie nie wieder auftreten.

Siehe auch das Video in meiner Signatur. Das habe ich da extra drin. :lol:

Re: [gelöst]Modify

19. November 2018 20:05

Nody3000 hat geschrieben:Erläuterung:
Findset ist Find('xyz') meistens (möglicherweise eben nicht immer) vorzuziehen.
Willst du nur Lesen machst du Findset
Willst du ein Modify machen machst du Findset(True)
Willst du den Primärschlüssel ändern aka. Rename machst du ein Findset(true,true)


Nur zu Klarstellung: Der zweite Parameter im FINDSET steht für UpdateKey. FINDSET(TRUE,TRUE) ist nötig wenn man ein Feld im Schlüssel ändern will, nicht nur beim Primärschlüssel, sondern bei jedem verwendeten Schlüssel.