[Gelöst] Daten in Tabelle Laufende Nummer

15. Mai 2018 15:44

Hallo zusammen.

ich möchte Zeilen von einer Tabelle1 in eine andere Tabelle2 schreiben.
Wie schreibe ich ans Ende der Tabelle1, ohne vorhandene Zeilen zu überschreiben?
Etwa so:
Code:
IF Tabelle2.Find('-') Then Repeat
     IF Tabelle1.Find('+') Then Begin
         Tabelle.Next;
         Tabelle1."Nr.":=Tabelle2."Nr.";
         Tabelle1."Dokument-ID":=Tabelle2."Document ID";
         Tabelle1.Insert;
     End;
Until Tabelle2.NEXT(+1)=0;

Das ist erstmal nur ein Code um die Daten stumpf ab der letzetn Zeile einzutragen.
Das schon übertragene Daten, nicht mit übertragen werden, kommt erst noch.
Jemand ne Idee, wie ich das mache?

Grüße Christian
Zuletzt geändert von navCH am 23. Mai 2018 17:15, insgesamt 2-mal geändert.

Re: Daten in Tabelle eintragen

15. Mai 2018 16:26

Vielleicht wäre INIT statt Next die bessere Wahl?
Etwa so:
Code:
IF Tabelle2.Findfirst Then Repeat
     IF Tabelle1.Findlast Then Begin
         Tabelle.Init;
         Tabelle1."Nr.":=Tabelle2."Nr.";
         Tabelle1."Dokument-ID":=Tabelle2."Document ID";
         Tabelle1.Insert;
     End;
Until Tabelle2.NEXT(+1)=0;


wie kann ich mir die letzte Nummer einer Nummernserie abfragen/erstellen?
Um zu vermeiden, dass ich Nummern im Feld Nummer selbst eintrage?

Gruß Christian

Re: Daten in Tabelle Laufende Nummer

15. Mai 2018 17:18

soll das Feld "Nr." über eine Nummernserie (wie z.B. die Rechnungsnummer bei gebuchten Rechnungen) gefüllt werden oder ist das eine fortlaufende Nummer (wie z.B.) bei den Sachposten, Artikelposten, etc.?

Falls letzteres der Fall ist, dann kannst du dich am Beispiel aus der Codeunit 12 orientieren:
Code:
...

WITH GenJnlLine DO BEGIN
  GlobalGLEntry.LOCKTABLE;
  IF GlobalGLEntry.FINDLAST THEN BEGIN
    NextEntryNo := GlobalGLEntry."Entry No." + 1;
    NextTransactionNo := GlobalGLEntry."Transaction No." + 1;
  END ELSE BEGIN
    NextEntryNo := 1;
    NextTransactionNo := 1;
  END;

Re: Daten in Tabelle Laufende Nummer

15. Mai 2018 18:00

soll das Feld "Nr." über eine Nummernserie (wie z.B. die Rechnungsnummer bei gebuchten Rechnungen) gefüllt werden oder ist das eine fortlaufende Nummer (wie z.B.) bei den Sachposten, Artikelposten, etc.?


Ich möchte bei Eingangsrechnungen die Nummernserie verwenden.

Ich versuche die Vergabe der Nummernserie so wie beim OnInsert()-trigger in Tabelle Rechnungseingangskopf zu verstehen und umzusetzen.


Gruß Christian

Re: Daten in Tabelle Laufende Nummer

15. Mai 2018 23:01

Hallo Christian zuerstmal die simple Lösung.

Ich würde es wie folgt schreiben.

Code:
IF Tabelle1.FINDSET THEN
  REPEAT
    IF NOT Tabelle2.GET(Tabelle1.Code) THEN BEGIN
      Tabelle2.INIT;
      Tabelle2."No." := Tabelle1."No.";
      Tabelle2.Description := Tabelle2.Description;
      Tabelle2.INSERT;
    END;
  UNTIL Tabelle1.NEXT = 0;


Hintergrund:
Durch den Primärschlüssel der eindeutig sein muss ist erstmal Verhindert das du jemals mit einem Insert Datensätze überschreiben kannst oder doppelt einfügst.
Es würde Crashen mit der Datensatz ist bereits vorhanden und das ist gut so. Das Prinzip nennt sich "Fast Fail".
Es wäre auch immer einem If insert then; vorzuziehen.

Weiterhin beschreibt in Tabelle1 Der Primärschlüssel deinen Datensatz so kannst du ihn z.b. in Tabelle 2 mit GET wiederfinden. Wie wenn nicht mit der Nummer ?
Das Get verhindert weiterhin unnötige Ausführungen für Datensätze die schon vorhanden sind.

