Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 12:10

Noch ne Idee:
Wenn man in der Form eine neue Zeile anlegt (in Nav5 zumindest), wird das hier durchlaufen:
Code:
UpdateBalance;
SetUpNewLine(xRec,Balance,BelowxRec);
CLEAR(ShortcutDimCode);
CLEAR(AccName);

In der Funktion SetupNewLine wird auch schon was an den Dimensionen gemacht. Vielleicht ist das das fehlende Teilchen?

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 13:32

Also ich habe jetzt in Gen Journal Line - OnPreDataItem()
Code:
"Gen. Journal Line".INIT;

eingefügt. Dort werden schon Zuweisungen gemacht. (Dataport ist nicht von mir! Ich versuche nur den Fehler zu finden.)
Dann habe ich in OnAfterImportRecord die Zeile:
Code:
"Gen. Journal Line".MODIFY(TRUE);

nach dem Validate auf Kostenstelle eingeügt.

Dann bekomme ich aber folgende Fehlermeldung:

Code:
Die Fibu Buch.-Blattzeile existiert nicht.
Identifizierende Felder und Werte:
Buch.-Blattvorlagenname='ALLGEMEIN',Buch.-Blattname='DEBIPABS',Zeilennr.='10000'

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 13:34

du hast den Insert vergessen!

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 13:41

fiddi hat geschrieben:du hast den Insert vergessen!

Oh, habs vergessen hinzuschreiben. Den Insert habe ich direkt nach dem INIT gemacht. Dann die Werte mit VALIDATE zugewiesen und zum Schluss ein Modify(true)

Ach, ich poste am Besten mal den ganzen Code. Hab die letzten Änderungen aber wieder rausgenommen. Das ist der Code wie er vorher war:
Code:
Gen. Journal Line - OnPreDataItem()
--------------------------------------------------------------------
VALIDATE( "Gen. Journal Line"."Line No.", 0 );

IF dtsFibuJournalZl.GET('ALLGEMEIN','DEBIPABS',10000) THEN
  IF dtsFibuJournalZl."Account No." <> '' THEN
    ERROR('Das Fibu-Journal ist nicht leer \ Bitte zuerst vorhandene Einträge buchen!')
  ELSE
    dtsFibuJournalZl.SETRANGE("Journal Template Name",'ALLGEMEIN');
    dtsFibuJournalZl.SETRANGE("Journal Batch Name",'DEBIPABS');
    dtsFibuJournalZl.DELETEALL;

Gen. Journal Line - OnBeforeExportRecord()
--------------------------------------------------------------------

Gen. Journal Line - OnAfterExportRecord()
--------------------------------------------------------------------

Gen. Journal Line - OnBeforeImportRecord()
--------------------------------------------------------------------
"Gen. Journal Line".VALIDATE( "Journal Template Name", 'ALLGEMEIN');
"Gen. Journal Line".VALIDATE( "Journal Batch Name", 'DEBIPABS' );
"Gen. Journal Line".VALIDATE( "Account Type", "Account Type"::"G/L Account" ); //1
"Gen. Journal Line".VALIDATE( "Line No.", "Gen. Journal Line"."Line No." + 10000 );
"Gen. Journal Line".VALIDATE( "Gen. Posting Type", 0 ); //2
"Gen. Journal Line".VALIDATE( "Gen. Bus. Posting Group", '' );//3
"Gen. Journal Line".VALIDATE( "Gen. Prod. Posting Group", '' ); //4
"Gen. Journal Line".VALIDATE( "VAT Bus. Posting Group", '' );
"Gen. Journal Line".VALIDATE( "VAT Prod. Posting Group", '' );

Gen. Journal Line - OnAfterImportRecord()
--------------------------------------------------------------------

IF vTag1 = '' THEN
  vTag1 := '0';

IF vMonat1 = '' THEN
  vMonat1 := '0';

vBuchungsdatum := FORMAT(vTag1 + vTag2 + vMonat1 + vMonat2 + vJahr);
EVALUATE("Gen. Journal Line"."Posting Date",vBuchungsdatum); // 1
VALIDATE("Gen. Journal Line".Amount);// 2

IF ("Account No." > '29999') AND ("Account No." < '50000') THEN BEGIN
  "Gen. Journal Line".VALIDATE( "Gen. Posting Type", 2 );// 3
  "Gen. Journal Line".VALIDATE( "Gen. Bus. Posting Group", 'INLAND' );// 4
  "Gen. Journal Line".VALIDATE( "Gen. Prod. Posting Group", '0' );// 5
  "Gen. Journal Line".VALIDATE( "VAT Bus. Posting Group", 'INLAND' );
  IF ("Account No." < '40000') THEN BEGIN    //Steuerkonten
    "Gen. Journal Line".VALIDATE( "VAT Prod. Posting Group", FORMAT('PABS' + "Gen. Journal Line"."Account No.") )//2
  END ELSE BEGIN
    "Gen. Journal Line"."VAT Prod. Posting Group" := 'xxx';
    IF SachKto.GET("Account No.") THEN BEGIN          //Erlöskonten
      IF SachKto."VAT Prod. Posting Group" <> '' THEN
        "Gen. Journal Line".VALIDATE( "VAT Prod. Posting Group", FORMAT('PABS' + SachKto."VAT Prod. Posting Group") );
    END;
  END;
  VALIDATE("Gen. Journal Line"."VAT Prod. Posting Group");
END;

IF vKost = '0' THEN BEGIN
   "Gen. Journal Line".VALIDATE( "Shortcut Dimension 1 Code", '' );//6
END ELSE BEGIN
   "Gen. Journal Line".VALIDATE( "Shortcut Dimension 1 Code", vKost );
END;

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 13:49

Ich schrieb glaube ich:
  • Primärschlüssel initialisieren(d.h. nicht nur INIT, sondern auch füllen der Primärschlüsselfelder und nur die) :wink:
  • Insert(True)
  • Felder Validieren
  • modify(true);

Und das alles im OnAfterImport.

Außerdem solltest du beim Import keine Felder des Buchblattes direkt befüllen (in den Dataportfields stehen keine Felder aus dem Buchblatt-Record).

evtl. benötigst du noch das was MacLane in der Form ausgegraben hat.

Gruß, Fiddi

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 16:25

Hey super!

Das hats gebracht. Ich habe den Dataport jetzt nach Deinen Vorgaben umgeschrieben, fiddi. Und nu funzts.
Man, man, man, was habe ich da für eine Schei... übernommen. In den Dataport-Fields wurde zum Einen direkt in die Tabelle geschrieben und zum Anderen in Variablen. Hab es jetzt so gemacht, dass er alles in Variablen schreibt. Dann habe ich in OnPreDataItem die Zuweisung herausgenommen und alle Zuweisungen in OnAfterImportRecord positioniert. Vorher habe ich den Schlüssel initialisiert, einen Insert gemacht, validates ausgeführt und dann noch einen Modify.

Na, das war das erste Mal das ich was mit Dataports gemacht habe. Nu weiss ich wie es Prinzipiell funktioniert.... :-)

Vielen Dank euch allen für die kompetente und schnelle Hilfe.

Re: Daten per Dataport einlesen und VALIDATE ausführen

29. Juli 2009 17:03

Du hast dir aber auch gleich eine der schlimmsten Tabellen ausgesucht :wink:

Gruß, Fiddi

Re: Daten per Dataport einlesen und VALIDATE ausführen

4. August 2009 17:11

Moin,

habe hier gerade auch noch ein Problem mit einem Dataport und dem Einlesen von Daten - daher hänge ich mich mal hier ran.

Ich lese aus einer CSV-Datei drei Spalten in die Temp-Variablen (_var1, _var2 ...)[alle Text 250] ein. Im "OnAfterImportRecord()"-Trigger fülle ich dann mein Record:

Code:
// ein paar Tests auf die "_var"-Variablen

CLEAR(tmpRecord);
tmpRecord.INIT;
tmpRecord."Customer No." := _var1;
EVALUATE(tmpRecord."Valid From", _var2);
tmpRecord."Valid until" := WORKDATE;
tmpRecord."Value" := '1';
IF NOT tmpRecord.INSERT(TRUE) THEN
BEGIN
  Error(errtext_0001, _var1);
END;


Es wird beim durchlaufen kein Fehler gemeldet aber in der Tabelle wird kein Datensatz eingefügt. Validate-Methoden sind auf keinem Feld der Tabelle und der Schlüssel liegt auf "Customer No." und "Valid From".

Den Vorschlag mit zuerst "INSERT" und danach "MODIFY" hat das selbe unbefriedigende Ergebnis.

Sofern ich mal "Müll-Daten" einlese (z.B. einen String in der Datumsspalte) kommt eine Fehlermeldung, also läuft er scheinbar schon die Routine durch.

AutoSave, AutoUpdate und AutoReplace sind alle auf "No"

Hat jemand noch ne Idee, warum er nicht speichert? Oder hab ich was wichtiges vergessen bei dem Dataport zu aktivieren, damit kein Rollback in der Transaktion oder ähnliches durchgeführt wird?

