Temporäre Tabellen/Recordvariablen

Bild Häufig gestellte Fragen (Frequently asked questions) zu den Microsoft Dynamics NAV Versionen

Temporäre Tabellen/Recordvariablen

Beitragvon Natalie » 26. Januar 2012 21:31

Dieser Artikel dient als Einstieg fĂĽr C/AL-Programmierer, die bereits praktische Kenntnisse von Records besitzen.
Ziel ist es nicht, alles Wissenswerte aufzuzählen.



Kurze Wiederholung: Recordvariablen
Recordvariablen erlauben uns in der C/AL-Programmierung den Zugriff auf Tabellen unserer NAV-Datenbank.
Deklariert ihr eine Recordvariable vom Typ Item (ich nenne sie an dieser Stelle mal RecItem), so erstellt ihr damit eine VerknĂĽpfung zur Artikeltabelle. In dieser Variable sind nun automatisch alle Tabellenfelder enthalten, die es in der Tabelle Item gibt.
Mit RecItem könnt ihr nun Daten in der Artikeltabelle lesen oder auch diese ändern. Führt ihr z.B. ein RecItem.MODIFY aus, so wird dieser Befehl direkt auf eurer Datenbank ausgeführt und der Artikel geändert.

Was sind temporäre Records?
Temporäre Records unterscheiden sich auf den ersten Blick nicht von "normalen" Recordvariablen. Sie kennen auch die gleichen Befehle wie RESET, SETRANGE, INSERT, MODIFY etc.
Der Unterschied ist: Richtig angewendet, wird nicht in die Datenbank geschrieben, sondern in eine Art Zwischenspeicher. Wofür das gut sein soll, lest ihr später.

Woran erkenne ich temporäre Records?
Wenn der Programmierer sauber arbeitet, hoffentlich an ihrem Namen!
Es ist sehr ratsam (aber leider keine Pflicht), alle als temporär deklarierte Recordvariablen durch eine Namenserweiterung kenntlich zu machen. So könnte aus RecItem ein TmpRecItem oder TempRecItem werden.
Meistens hält sich z.B. der Standard daran - leider aber auch nicht immer. Ein TempRec kann in Wirklichkeit in "normaler" Record sein, und hinter einem SalesLine könnte sich ein temporärer Record verbergen.
Das einzig sichere Kennzeichen ist daher die Deklaration.

Deklaration
Ihr macht alles zunächst genauso wie bei gewöhnlichen Recordvariablen. Zum Schluss ruft ihr die Eigenschaften der Variable auf und setzt Temporary = Yes.
Falls ihr die Eigenschaften nicht aufrufen könnt oder das Eigenschaftsfenster leer und nicht editierbar sind, speichert eure bisherigen Änderunge, schließt alle Fenster und versucht es erneut.

WofĂĽr das Ganze?
Beispiel aus dem Standard:
Der Report 111 druckt die Debitoren-Top-10. Der Report muss, um dies drucken zu können, irgendwo eine Kombination aus Debitorennr. und Umsatz speichern. Die Debitorennr. ist vom Datentyp Code20 (also quasi Text), der Umsatz ist decimal. In C/AL haben wir zunächst keine Möglichkeit, diese Kombination zu speichern: Einzeln deklarierte Variablen stehen in keinem Zusammenhang zueinander. Auch Arrays (eine Variable mit gesetzter Eigenschaft Dimensions) bringen nicht die Lösung: Eine Arrayvariable kann nur mehrere Einzelvariablen des gleichen Datentyps beinhalten. Kombininiert ihr zwei Arrayvariablen, bleibt das Problem, das ein Array nur so viele "Zeilen" haben kann, wie ihr unter Eigenschaft Dimensions definiert habt.
Und was macht ihr, wenn ihr nicht nur zwei Variablen zusammen halten mĂĽsst, sondern noch viel mehr?

Im Fall des Reports 111 verwendet der Standard die temporäre Recordvariable CustAmount (die besser TempCustAmount genannt worden wäre). Dieser Record verweist auf Tabelle "Customer Amount", das ist Tabelle 266. Ihr werdet vielleicht feststellen, dass diese Tabelle in eurer Datanbank leer ist. Das liegt daran, dass es sich um eine sog. Puffertabelle handelt, welche ausschließlich temporär verwendet wird.

Temporäre Records können aber auch verwendet werden, um sich anderweitig gefundene Datensätze (aus der gleichen Tabelle, versteht sich) zu merken und anderen Programmteilen zu übergeben. Die nächste Funktion kann zu der bereits gefüllten Recordvariable nochmal eigene Datensätze hinzufügen. Andere Funktionen löschen vielleicht wieder Datensätze aus diesem Pool heraus.

Der Inhalt temporärer Records lässt sich sogar auf Forms/Pages ausgeben.

Wie gehe ich mit temp. Records um?

WICHTIG: Keine Trigger
Trigger löst ihr aus, wenn ihr mit INSERT/MODIFY/DELETE/RENAME(TRUE) oder auch VALIDATE arbeitet.
Dann wird der Quelltext ausgeführt, der in der Tabelle an jeweiliger Stelle hinterlegt ist. Und das ist zu 99,99% schädlich.
Löscht ihr mittels DELETE(TRUE) beispielsweise einen temp. Auftragskopf, dann würden vielleicht echte (!) Verkaufszeilen in eurer Datenbank gelöscht werden. Denn die temporäre Eigenschaft vererbt sich nicht auf die Variablen innerhalb der Trigger.
Darum:
  • Niemals!! Trigger an temporären Recordvariablen von Standardtabellen einsetzen.
  • Wenn ihr die Tabellen selbst desingt, und ihr Trigger einsetzen mĂĽsst, verzichtet auf jeglichen Code in Triggern der die echte Datenbank modifizieren könnte!
  • Verwendet fĂĽr temporäre Records nach Möglichkeit nur Tabellen, die normalerweise keine Daten enthalten, dann macht es zunächst nichts, wenn TEMPORARY=Yes vergessen wird.