Wenn du die Nummern nicht Synchron hättest müsstest du das Feld "Document ID" abfiltern und gucken ob du diesen schon hast oder ähnliches.
Auch hier macht sich wieder eine Helperfunktion DocumentNumberExist praktisch.

Wenn du neue Datensätze anlegen willst Initialisierst du diese immer erst mit Init. Du stehst dann weder am Ende, der Mitte oder am Anfang der Tabelle. Du bist dann wie außerhalb. Erst wenn du Insert ausführst kümmert sich der Datenbankserver wo dieser Datensatz eingetragen wird.

Hinweis: Init setzt nicht den Schlüsselwert zurück. Diesen musst du dann mit der neuen Nummer überschreiben. Sonst hast du einen "Datensatz existiert schon" Fehler beim Insert (Guter Fehler! -> Fast Fail)

Weiterhin beliebt:
Code:
IF Tabelle1.FINDSET THEN
  REPEAT
    IF NOT Tabelle2.GET(Tabelle1."No.") THEN BEGIN
      Tabelle2.INIT;
      Tabelle2."No." := GetLastNoFromTable2;
      Tabelle2.Description := Tabelle2.Description;
      Tabelle2.INSERT;
    END;
  UNTIL Tabelle1.NEXT = 0;


Eine Helperfunktion die immer frisch die Nummer zieht.
Ein Locktable ist hier immer eine Überlegung Wert da bei stark beanspruchten Tabellen während des buchens/suchens sich die Nummer weiterbewegen könnte.

Code:
LOCAL GetLastNoFromTable2() : Integer
Local Var Tabelle2
Tabelle2.Locktable;
IF Tabelle2.findlast THEN
  EXIT(Tabelle2."No." + 1)
ELSE
  EXIT(1);


Findset solltest du immer benutzen wenn du nicht genau den ersten(Findfirst) oder den letzten (Findlast) finden willst oder danach mit einer Schleife über das Recordset iterierst.
Find('-') oder ähnliches wird nur noch in speziellen fällen benutzt seit dem Dynamics Nav für SQL optimiert wurde.

Wenn du dich fragst wie du dinge schreibst oder warum, dann finde ich die Microsoft Hilfe oder andere Seiten hilfreich.
Oder halt mal hier fragen :wink:

Es lohnt sich außerdem alle Befehle mal in der Hilfe gelesen zu haben. Du kannst so nutzlose Zeichen weglassen.

FINDSET = FINDSET(FALSE,FALSE) DefaultValue FALSE,FALSE
NEXT = NEXT(1) Defaulf Value = 1
Insert = Insert(FALSE) DefaultValue FALSE
Counter += 1 = Counter := Counter + 1
etc.

Und Regel Nummer 1
https://user-images.githubusercontent.com/12088142/27789036-25cd94d0-5feb-11e7-9634-fc5bff0bc858.png :lol:

Re: Daten in Tabelle Laufende Nummer

15. Mai 2018 23:20

Tabelle 27
NoSeriesMgt.InitSeries(InvtSetup."Item Nos.",xRec."No. Series",0D,"No.","No. Series");

