[gelöst] Hilfe bei Reporterstellung in NAV4.0

30. November 2006 12:21

Bin neu hier und mit der Programmierung in Navision noch arg am kämpfen. Daher entschuldigt bitte meine Anfrage. Handbücher und Hilfeindex in Navision konnten mir nicht helfen.

Ich möchte einen Report schreiben, der auf der Tabelle 5067 alle Einträge für eine Beziehung (B1) löscht und für die gleiche Kontaktnummer eine andere Beziehung (B2) in (B3) ändert.

Schritte:
Habe im DataItemTableView einen Filter auf die eine Beziehung (B1) gesetzt, um nur diese Beziehungen (B1) zu erhalten.
Damit ich aber auch auf die Beziehunge (B2) zugreifen kann, habe ich das gleiche DataItem (5067) ein weiteres Mal in den Report eingefügt und über die Kontaktnummer verlinkt. Hier setze ich in DataItemTableView den Filter auf die Beziehung (B2).

Problem:
Ich bin in der Lage, die Beziehung (B1) im Code OnAfterGetRecord mittels "5067.DELETE;" zu löschen, kriege aber das Ändern der Beziehung (B2) nicht hin.

Kann mir jemand von euch bitte helfen?

Vielen herzlichen Dank
Zuletzt geändert von avocadouno am 7. Dezember 2006 13:06, insgesamt 1-mal geändert.

30. November 2006 12:42

Hier wäre dein Quellcode schon hilfreich!

--- (EDIT) SORRY,
merke erst jetzt, dass ich das Problem falsch verstanden habe.
Folgendes hilft dir also nicht direkt, aber vielleicht indirekt (von wegen
Variable etc.) ---------


Grundsätzlich ist auch folgendes möglich:
Du benutzt nur ein DataItem, filterst auf B1 UND B2 und machst im OnAfterGetRecord-Trigger folgendes:

Definiere erst einmal einen lokalen Record locRecord vom selben Typ wie dein DataItem.

Code:
locRecord := AktuellerRecord (also Name DataItem);
IF Beziehung = B1 THEN BEGIN
  locRecord.DELETE(TRUE);
END ELSE BEGIN
  locRecord.VALIDATE(Beziehung, B3);
  locRecord.MODIFY(TRUE);
END;

30. November 2006 12:47

Da der Primärschlüssel für die Tabelle 5067 aus "Contact No.und "Job Responsibility Code" besteht, mußt du einen neuen Datensatz einfügen, und den alten löschen.


Code:
Dazu benötigst du eine Recordvariable

Name                             DataType     Subtype                       Length
Contact Job Responsibility_2     Record       Contact Job Responsibility


Contact Job Responsibility - OnAfterGetRecord()

If "Job Responsibility Code" = 'B1' Then
   DELETE;

If "Job Responsibility Code" = 'B2' Then Begin
   "Contact Job Responsibility_2".RESET;
   If NOT "Contact Job Responsibility_2".GET("Contact No.",'B3') Then Begin
      "Contact Job Responsibility_2".VALIDATE("Contact No.","Contact No.");
      "Contact Job Responsibility_2".VALIDATE("Job Responsibility Code",'B3');
      "Contact Job Responsibility_2".INSERT;
   END;
   DELETE;
END;


mfg Michael

(war wohl etwas zu langsam)

30. November 2006 12:56

Vielen Dank Leute

Ihr seid ja echt schnell. Werde das ausprobieren, sobald ich kann. Das ist aber leider erst nächste Woche. Werde dann natürlich auch das Thema auf "gelöst" ändern, wenn es denn funktioniert ;-)

5. Dezember 2006 11:59

Funktioniert leider noch nicht wie gewünscht.

Wie läuft das genau, wenn ein Kontakt mehrere Einträge in der Tabelle "Contact Job Responsibility" hat? Wird da jede einzelne Zeile einzeln angeschaut, oder sind beispielsweise 2 Einträge darin aus dem gleichen OnAfterGetRecord Trigger ansprechbar?
Mein Problem ist nämlich, dass nicht entweder Beziehung B1 oder B2 etwas auslösen, sondern die Kombination wenn B1 UND B2 vorhanden sein müssen. Das scheint mir aber nicht zu funktionieren. Habe das mit MESSAGE('TEST') versucht herauszufinden.
Oder habe ich da etwas falsch verstanden?

Danke für jeden Hinweis

5. Dezember 2006 12:03

OnAfterGetRecord durchläuft die Records immer sukzessive; das heißt, dass du genau einen gerade betrachtest.

Um B1 UND B2 zu prüfen, würde ich so vorgehen:
OnAfterGetRecord prüft zunächst B1.
Wenn B1 zutrifft, frage mit einer lokalen Record-Variable B2 ab (kannst du ja in eine Funktion ausgliedern und so den Boolean-Wert abfragen).

5. Dezember 2006 12:13

Eben diesen Link krieg ich nicht hin. Kannst Du mir dazu etwas mehr sagen, bitte?

5. Dezember 2006 12:17

Dafür brauch ich erst einmal deinen bisherigen OnAfterGetRecord-Trigger (hier als Text), bitte.

5. Dezember 2006 12:31

Hier mein bisheriger Code. Viel ist es noch nicht, weil ich noch nicht das gewünschte abfragen kann. Mit den beiden Message-funktionen will ich nur schauen, wie weit der Code funktioniert.

Code:
IF "Job Responsibility Code" = 'NO_TD' THEN BEGIN
   MESSAGE('TEST 1 %1',"Contact No.");
   IF "Job Responsibility Code" = 'SOT' THEN BEGIN
      MESSAGE('TEST 2 %1',"Contact No.");
      //hier käme der Code, um den Job Resp Code von 'SOT' nach 'BAV' zu wechseln.
   END;
   "Job Responsibility Code".DELETE
END;


Das Ziel wäre also bei einem Kontakt, der den JR Code 'NO_TD' hat, diesen zu löschen, und wenn er zusätzlich den JR Code 'SOT' hat, diesen nach 'BAV' zu ändern.

5. Dezember 2006 13:21

Hier mein Versuch (natürlich ungetestet):

Code:
IF "Job Responsibility Code" = 'NO_TD' THEN BEGIN

   IF locContJobResp.GET("Contact No.",'SOT') THEN BEGIN
      locContJobResp.Job Responsibility Code" := 'BAV';
      locContJobResp.MODIFY(TRUE);
   END;

   locContJobResp.GET("Contact No.","Job Responsibility Code");
   locContJobResp.DELETE;
END;


Ich weiß nur nicht, ob sich trotz der Vorsichtsmaßnehme mit der lokalen Record-Variable dennoch die Daten gegenseitig ins Gehege kommen ...

7. Dezember 2006 12:05

Irgendwie scheint das nicht zu funktionieren. Ich erhalte die Fehlermeldung Job Responsibility Code existiert nicht. Identifizierende Felder und Werte ... Job Responsibility Code= 'BAV'.

Ich kann sonst noch versuchen, das ganze etwas zu verdeutlichen:
Wenn ein Kontakt den "Job Responsibility Code" 'NO_TD' hat, soll dieser gelöscht werden.
Wenn der gleiche Kontakt neben 'NO_TD' noch den Code 'SOT' hat, soll 'SOT' durch 'BAV' ersetzt werden.

Oder so:
Aus
Kontakt1('NO_TD') wird Kontakt1()
Kontakt2('NO_TD','SOT') wird Kontakt2('BAV')

Kontakt3('SOT') bleibt Kontakt3('SOT')

7. Dezember 2006 12:26

nächster Versuch:
Code:
IF "Job Responsibility Code" = 'NO_TD' THEN BEGIN

   IF locContJobResp.GET("Contact No.",'SOT') THEN BEGIN
      IF locContJobResp.RENAME("Contact No.", 'BAV)' THEN;       
   END;

   locContJobResp.GET("Contact No.","Job Responsibility Code");
   locContJobResp.DELETE;
END;

7. Dezember 2006 12:44

Riesen DANKESCHÖN an Natalie und auch an mespelage. Es funktioniert jetzt.

Dein letzter Code hat die Lösung gebracht.

Ich muss gestehen, auf die Variante wäre ich nie im Leben gekommen. Das zeigt wieder einmal, wie wichtig es ist, seine Gedanken mit anderen teilen zu können.

Vielen Dank nochmals. Ich hoffe, ich kann auch irgendwann einmal helfen bei einem Problem. Will mich ja revanchieren können :-)

7. Dezember 2006 13:38

avocadouno hat geschrieben:Riesen DANKESCHÖN an Natalie und auch an mespelage. Es funktioniert jetzt.
Dein letzter Code hat die Lösung gebracht.

*freu*

Ich muss gestehen, auf die Variante wäre ich nie im Leben gekommen.

Dann vielleicht noch zur Erklärung, wie du bei sowas generell vorgehst:

Wenn du in einer Schleife (hier ist es zunächst die OnAfterGetRecord-Schleife) Datensätze löschen, hinzufügen oder Schlüsselwerte ändern möchtest, darfst du dies nicht in der ursprünglichen Schleifen-Variable (hier das Data-Item) tun, da du dir sonst den Schleifenablauf durch neue, geänderte oder fehlende Datensätze zerschießt.

Darum Änderungen zunächst und immer in einer lokalen Variable (= Kopie des aktuell betrachteten Datensatzes) vornehmen.

Nun zu dem Unterschied zwischen dem falschen und richtigen Code:
Wenn ich keine Schlüsselfelder ändere, benutze ich MODIFY.
Mit MODIFY sucht das System automatisch nach einem Datensatz mit denselben Schlüsselfeldern wie im Record. Das ist der Grund, warum es vorhin nicht geklappt hat: Es existierte ja noch kein Datensatz mit 'BAV' für den Kontakt; den wollten wir ja eben erst erzeugen.

Ändere ich Schlüsselfelder, muss ich unbedingt mit RENAME arbeiten. Hierfür ist es wichtig, den Record per GET oder FIND vorher unbedingt auf den zu ändernden Datensatz gesetzt zu haben.

Hoffe das war einigermaßen verständlich ;-)

7. Dezember 2006 13:44

Ich glaube, das verstehe ich. Jetzt. Aber wenn das einem nicht gesagt wird ist es nicht wirklich einfach, auf diese Idee zu kommen. Also nochmals herzlichen Dank.