Kleine Frage fürs debugging am Rande: Kann man die Kommunikation zwischen Navision und dem SQL-Server (2005) irgendwie mitlesen, also welche Querys darüber wandern und so? Ausreichende Berechtigungnen vorausgesetzt.

Vielleicht hat ja jemand einen Tipp für mich, danke!

Paul

Re: Daten per Dataport einlesen und VALIDATE ausführen

4. August 2009 17:15

paul hat geschrieben:[...]Es wird beim durchlaufen kein Fehler gemeldet aber in der Tabelle wird kein Datensatz eingefügt.

Du startest den Dataport aber nicht aus dem "Design-Mode" heraus, oder? Schon über die "Run"-Schaltfläche des ObjectDesigners oder über das Hauptmenü?

Gruß, Marc

Re: Daten per Dataport einlesen und VALIDATE ausführen

4. August 2009 17:38

Marc Teuber hat geschrieben:Du startest den Dataport aber nicht aus dem "Design-Mode" heraus, oder? Schon über die "Run"-Schaltfläche des ObjectDesigners oder über das Hauptmenü?


Treffer versenkt - das war der Fehler von mir. Oh man, .... Danke^2!!!

Paul

Re: Daten per Dataport einlesen und VALIDATE ausführen

4. August 2009 22:44

paul hat geschrieben:Treffer versenkt - das war der Fehler von mir. Oh man, .... Danke^2!!!

Andere Möglichkeit: Im OnPostDataport-Trigger ein COMMIT setzen, dann klappt es auch im Design Mode.

Re: Daten per Dataport einlesen und VALIDATE ausführen

5. August 2009 10:43

sollte man aber entweder nicht vergessen wieder raus zu nehmen oder, mein Vorschlag, garnicht erst machen :)
gewoehn dir lieber an, richtige tests per run zu starten!

sonst passiert dir das noch 100male ohne das du draus lernst oder du importierst sogar fehlerhafte Daten!

BTW:
Batchlaufinsert sollte man (fast) immer wie folgt an gehen:
Code:
CLEAR(RecVar);
RecVar.INIT;
// ....
RecVar.INSERT(TRUE/FALSE);

Re: Daten per Dataport einlesen und VALIDATE ausführen

5. August 2009 12:50

@MathiasKönig,

Die Methode mit:
Code:
CLEAR(RecVar);
RecVar.INIT;
// ....
RecVar.INSERT(TRUE/FALSE);

dürfte bei allen Tabellen, die mit Dimensionen arbeiten oder automatisch zusätzliche Tabellen füllen (z.B. Textbausteine,..) nicht funktionieren, da diese Tabellen versuchen auf die ursprüngliche Tabelle zu referenzieren, die sie aber noch nicht findet (sehe oben). Die andere Methode ist folgende (die übrigens auch von den Forms angewendet wird, die kein "Delayed Insert" haben):

Code:
CLEAR(RecVar);
RecVar.INIT;
RecVar. Primärschlüssel setzten
RecVar.INSERT(TRUE);
ReFeldwerte setzen
RecVar.Modify(TRUE/FALSE);



Gruß, Fiddi

Re: Daten per Dataport einlesen und VALIDATE ausführen

5. August 2009 13:41

MatthiasKönig hat geschrieben:sollte man aber entweder nicht vergessen wieder raus zu nehmen oder, mein Vorschlag, garnicht erst machen :)
gewoehn dir lieber an, richtige tests per run zu starten!
sonst passiert dir das noch 100male ohne das du draus lernst oder du importierst sogar fehlerhafte Daten!

Da nach dem Durchlauf des letzten Triggers der Client ohnehin die Transaktion automatisch abschließt, führt ein COMMIT hier nur dann zu einem geänderten Verhalten, wenn mehrere Dataports per Codeaufruf automatisch nacheinander gestartet werden würden. Dann führt ein COMMIT ggf. zu halb importierten Daten, wenn danach der Import abgebrochen wird.

Bei sehr langen Datenimporten, bei denen man nicht die ganze Zeit das Statusfenster beachtet, ist auch häufig in diesem Trigger etwa
Code:
MESSAGE('Daten sind importiert');
zu finden. In solchen Fällen sollte sogar davor ein COMMIT stehen, da die Transaktion sonst nicht angeschlossen wird, bis man "OK" drückt und daher die Meldung eigentlich noch nicht zutrifft. Beim Native Server bleiben dann auch bis dahin auch alle beteiligten Tabellen gesperrt und blockieren andere User im System.