Code:
NoSeriesMgt.InitSeries(
  NummernserieCode  << Input Nummernseriencode meistens aus einer Setup Tabelle
  OldNoSeries,
  Date,
  NewNumber << Var Parameter kommt mit Wert zurück (deiner neue Nummer)
  NewNoSeries  << Var Parameter kommt mit Wert zurück (neuer Nummernseriencode)


Kurz für die Lösung mit der Nummernserie brauchst du eine Setup Tabelle und eine Einrichtung. Ich empfehle nicht es hart zu Coden. Das wäre direkt ein Antipattern

Re: Daten in Tabelle Laufende Nummer

16. Mai 2018 13:58

Hallo Nody3000.

Erstmal Vielen Dank, für deinen Beitrag! Großes Lob! :-D
Ich habe eben erstmal die simple Variante ausprobiert.
Der Code lies sich kompilieren, konnte ich auch ausführen, aber ich habe den Eintrag in der Tabelle nicht gefunden?
Womöglich habe ich noch irgendwas übersehen. Ich melde mich gleich nochmal und probiere auch die anderen Varianten noch aus.

Ps. Wenn ich die Macht in mir spüre, wechsel ich auf die dunkle Seite! :lol:

Gruß
Christian
Zuletzt geändert von navCH am 16. Mai 2018 16:41, insgesamt 1-mal geändert.

Re: Daten in Tabelle Laufende Nummer

16. Mai 2018 15:03

Der Code lies sich kompilieren, konnte ich auch ausführen, aber ich habe den Eintrag in der Tabelle nicht gefunden?

Sorry, mein Fehler. Habe zuerst in der Übersicht nachgeschaut, dort habe ich den nicht gefunden. In der Tabelle ist der Eintrag drin!
Alles Gut!

Re: Daten in Tabelle Laufende Nummer

16. Mai 2018 16:39

In der Helperfunktion, an der Stelle:
EXIT(Tabelle2."No." + 1)

sagt mir der Compiler:
1 of the Operators contains an invalid type.
Code + Integer

Habe ich auch probiert:
EXIT(Tabelle2."No." + '1')

sagt mir der Compiler:
1 of the Operators contains an invalid type.
Integer := Text

Was mache ich falsch?

Gruß Christian

Re: Daten in Tabelle Laufende Nummer

16. Mai 2018 18:07

Mit Evaluate() habe ich Table.Nr. auf Integer konvertiert.
Hierbei habe ich das Problem, dass ich dann natürlich keine Alphanumerischen Nummern addieren kann.
Wenn das nur numerische Nummern wären würde es gehen.

LOCAL GetLastNoFromTable2() : Integer

Code:
Table2.LOCKTABLE;
IF Table2.FINDLAST THEN BEGIN
    EVALUATE(ConvertToInt,Table2."Nr.");
    EXIT(ConvertToInt."Nr." + 1)
END ELSE
  EXIT(1);


Vielen Dank Nody3000 :!:

Ps. Woran kann das liegen, dass der Eintrag in der Tabelle steht, aber nicht in der Übersicht?
Zuletzt geändert von navCH am 17. Mai 2018 11:14, insgesamt 1-mal geändert.

Re: Daten in Tabelle Laufende Nummer

17. Mai 2018 08:20

Nody3000 hat geschrieben:Findset solltest du immer benutzen wenn du nicht genau den ersten(Findfirst) oder den letzten (Findlast) finden willst oder danach mit einer Schleife über das Recordset iterierst.
Find('-') oder ähnliches wird nur noch in speziellen fällen benutzt seit dem Dynamics Nav für SQL optimiert wurde.


Um diese Befehle und deren resultierende Abfragen auf dem SQL Server zu verstehen kann diese Blog-Serie von Vjeko nur empfehlen
http://vjeko.com/are-there-any-records-there/
http://vjeko.com/the-if-count-1-conundrum/
http://vjeko.com/when-you-just-must-cou ... tter-what/

Re: Daten in Tabelle Laufende Nummer

17. Mai 2018 12:10

Kurz für die Lösung mit der Nummernserie brauchst du eine Setup Tabelle und eine Einrichtung

Wie muss die Tabelle/Einrichtug aussehen? Welche Felder?

Wofür brauche ich die Setup Tabelle und die Einrichtung?

Gruß, Christian
Zuletzt geändert von navCH am 17. Mai 2018 13:01, insgesamt 1-mal geändert.

Re: Daten in Tabelle Laufende Nummer

17. Mai 2018 12:50

Ah ich sehe schon, du warst fleißig.

Ps. Woran kann das liegen, dass der Eintrag in der Tabelle steht, aber nicht in der Übersicht?

Hat die Übersicht einen SourceTableView Filter oder wird generell irgendwie gefiltert ?

Setup Tabelle:
Schau dir mal Tabelle 98 Feld 63 Bank Account Nos. an.

Diese Setuptabelle hat dann ein Feld mit einer Tablerelation auf die Tabelle "No. Series".

Du machst dann eine Tabelle 50000
1 Code
2 My Document Nos.

Im Code machst du dann ein GET() weil Setup Datensätze üblicherweise einen leeren Code haben und verwendest dann den Wert aus My Document Nos.

Re: Daten in Tabelle Laufende Nummer

17. Mai 2018 14:24

Hat die Übersicht einen SourceTableView Filter oder wird generell irgendwie gefiltert ?

Ich hab das Problem gefunden. Wenn ich neue Einträge in die Tabelle schreibe, muss ich auch das Feld Buch.-Blattname füllen. In meinen Fall 'Standard'.
Jetzt zeigt er die Einträge an.

Diese Setuptabelle hat dann ein Feld mit einer Tablerelation auf die Tabelle "No. Series".

Du machst dann eine Tabelle 50000
1 Code
2 My Document Nos.

Also mache ich eine Tablerelation auf Feld 2 My Document Nos. ?
Was mache ich mit Feld 1 Code?

Gruß, Christian

Re: Daten in Tabelle Laufende Nummer

17. Mai 2018 18:39

Ich habe das jetzt folgendermaßen gelöst.
Die Nummer wird über Nummernserie vergeben.
Ich mache nur ein Insert(True) auf den Insert-Trigger von der ReBu Tabelle.

Code:
        IF Tabelle1.FINDSET THEN
        REPEAT
             IF NOT Tabelle2.GET(Tabelle1."Nr.") THEN BEGIN
                Tabelle2.INIT; 

                //Tabelle2."Nr." --> muss nicht übergeben werden
                ...
                Tabelle2."Dokument-ID":=Tabelle1."Document ID";
                ...
                Tabelle2.INSERT(TRUE);
             END;             
        UNTIL Tabelle1.NEXT=0;


Vielen Dank nochmal!
Gruß, Christian

Re: Daten in Tabelle Laufende Nummer

18. Mai 2018 12:02

Hallo.

wie verhält sich der Datentransfer in die Rechnungszeilen?
Mache ich dort auch ein Findset, Init, Insert(true) und mit Zeilen-Nr. counter?


Gruß Christian

Re: Daten in Tabelle Laufende Nummer

18. Mai 2018 15:13

was für ein Datentransfer in Rechnungszeilen?

Ich würde dich um eines bitten - schreib deine Anforderung mal genau auf.

Re: Daten in Tabelle Laufende Nummer

18. Mai 2018 15:45

Hallo zusammen.

Ich habe Kopfdaten von einer TabelleKopf1 in eine TabelleKopf2 geschrieben, siehe vorher.
Und jetzt habe ich Zeilendaten von einer TabelleZeile1 in eine TabelleZeile2 geschrieben. Das habe ich dann wie folgt in die Tabelle geschrieben:
Bin mir hier nur noch etwas unsicher gewesen.
Code:
        IF TabelleZeile1.FINDSET THEN
        REPEAT
            IF NOT TabelleZeile2.GET(TabelleZeile1."Nr.") THEN BEGIN
                TabelleZeile2.INIT;
                TabelleZeile2."Nr.":=TabelleKopf2."Nr.";
                NewLineNoReBu+=10000;
                TabelleZeile2."Zeilennr.":= NewLineNoReBu;
                TabelleZeile2.Kostenstelle:=TabelleZeile1.Kostenstelle;
                ...               

                //Validate(): 
                TabelleZeile2.VALIDATE();                 
                ...
                TabelleZeile2.INSERT(TRUE);
            END;
        UNTIL TabelleZeile1.NEXT=0;


Welche Validate()-Trigger sollte man denn im ReBu bei Kopf und Zeilen generell ausführen? Oder sollte man gleich alle ausführen?

Gruß, Christian

Re: Daten in Tabelle Laufende Nummer

18. Mai 2018 21:31

Bei deiner Zeile machst du im Grunde das selbe pro Rechnung.

Ich empfehle dir dafür eine eigene Helperfunktion zu schreiben.
Der Grund ist hier : https://youtu.be/18b710d6nMg?t=221

Mach es aber nicht so:
TransferInvoice;
TransferInvoiceLinesFromInvoice;

Sondern Impliziere die Zeilencopy Funktion in der Rechnungscopy Funktion. So kann ein anderer der diese Funktion benutzt sie nicht vergessen. Fass jemand die Zeilen nicht kopieren möchte kannst du einen weiteren Parameter erfinden "CopyWithLines" = False

Code:
LOCAL TransferInvoice()
IF Tabelle1.FINDSET THEN
  REPEAT
    IF NOT Tabelle2.GET(Tabelle1."No.") THEN BEGIN
      Tabelle2.INIT;
      Tabelle2."No." := GetLastNoFromTable;
      Tabelle2.Description := Tabelle2.Description;
      Tabelle2.INSERT;
    END;

    TransferInvoiceLinesFromInvoice(Tabelle1."No.");  <<< Modulare Zeilen Copy Funktion impliziert
  UNTIL Tabelle1.NEXT = 0;


Code:
LOCAL TransferInvoiceLinesFromInvoice(InvoiceNo : Code[20])
Table1Line.SETRANGE(No,InvoiceNo);
IF Table1Line.FINDSET THEN
  REPEAT
    IF NOT Table2Line.GET(Table1Line.No,Table1Line."Line No") THEN BEGIN
      Table2Line.INIT;
      Table2Line.No := Table1Line.No;
      Table2Line."Line No" := Table1Line."Line No";
      Table2Line.Description := Table1Line.Description;
      Table2Line.INSERT;

      //Möglichkeit 2 Transferfields
      //Table2Line.INIT;
      //Table2Line.TRANSFERFIELDS(Table1Line);
      //Talbe2Line.Insert;
    END;
  UNTIL Table1Line.NEXT = 0;



Ich hatte meinen Code weggeworfen und habe jetzt deinen aus dem Forum kopiert dabei ist mir eingefallen das du Evaluate und Format mit Codes durch IncStr ersetzen kannst.
Code:
LOCAL GetLastNoFromTable() : Code[20]
IF Tabelle2.FINDLAST THEN BEGIN
    EXIT(INCSTR(Tabelle2."No."))
END ELSE
  EXIT('1');

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 10:21

Ich habe ein Feld Kostenstelle, dass lässt sich nicht von Tabellekopf1 in TabelleKopf2 schreiben?
Bei allen anderen Felder lassen sich die Werte in die Felder schreiben, bzw. validieren.

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 11:11

navCH hat geschrieben:Ich habe ein Feld Kostenstelle, dass lässt sich nicht von Tabellekopf1 in TabelleKopf2 schreiben?


ich verstehe die Frage nicht - oder ist die ggf. gar keine Frage?
Du kannst das Feld "Kostenstelle" nicht von Table A nach Table B schreiben?
Kommt ein Fehler? - wenn ja, welcher?

wie sieht der Code zum Transfer von TableA.Kostenstelle zu TabeleB.Kostenstelle aus?

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 11:32

Hallo Sweikelt.

Nein es kommt kein Fehler.
Feld Kostenstelle hat ein TableRealtion auf Tabelle Kostenstelle. Ich dachte ich kann da einfach drauf schreiben und validieren, klappt aber irgendwie nicht.
Gebe ne Message aus an der Stelle nach der Wertübergabe und der wert steht drin.
Code:

        IF Rechnungseingangsbuchkopf.FINDSET THEN
        REPEAT
             IF NOT RechEingangKopfEcht.GET(Rechnungseingangsbuchkopf."Nr.") THEN BEGIN
                RechEingangKopfEcht.INIT;
               
                RechEingangKopfEcht.Kostenstelle:=Rechnungseingangsbuchkopf.Kostenstelle;
                MESSAGE(RechEingangKopfEcht.Kostenstelle); --> Message ergibt, das der Wert in RechEingangKopfEcht.Kostenstelle übergeben wurde!
                RechEingangKopfEcht.VALIDATE(RechEingangKopfEcht.Kostenstelle);
                               
                RechEingangKopfEcht.INSERT(TRUE);
             END;             
        UNTIL Rechnungseingangsbuchkopf.NEXT=0;


Gruß,
Christian

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 11:36

ahhhh ok

mach mal bitte so:
Code:
RechEingangKopfEcht.VALIDATE(RechEingangKopfEcht.Kostenstelle,Rechnungseingangsbuchkopf.Kostenstelle);


dann sollte es klappen.
Dein Validate nach der Zuweisung validiert deine Kostenstelle mit einem "leeren" Wert.
Wenn du erst ein Insert, dann Validate (so wie du es hattest) und dann ein Modify gemacht hättest, hätte es sicherlich auch geklappt.

--> aber wenn du eh validieren möchtest, kannst du das auch gleich im Validate Code erledigen.

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 11:56

mach mal bitte so:
RechEingangKopfEcht.VALIDATE(RechEingangKopfEcht.Kostenstelle,Rechnungseingangsbuchkopf.Kostenstelle);

Das hat auch nicht funktioniert:
Code:
IF Rechnungseingangsbuchkopf.FINDSET THEN
        REPEAT
             IF NOT RechEingangKopfEcht.GET(Rechnungseingangsbuchkopf."Nr.") THEN BEGIN
                RechEingangKopfEcht.INIT;
               
                RechEingangKopfEcht.Kostenstelle:=Rechnungseingangsbuchkopf.Kostenstelle;
                MESSAGE(RechEingangKopfEcht.Kostenstelle); --> Message ergibt, das der Wert in RechEingangKopfEcht.Kostenstelle übergeben wurde!
                RechEingangKopfEcht.VALIDATE(RechEingangKopfEcht.Kostenstelle,Rechnungseingangsbuchkopf.Kostenstelle);
                               
                RechEingangKopfEcht.INSERT(TRUE);
             END;             
        UNTIL Rechnungseingangsbuchkopf.NEXT=0;

Vor dem Insert(True) ist alles fein, der wert steht in RechEingangKopfEcht.Kostenstelle, aber nach dem Insert(True) ist der wert weg!

Re: Daten in Tabelle Laufende Nummer

22. Mai 2018 13:20

dann kann es im Grunde nur noch im Insert-Trigger passieren.
Dann also erst insert und dann dein Validate auf die Kostenstelle und dann halt eben noch ein Modify auf den Datensatz