Eine frisch deklarierte temporäre Recordvariable verhält sich zunächst wie eine neu erstelle Tabelle: Sie ist komplett leer. Ihr müsst sie selbst per C/AL füllen.

Temp. Record befĂĽllen
Beispiel: Wir möchten alle (oder einige) Datensätze aus Tabelle 3 Payment Terms in einem temp. Records speichern.
Dann könnte der Quelltext so aussehen:
Code: Alles auswählen
IF PaymentTerms.FINDSET THEN BEGIN
  REPEAT
    TempPaymentTerms 
:= PaymentTerms;
    TempPaymentTerms.INSERT;
  UNTIL PaymentTerms.NEXT = 0;
END; 

Wie in "normalen" Tabelle auch wĂĽrdet ihr ĂĽbrigens einen Laufzeitfehler erhalten, falls ein Datensatz schon vorhanden ist.

Vielleicht möchtet ihr aber so eine Tabelle komplett manuell befüllen? Ein Datensatz könnte so angelegt werden:
Code: Alles auswählen
TempPaymentTerms.INIT;
TempPaymentTerms.Code := 'ZAHLCODE1';
TempPaymentTerms.Description := 'Zahlung sofort';
TempPaymentTerms.INSERT

Komplettes temp. Recordset leeren
Angenommen, TempPaymentTerms zeigt noch immer auf ZAHLCODE1.
Führt ihr nun TempPaymentTerms.DELETE aus, so würdet ihr nur den ZAHLCODE1-Datensatz löschen.
Um wirklich alles zu löschen, gewöhnt euch am besten an:
Code: Alles auswählen
TempPaymentTerms.RESET;
TempPaymentTerms.DELETEALL; // (1)
CLEAR(TempPaymentTerms); // (2)  

(1) Löscht alle Datensätze, lässt aber die Felder auf dem zuletzt gezeigten Datensatz gefüllt.
(2) Initialisiert auch die zuletzt angezeigten Felder.
Am einfachsten lässt sich das nachvollziehen, wenn ihr diese Zeilen mal debuggt und die TempPaymentTerms-Variable beobachtet.



Zu guter Letzt: ein paar Tipps

  • FĂĽhlt ihr euch fit im Umgang mit Records in C/AL? Wenn nicht, ĂĽberlasst temporäre Records besser erfahreneren Programmieren.

  • Temp. Records belasten den Zwischenspeicher. Gerät euer gefĂĽllter Record zu "voll", kann dies euren Client ausbremsen.

  • Ihr möchtet in eurer nächsten Codezeile TempRec.DELETEALL schreiben? Vergewissert euch aller-allerspätestens jetzt noch einmal, dass eure Variable korrekt als temporär deklariert ist!

  • Vorsicht in den Reports fĂĽr ungebuchte VK- und EK-Belegen (z.B. Auftragsbestätigung oder EK-Bestellung: Die globale Recordvariable SalesLine bzw. PurchLine ist - trotz ihres Namens - temporär! Wer - aus welchen GrĂĽnden auch immer - diese Variable auf nicht temporär setzt und den Report ausfĂĽhrt, :!: löscht unwiderruflich alle VK- bzw. EK-Zeilen :!:
    Grund: SalesLine.DELETEALL bzw. PurchLine.DELETEALL im DataItem CopyLoop.

  • Codeunit 5988 Serv-Documents Mgt. verwendet zahlreiche temporäre Records - nur leider sieht man das den Variablen dem Namen nach nicht an.
Benutzeravatar
Natalie
Moderator
Moderator
 
Beiträge: 9257
Registriert: 31. Oktober 2006 19:51
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV

Re: Temporäre Tabellen/Recordvariablen

Beitragvon Natalie » 2. November 2012 10:07

Wer sich tiefer mit temporären Records beschäftigen möchte, der sollte sich noch diesen englischsprachigen Blogartikel anschauen:
http://navigateintosuccess.com/blog/som ... ary-tables
Benutzeravatar
Natalie
Moderator
Moderator
 
Beiträge: 9257
Registriert: 31. Oktober 2006 19:51
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics NAV

Re: Temporäre Tabellen/Recordvariablen

Beitragvon Kowa » 19. Februar 2020 14:51


Da obiger Link zum Artikel mitterweile verwaist ist: Hier gibt es ihn weiterhin :arrow: Some tips and hints about temporary tables
GruĂź, Kai

Frage beantwortet? Schreibe bitte [Gelöst] vor den Titel des ersten Beitrags.
Bitte erst suchen, dann fragen. Bitte beachte den kleinen Community-Knigge.
Kein Support per PN, Mail, Messenger oder Telefon! DafĂĽr ist dieses Forum da.

Download: Dynamics NAV Object Text Explorer (Alternativlink). MVP Alumni
Benutzeravatar
Kowa
Moderator
Moderator
 
Beiträge: 7835
Registriert: 17. Juni 2005 17:32
Wohnort: Bremen
Realer Name: Kai Kowalewski
Arbeitsort: Osterholz-Scharmbeck
Bezug zu Microsoft Dynamics: Microsoft Partner
Microsoft Dynamics Produkt: Microsoft Dynamics 365
Microsoft Dynamics Version: BC, NAV 2018 bis Navision 2.01


ZurĂĽck zu NAV FAQ

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast