[Gelöst] Setfilter Dezimalfeld <> 0

19. November 2016 11:11

LIebes Forum,
ich habe vor kurzem angefangen mich mit der Programmierung in Navision zu beschäftigen.
Aktuell stehe ich vor dem Problem, dass ich in einem Record einen Filter auf ein Dezimalfeld setzen möchte, um eine Division durch 0 zu vermeiden.
Irgendwie funktioniert der Filter aber leider nicht.
Es wäre toll, wenn ihr mir weiterhelfen könnten.
Ich bin leider noch ein Anfänger, was das betrifft.
Hier mein Versuch:

PlanningRec.SETFILTER("Real Planning Value",'<>0,00');
PlanningRec.MODIFYALL("Planning LUG","Running Planning Value" / "Real Planning Value");

Vielen Dank im Voraus.
Grüße Jürgen
Zuletzt geändert von Cybermad am 21. November 2016 12:11, insgesamt 1-mal geändert.

Re: Setfilter Dezimalfeld <> 0

19. November 2016 13:21

Das geht nicht mit MODIFYALL. Das kannst du nur verwenden, wenn alle Records (innerhalb des Filters) den gleichen! Wert in einem Feld bekommen sollen, und dieser schon vorher feststeht.
Durchlaufe also alle Records einzeln mit REPEAT.... UNTIL und verwende MODIFY.

Und was deinen Filter angeht:
PlanningRec.SETFILTER("Real Planning Value",'<>%1',0);

Re: Setfilter Dezimalfeld <> 0

20. November 2016 16:29

Danke für den Tip.
Habe folgendes versucht - funktioniert aber leider auch nicht.
Ich möchte gerne beim Öffnen des Formulars den Wert für alle Zeilen der Tabelle neu rechnen lassen.

Code:
IF PlanningRec.FINDSET THEN 
  BEGIN
    REPEAT
      IF PlanningRec
."Real Planning Value" > 0 THEN
          BEGIN
              PlanningRec
."Planning LUG" := PlanningRec."Running Planning Value" / PlanningRec."Real Planning Value";
              PlanningRec.MODIFY(TRUE);
          END
      ELSE
          BEGIN
            PlanningRec
."Planning LUG" := 0;
            PlanningRec.MODIFY(TRUE);
          END
    UNTIL PlanningRec
.NEXT = 0;
  END;

Re: Setfilter Dezimalfeld <> 0

20. November 2016 16:50

Habe ich für dich gerade gemacht, bitte beim nächsten Mal selber daran denken:
Dein Quelltext ist leichter zu lesen und zu verstehen, wenn du ihn zwischen so genannte Code-Tags setzt. Insbesondere deine Formatierungen werden so auch beibehalten.
Daher bitten wir dich, vor und nach deinem Quelltext diese Code-Tags einzufügen. Beispiel:

[code]Dein Quelltext[/code]


Dein Quelltext sieht soweit funktional aus. Ich würde ihn persönlich gemäß der allgemeinen C/AL-Konventionen (also so wie es der NAV-Standard auch macht) anders formatieren, aber das tut nichts zur Sache:
Code:
    IF PlanningRec.FINDSET(TRUE) THEN BEGIN // siehe Onlinehilfe, warum FINDSET mit Parameter TRUE
      REPEAT
        IF PlanningRec."Real Planning Value" <> 0 THEN BEGIN // <> statt > ?              
          PlanningRec."Planning LUG" := PlanningRec."Running Planning Value" / PlanningRec."Real Planning Value";               
        END ELSE BEGIN
          PlanningRec."Planning LUG" := 0;
        END;
        PlanningRec.MODIFY(TRUE);
      UNTIL PlanningRec.NEXT = 0;
    END; 


Was also heißt, "funktioniert nicht"? Wo bzw. wann genau rufst du den Quelltext auf?
Versuch es evtl. im OnInit-Trigger.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 08:54

OK,
bei OnInit wir der Coide ausgeführt.
Nun kommt der Hinweis "Sie können keine Änderungen an der Datenbank durchführen ehe eine Transaktion gestartet wurde."
Wie gesagt, ich bin noch neu in der Navision-Programmierung, aber das sieht recht komplizierrt aus.
Ich möchte ja nur beim Öffnen des Formulars eine Spalte in meiner Tabelle komplett neu rechnen lassen.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 09:18

Cybermad hat geschrieben:Nun kommt der Hinweis "Sie können keine Änderungen an der Datenbank durchführen ehe eine Transaktion gestartet wurde."

Ich habe es befürchtet ... Es gibt mehrere Lösungsansätze. Zunächst: Dient das Feld PlanningRec."Planning LUG" nur der Information für den Benutzer vorm Bildschirm, oder muss es wirklich ein fester, gespeicherter Wert in der Tabelle sein, nach welchem man auch suchen und filtern können muss? Im ersten Fall können wir den Wert auch zur Laufzeit berechnen und anzeigen, immer aktuell, und ohne MODIFY, das die Fehlermeldung verursacht. (Wie das geht, sage ich dann bei Bedarf später).

Re: Setfilter Dezimalfeld <> 0

21. November 2016 09:41

Ich benötige den Wert in der Tabelle, um später damit weiterrechnen zu können.
Da die Tabelle bereits mit Werten gefüllt ist, müsste ich zunächst einmal den Wert für alle Datensätze berechnen.
Ggf. muss ich hier noch mit einem Trigger (OnValidate())den Wert berechnen lassen, sobald etwas geändert wird.
Das mache ich - soweit ich weiß dann in der Tabelle.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 10:18

Cybermad hat geschrieben:Ggf. muss ich hier noch mit einem Trigger (OnValidate())den Wert berechnen lassen, sobald etwas geändert wird.
Das mache ich - soweit ich weiß dann in der Tabelle.
Ganz genau, so sollte das - für echte Tabellenfelder - immer gemacht werden, und nicht etwa über einen Stapellauf im Nachhinein.
Am einfachsten erstellst du in der Tabelle eine Funktion UpdatePlanningLUG (oder ähnlich), welche du im OnValidate der Felder "Running Planning Value" und "Real Planning Value" aufrufst.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 10:38

Mein Problem dabei ist nur, dass die beiden Felder nicht editierbar sind (alos wird OnValidate() nicht ausgeführt).
Das Feld PlanningLUG soll einfach nur berechnet und in der Form dargestellt werden.
Ich weiß nur nicht ob es hierzu überhaupt einen Trigger gibt.
Daher war ja mein erster Ansatz den Wert in einem Tabellenfeld zu speichern.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 10:57

Cybermad hat geschrieben:Mein Problem dabei ist nur, dass die beiden Felder nicht editierbar sind (alos wird OnValidate() nicht ausgeführt).

Das stimmt so nicht. Wodurch werden die Felder denn überhaupt gefüllt? Diese Funktion muss es nur mit VALIDATE(Feldname,Feldwert) statt Feldname := Feldwert tun, dann wird auch der OnValidate-Trigger der des Tabellenfeldes ausgeführt.

Das Feld PlanningLUG soll einfach nur berechnet und in der Form dargestellt werden.

Vorhin hast du noch etwas anderes gesagt.
Entscheide dich bitte, ob du den Planning LUG nun speichern möchtest, oder nicht.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 11:18

OK,
ich habe gerade überlegt, welche der Möglichkeiten die Optimale wäre.
Grundsätzlich habe ich mir in der Tabelle ein Feld (PlanningLUG) erstellt.
Die beiden zur Berechnung notwendigen Spalten bestehen (jetzt) aus 2 FlowFields (Laufende Summe über Monatswerte der aktuellen Tabelle und Lookup auf andere Tabelle in der der 2. Wert enthalten ist)
Diese Werte müssen nicht editierbar sein.
Mir gelingt es nur nicht das leere Tabellenfeld (PlanningLUG) zu berechnen.

Mein erster Ansatz war also beim Öffnen der Form den Wert berechnen zu wollen und diesen dann Satzweise in der Tabelle zu speichern.
Dann bin ich dazu gekommen den Wert auf Tabellen(Satz-)ebene berechnen zu wollen.
Mir fehlt allerdings dazu der Trigger, der auch ausgeführt wird.
Wie gesagt ich bin neu in der Programmierung von Navision.
Ich weiß leider derzeit nicht welches der Weg ist um in dem Feld einfach nur einen Wert zu berechnen.

In der gleichen Tabelle habe ich so etwas ähnliches für eine Prozentberechnung gemacht.
Der Unterschied hierbei ist aber, dass der Prozentwert eingegeben und dann mit OnValidate() die Berechnung korrekt durchgeführt wird.

Trotzdem Besten Dank.

Re: Setfilter Dezimalfeld <> 0

21. November 2016 11:29

Dann speichern wir PlanningLUG nicht als Tabellenfeld ab, sondern zeigen es nur frisch berechnet in der Form mittels eines Funktionsaufrufs an.

Kann bitte jemand anders die Erklärung hierfür übernehmen? Ich habe jetzt keine Zeit mehr :(

Re: Setfilter Dezimalfeld <> 0

21. November 2016 11:53

Hallo,

dann versuche ich mal den Part von Natalie weiter zu spinnen. :-D

Was wir also zunächst benötigen ist eine globale dezimal Variable nennen wir Sie mal "PlanningLUG".

Dann programmierst du im "OnAfterGetRecord" und im "OnAfterGetCurrentRecord" mal folgendes:
Code:
PlanningLUG := 0;
CALCFIELDS( "Running Planning Value","Real Planning Value");
IF "Real Planning Value" <> 0 THEN             
  PlanningLUG := "Running Planning Value" / "Real Planning Value";               


Als letztes musst du die Variable in der Page noch austauschen, mit einer Caption versehen und auf "Editable=FALSE" setzen.

Gruß Fiddi

Re: Setfilter Dezimalfeld <> 0

21. November 2016 12:10

Super,
Vielen Dank Euch Beiden.
Das hilft mir weiter.
Grüße
Jürgen