Und noch etwas aus der Welt vom R2 Client.

Bitte korrigiere mich wer, aber ich glaube die Funktion in Listen nach einem vorhandenen Schlüssel zu sortieren ist im neuen Client nicht mehr vorhanden! Erst war ich geschockt, aber es gibt jetzt ja die Möglichkeit nach jedem beliebigem Feld zu sortieren, in dem man darauf klickt. Dies ist unabhängig ob es einen Schlüssel zu diesem Feld gibt. In meinem Beispielfall wurde in den Artikelposten nach den Artikelnummern sortiert (erkennbar an dem kleinen grün markierten Pfeil):

Aber das ist ja häufig nicht genug! Will man weitere Felder zur Sortierung hinzuziehen, hält man Shift (Umschalt) gedrückt und klickt das nächste Feld an, in unserem Fall die Menge:

Nun zeigt uns die Liste die Posten sortiert nach Artikel und dann sortiert nach Mengen an. So erkennt man, dass erst der Artikel 1000 aufgelistet wird und dessen Posten nach Mengen sortiert sind.

NAV merkt sich aber nicht die Reihenfolge der angeklickten Spalten, sondern geht je nach Spalten Anordnung die Sortierung durch. Wenn wir also die Menge vor die Artikelnummer schieben, wird er erst nach Menge sortiert und dann innerhalb dieser nach den Artikeln:

Wenn diese Ansicht gespeichert wird, werden auch die gewählten Sortierungen gespeichert, leider nicht die Spalten Anordnung.

Mit freundlichen Grüßen,

Matthias König

Advertisements

Dynamics NAV 2013 R2 – Tool Tips bei Actions

Veröffentlicht: 20. Dezember 2013 in Tipp

Hi,

eigentlich wollte ich ja erst mein Tutorial weiter schreiben aber dies muss ich dazwischen schieben 🙂 Es ist nun möglich, ToolTips im Client (Windows und Web) sehr sinnvoll einzusetzen! Hinterlegt man einen ToolTip in einer Action, taucht dieser beim MouseOver auf (hier samt Action grün umrandet):

Mit diesem „Feature“ kann man dem Benutzer dann zukünftig unter die Arme greifen und ihm die Online Hilfe ersparen 🙂

Mit freundlichen Grüßen,

Matthias König

Um einen alten (< NAV 2013) Report in Dynamics NAV 2013 zu importieren, muss der Report nur per Client-Funktion „upgegradet“ werden. Erst einmal bekommt man den folgenden Fehler, wenn man einen Report öffnen möchte (schon beim Design):

snap1911.png

Über „Extras–>Berichte upgraden“ kann dieser Report vollautomatisch umkonvertiert werden:

snap1912.png

Mit freundlichen Grüßen,

Matthias König

Change Log in 2013

Veröffentlicht: 26. Oktober 2012 in NAV 2013, Whats New

Nachdem ich mich nun in NAV 2013 mit dem  Change Log (Änderungsprotokoll) auseinander gesetzt habe, sind mir die folgenden zwei Änderungen stark aufgefallen:

  1. Der Change Log musst nicht mehr manuell im Code nachprogrammiert werden! Das bedeutet, dass Datensatzänderungen (etc.) die per Code erstellt werden, werden automatisch (wenn das Änderungsprotokoll für diese Tabelle eingerichtet wurde) im Änderungsprotokoll aufgenommen.
  2. Geloggte Option-Felder zeigen im Feld „Alter“ und „Neuer“-Wert ihren Index (Integer) statt des Optionwertes an. Der Grund dafür ist die nun folgend erklärte Änderung im Change Log Management (CU 423):

Noch in NAV 2009 wurde beim eintragen der Feldwerte eine extra Funktion aufgerufen, die den Optionindex in den Optionwert (Textliche  Bedeutung) formatiert hat:

 

Nun versucht NAV 2013 die Standard FORMAT Funktion zu verwenden. Meiner Meinung nach aber mit den falschen Parametern:

 

Der letzte Parameter „9“ definiert das Format des Wertes und die „9“ ist das XML Format. Der Wert „0“ würde wohl den Option-Wert und nicht dessen Index anzeigen.

 

Mit freundlichen Grüßen,

Matthias König

 

BTW: Ich arbeite aktuell an einem kurzen Beitrag über Filter um den Entwickler Kurs für Rookies fortzuführen 🙂

L und R TRIM per DELCHR

Veröffentlicht: 20. Juli 2012 in Tipp

Ich habe Jahrelang immer wieder eine Funktion geschrieben, die mein L und R Trim (Leerzeichen Links und Rechts entfernen ) ausgeführt hat. Nun gab mir ein netter Kollege folgenden Hinweis: „Nutze doch DELCHR.“

Und es funktioniert wunderbar! Man hätte es evtl. aus der Hilfe ableiten können, ich bin aber nicht drauf gekommen 🙂

Hier die Syntax:

TextVariable := DELCHR(TextVariable, '<>');

Und mal wieder zeigt sich: „Wissen ist das einzige Gut, das sich vermehrt, wenn man es teilt“

Mit freundlichen Grüßen, Matthias König

 

P.S. Da Dynamics NAV eine super community hat, findet man in den Kommentaren dieses Beitrags noch die folgenden Funktionen:

  • Alle Zeichen ausser Ziffern im String löschen
  • Zeichen an Text anfügen, wenn nicht schon vorhanden (z.B. das \ hinter Pfaden)
  • Anzahl der ‘s’ in ‘Flussschifffahrt’ (Anzahl eines Zeichens in einem Text)

So, wollen wir uns ersteinmal vor weiterer trockener Theorie drücken und fangen vor unserem Projekt an, eine kleine Übungsaufgabe zu programmieren. Die Aufgabe wird sein, einen sechsseitigen Spielwürfel zu entwickeln. Dies ist eine Aufgabe, die fernab der Realität ist, da diese Zufallszahlen in einem ERP System kaum Sinn ergeben (falls er ein realistisches Szenario dafür hat, ich würde es gern im Kommentarbereich lesen :D).

Zu Allererst startest du Dynamics NAV mit einer Entwicklerlizenz (Lizenz im zweifel per Ändern laden) und wählst über Datei->Datenbank->Öffnen deine Datenbank aus (wenn nicht schon geöffnet).
Nachdem du über Strg+O oder Datei->Mandant->Öffnen den Mandanten gewählt hast, brauchen wir den Object Explorer. Dieser ist das wichtigste Fenster für den Entwickler, denn dort hat man alle Objekte in einer Übersicht vor sich und kann neue erstellen.

Um einen Würfel zu realisieren, brauchen wir eine Oberfläche. In der aktuellen NAV Version (2009 R2) können wir noch Forms verwenden, was wir in diesem Fall auch tun werden.

Klicke also auf Form dann unten auf den Button [New].

In unserem Fall brauchen wir keine Datenquelle, da der Würfel nur unser Ergebnis anzeigen, aber nicht speichern soll. Also verwenden wir „Create a blank form“. Du kannst, bzw. solltest dich sogar in einer ruhigen Minute aber dennoch daran machen, die weiteren Optionen in diesem Assistenten zu testen und damit rumspielen. Diese nehmen einem häufig viel arbeit am Anfang ab. Wenn der Assistent mit [Ok] bestätigt wurde, erscheint das folgende Fenster.

ich habe dies mit der ID 90555 und den treffenden Namen  „Dice“ gespeichert (Datei->Speichern oder strg+s).
Daraufhin können wir uns über das Design der Anwendung gedanken machen. Dies darf in keiner weise vernachlässigt werden, denn auch bei Software wirkt der erste Eindruck. Ich habe mir angewöhnt so Standard nah wie möglich zu designen, damit sich der Benutzer so schnell wie möglich zurecht findet und die Software wieder erkennt. Dazu sollte man direkt sauber Designen. Im Allgemeinen heisst das, dass die Anwendung ordentlich ausformuliert wird, die Buttons an die richgen Stellen platziert werden, keine obzöhne oder beleidigede Meldungen (Hinweis da dies sehr beliebt unter Berufsschüllern ist…ich hab nie verstanden warum…) verwenden und bekannte Eigenschaften der Controlls direkt (glues) wie gewünscht setzen …. lasse Kleinigkeiten nicht den ersten Eindruck zerstören. Ebenfalls sollte auf Tippfehler und Rechtschreibfehler geachtet werden.

Da ich in diesem Tutorial aber davon ausgehe, dass man den Standard noch garnicht kennt, werde ich dies nach bestem Wissen und Gewissen immer mit dazu schreiben (In diesemfall meine ich vor allem die Microsoft Richtlinien) 😀

Da wir uns nun schon gedanken gemacht haben, wie unser Würfel aussehen soll, designen wir unsere Form wie folgt. Wie dies genau funktioniert, wird kann nach der kurzen Erläuterung erklärt. Du kannst allerdings gerne versuchen dies ohne meine Beschreibung zu erstelllen:

Hierbei habe ich folgendes erstellt:

  1. Textbox für die Würfelausgabe
  2. Button zum würfeln
  3. Button um den Würfel zu reseten

dabei wurde folgendes beachtet:

Controlbeschreibung

Würfelausgabe:
  • Die Textbox wurde zwei Grids vom linken und rechten Rand, sowie von oben entfernt platziert
  • Die Textbox hat den HorzGlue Both: Damit zieht sich das Textfeld in die Horizontale mit dem Fenster (teste später Vollbild ;))
  • Die Textbox hat den VertGlue Top: Hiermit verankere ich die Textbox an den oberen Rand
  • Die Textbox wird auf Editable No gesetzt
  • Variable „DiceResult“ vom Typen Integer erstellen
  • Der Textbox die Variable „DiceResult“ zuweisen. Dies wird über die Eigenschaft „SourceExpression“ sichergestellt.
[Würfeln]-Button
  • Diesen Button an den unteren rechten Rand geschoben
  • Zwei Grids von Rechts und von unten vom Form-Rand entfernt
  • Dieser Button hat den HorzGlue auf Right: Dieser Button bleibt immer am Rechten Rand
  • Dieser Button hat den VertGlue auf Bottom: Hiermit bleibt der Button immer am „Boden“ 😉
  • Die Eigeschaft „CaptionML“ wie folgt gesetzt: „DEU=Würfeln;ENU=Roll the Dice“
[Würfel-Zurücksetzen]-Button
  • Diesen Button an den unteren rechten Rand, links neben den „Würfeln“-Button geschoben
  • Zwei Grids von dem  „Würfeln“-Button und von dem unteren  Form-Rand entfernt
  • Dieser Button hat den HorzGlue auf Right: Dieser Button bleibt immer am Rechten Rand
  • Dieser Button hat den VertGlue auf Bottom: Hiermit bleibt der Button immer am „Boden“ 😉
  • Die Eigeschaft „CaptionML“ wie folgt gesetzt: „DEU=Würfel-Zurücksetzen;ENU=Reset Dice“

Wie designe ich diese Form?

Derzeit haben wir noch die leere Form, wie im Screenshot zuvor gezeigt. Um hier Controls (Buttons, Textbox etc.)  zu erstellen, muss die Toolbox eingeblendet werden:  Dies geht entweder über das Werkzeugsymbol oder über Ansicht->Toolbox. Hier gibt es eine kleine Auswahl an Controls. In unserem Fall brauchen wir oben Rechts die TextBox. Diese ist nicht zu verwechseln mit dem Label daneben. In dem Label können keine Dynamischen Daten eingetragen werden sondern immer nur ein Fester Wert. Wir brauchen hier aber immer unser Würfelergebnis, also wird die TextBox verwendet.

Klicke auf das Symbol in der Toolbox und klicke erneut (nicht gedrückt halten oder ähnliches) in das leere Fenster. Nun siehst du die TextBox.  Nun brauchen wir die zuvor beschriebenen Eigenschaften des Controls. Diese findest du entweder wieder in der Symbolleiste oder über Ansicht->Properties. Alternativ (mein Favorit) verwendet man das Tastenkürzel Shift+F4. Daraufhin öffnet sich eine lange Liste mit vielen Einstellmöglichkeiten. Dies sind die Eigenschaften! Hierüber können Beschriftungen, Positionen, Größen, Schriftarten, Funktionen, Farben etc. gesteuert werden. Da wir aber nur die oben genannten Eigenschaften benötigen, setze die Werte bitte wie beschrieben.

Um die Buttons zu positionieren verwendest du aus der ToolBox das vierte Symbol von oben links vertikal gezählt. Hier kannst du, wie gerade beschrieben, die Eigenschaften öffnen und die des Buttos nach belieben verändern. Bitte versuch dich vorerst an die oben beschriebenen vorgaben zu halten. Witzigerweise ist Horz,- und Vertglue genau entgegegesetzt von dem, was der Styleguide verwendet.

Was ist ein Grid?

Es wurde in der Controlbeschreibung definiert, wieviele „Grids“ das Control z.B. vom Rand entfernt sein soll. Ein Grid ist laut Übersetzung ein Gitter und genau ein solches ist über einer Form. Dieses sieht man nicht ist aber da, um Controls etwas kontrollierter zu Platzieren. Wenn du dir ein Control mit der Maus einmal schnappst und versuchst zu verschieben, dann merkst du, das dies nicht milimeter genau Funktioniert, sondern immer an gewissen Stellen „einrastet“. Dies wird „ein Grid“ genannt. Das heisst, zwei „einraster“ = zwei Grids. Solange man die Einstellungen nicht verändert, ist der Styleguide das jede Form einen Rand von zwei Grids besitzt. Das bedeutet, dass kein Control bis an den Rand geht, sondern immer zwei Grids in die Form Mitte verschoben wird.  Ausserdem werden Buttons unten Rechts in die Ecke zwei Grids unter dem letzten Control gesetzt. Jeder weiterer Button wird zwei Grid links von dem letzten Button angelegt.

In einer Form und in der RequestForm des Classic Client Reports gibt es für die Form selbst, die Eigenschaften HorzGrid und VertGrid. Hiermit kann das Grid nach belieben verändert werden. Allerdings wird damit der Styleguide ziemlich sicher gebrochen. Nebenher, wenn man die Grid-Funktion nur kurz deaktivieren will geht dies über Format->Snap to Grid. Wenn diese Option deaktiviert wurde, kann ein Control an jede Stelle des Forms platziert werden.

Nun verschiebe die Buttons und die Textbox, wie beschrieben an die entsprechenden Stellen.

Damit ist die Form an und für sich Fertig.

Der erste AL Code!

Wir wollen einen Würfel Programmieren! also, was braucht man für einen Würfel? eine Zufallszahl zwischen Eins und Sechs (wir gehen mal von einemm 6-er Würfel aus)  und hier sind die Stichpunkte die man dafür benötigt: RANDOM und RANDOMIZE. Auf dem Klick unseres Würfelbuttons soll eine Zahl zwischen Eins und Sechs erscheinen und dafür brauchen wir die Funktion-NAV „RANDOM“ die zu Deutsch „Zufall“ bedeutet:

Zu dem Random-Befehl sagt uns die Dynamics NAV Hilfe dies: „returns a pseudo random number“. Das bedeutet im Klartext: Immer wenn die Funktion RANDOM verwendet wird, kommen die selben Zahlen in der selben Reihenfolge. Mit anderen Worten: Jedesmal wenn wir unseren Würfel neustarten kommen die selben Zahlen in der gleichen Reihenfolge.

Dies ist in fast allen Programmiersprachen der Fall, da ein Computer eigentlich gar keine Zufälle kennt. Daher verwendet der RANDOM Befehl eine gewisse (immer gleiche) Reihenfolge auf Basis eines internen Wertes. Dieser interne Wert kann mit Hilfe von RANDOMIZE gesetzt und verändert werden:

Über den Parameter Seed kann ein neues neues Set von Nummern für die RANDOM Funktion erstellt werden.

Kleiner Ex-Kurs, Syntax einer Funktion:

Funktion(Parameter);

Das heisst wenn wir hier nun Beispielhaft Randomize benutzen:

RANDOMIZE(5);
MESSAGE( FORMAT( RANDOM(6) ) );

auf einen Button programmieren würden, würde mit dem internen Wert 5 ein neues Set an Zahlen erstellt werden. Dies wird mit jeder verwendung von RANDOM von vorn durchgegangen. Wir haben also eine Variation zu dem Zahlenset ohne unser Randomize.

Durch den Parameter bei RANDOM wird die maximal höchste Zahl definiert. In unserem Beispiel ist die Maximal höchste Zahl also Sechs.

Wir haben noch immer keine richtigen Zufallszahlen aber sind schon nahe dran!

Um im im besten Fall immer ein neues Set an Zahlen zu bekommen, brauchen wir also für Randomize eine sich ändernde Zahl. Was ändert sich regelmäßig? Genau, die Uhrzeit! Also verwenden wir die Zeit (TIME) um Randomize zu füllen. Da Randomize allerdings eine Variable vom DatentypInteger“ benötigt, müssen wir unsere „Time“ in Integer umwandeln (Typecasten).  Aber fangen wir mal klein an:

Der NAV Befehl „TIME“ gibt die aktuelle Uhrzeit mit Sekunden zurück und diese wollen wir für Randomize verwenden. Also kopieren wir uns TIME ersteinmal in eine Text Variable.

Wie erstelle ich eine Variable in NAV?

Um die Variable vom Datentypen Text zu erstellen, muss man im Vorfeld folgendes Wissen: Es gibt Globale und Lokale Variablen. Diese beiden Unterscheiden sich nur im sogenannten „Scope“ (dt. Bereich). Das bedeutet, wie weit wir die Variablen in der Porgrammierung noch im Zugriff haben.

  • Globale Variablen: Überalll in diesem  NAV Objekt im Zugriff. Das bedeutet, wenn so eine Variable angelegt wurde, dass diese in jedem Trigger, jeder Funktion etc. im Zugriff ist. Nicht aber in Irgendeinem anderen Objekt.
  • Lokale Variablen: Sind nur in der aktuellen Funktion im Zugriff. Soll heissen: Wenn eine Lokale Variable in einem OnPush-Trigger angelegt wird, dann kann diese auch nur in diesem Ereignis angesprochen werden.

Variablen erstellt man, anders als in vielen anderen Programmiersprachen nicht im Code selbst, sondern über einen Menüpunkt: Ansicht–>Globale/Lokale Variable. Für unseren Fall benötigen wir eine Globale Variable die wir einfach TimeTxt nennen. Hier vergeben wir nun den Typen Text und die Maximale länge von 30 Zeichen (dies kann bei belieben gerne optimiert werden ;)). Nun kann diese Variable überall in dem Fenster verwendet werden.

Auf Knopfdruck Code Ausführen

Nun setzten wir unseren ersten Trigger/Event. Ein Trigger (Synonym Event) ist nichts anderes als ein bestimmtes Ereignis, welches an einer bestimmten Stelle eintritt. Zum Beispiel das klicken auf unseren Knopf, welchen wir auch nun das erste mal verwenden und auch das erste mal Code verwenden können:

Klicke im Designer auf den „Würfeln„-Button und drücke F9 (Alternativ Ansicht–>C/AL Code) und gebe dort den folgenden Code ein:

TimeTxt := FORMAT(TIME);
MESSAGE(TimeTxt);

Jedesmal wenn nun auf den Button geklickt wird, wird die aktuelle Zeit angezeigt. Das FORMAT() ist eine Internefunktion die sehr mächtig ist, wir verwenden sie aber diesesmal nur um aus einer Time Variable eine Text Variable zu machen (Typecasting). Genau für diesen Zweck brauche ich die Funktion am meisten 😉

Dieser sich veränderner Wert kann nun verwendet werden um immer ein neues Set aus „Zufallszahlen“ zu bekommen.

Das Symbol Menu

Da es in Dynamics NAV kein intellisense gibt, gibt es diese geniale Alternative! Überall wo wir Zugriff auf den Programmcode haben, können wir über Extras–>Symbol Menu oder F5 dieses öffnen. Dort werden die System Variablen, System Funktionen, Lokale und Globale Variablen, Unterfunktionen der Variablen (wenn diese z.B. Codeunits sind), interne Funktionen etc…. aufgelistet.
Hier kann man also gelegentlich mal nach interessanten Funktionen stöbern. Es erscheinen mit neuen Versionen auch häufig neue Funktion.

Schneiden wir den Text in Integer!

Da wir in dem Parameter Seed von Randomize einen Integer (also eine Ganzzahl) benötigen, müssen aus der Uhrzeit die Punkte heraus, da diese in eine Ganzzahl nicht herein passen. Außerdem ist es von Vorteil, wenn wir eine neue Variable anlegen, in der wir diese geschnittene Uhrzeit festhalten. Also legen wir (wie in „Wie erstelle ich eine Variable in NAV“?) eine Variable vom Typ Integer an, die TimeInteger heißt. Um diese ordentlich zu befüllen, schreiben nun den folgenden Code:

TimeTxt := FORMAT(TIME);
EVALUATE(TimeInteger, DELCHR(TimeTxt, '=',':'));

Mit DELCHR löschen wir  jeden Doppelpunkt aus unserem TimeTxt und diesen geschnittenen Text, Typecasten( 😉 ) wir  in TimeInteger mit Evaluate (bitte alles weitere dazu in der C/Side Reference Hilfe heraus suchen).

Diesen Integer-Wert könnten wir über den folgenden Befehl anzeigen lassen:

MESSAGE( FORMAT( TimeInteger ) );

Wir nutzen diesen Wert aber nun als Seed Parameter in RANDOMIZE:

TimeTxt := FORMAT(TIME);
EVALUATE(TimeInteger, DELCHR(TimeTxt, '=',':'));
RANDOMIZE(TimeInteger);

Aufgrund eines nicht definierbaren NAV Problems, darf dieser Code nicht direkt in dem onPush des Buttons, sondern sollte ausgelagert werden. Ich schlage vor, dies immer bei öffnen der Form (in dem OnOpen Trigger) auszuführen. Also fokussiere auf deiner Form im Designer nur die Hauptform (ESC bis zur Schliessen-Abfrage, diese zur not mit „Abbrechen“ schliessen) und drücke F9 um in den C/AL Code zu gelangen. Hier sehen wir die verschiedenen Events und in dem „OnPush“ fügen wir den Code ein. Das bedeutet, dass immer beim starten des Fensters die aktuelle Zeit verwendet wird, um ein neues Set an pseudo Zufallszahlen zu generieren. So hat man mit jedem Start des Fensters eine andere Zufallszahlreihenfolge.

Mit all diesen Events können verschiedenste Anforderungen gelöst werden. Mein Tipp ist, die Hilfe der Form Triggers einfach mal zu überfliegen (suche in der Online Hilfe nach „C/Side Form Trigger“, der erste Treffer).

Endlich wird gewürfelt!

Nun entwickeln wir Endlich das finale Würfeln. Wenn wir nun wieder in den OnPush Trigger des Buttons gehen, löschen wir erst den ganzen bestehenden Code daraus und tragen nur die folgende Zeile ein:

DiceResult := RANDOM(6);

Jetzt starten wir die Form über Datei–>Run oder der Tastenkombie STRG+R und klicken auf würfeln! und voila, es wird eine Zufallszahl zwischen 1 und 6 ausgegeben. Beim nächsten Starten des Würfel-Fensters wird es eine andere Reihenfolge von Würfelergebnissen geben, dies stellen wir im OnRun Trigger sicher.

Und zu guter letzt brauchen wir noch die „Würfel zurücksetzen“ Funktion. Dafür brauchen wir nur in das Event des entsprechenden Buttons..

CLEAR(DiceResult);

.. einprogrammieren und auch diese Funktion, kann getestet werden!

So, das wars für diesen Teil ersteinmal! Ich hoffe es hat euch trotz der großen Verzögerung gefallen. Bitte lasst euch doch im Kommentarbereich aus, wie Sinnvoll und gelungen dieser Artikel ist.

Mit freundlichen Grüßen, Matthias König

Dies soll der Start in einer Reihe von Beiträgen sein, die für NAV Neu-Einsteiger angedacht ist. Dieser soll die Programmierung sowie dessen Datenbank-Design umfassen. Die Zielgruppe dieser Artikel betrifft also Studenten, Schüler, Praktikanten und Neueinsteiger.

Zu allererst einmal: Microsoft Dynamics NAV ist ein ERP-System. Das bedeutet, es dient dazu um die Ressourcen einer Firma zu planen. Zum Beispiel: Wieviele Artikel habe ich noch auf Lager? wie teuer waren diese? was nehme ich für diesen Artikel? Welche Kunden haben diesen gekauft? Wieviel muß mir der Kunde überhaupt noch bezahlen? Was haben wir eingekauft? etc.

Das sind nur einige wenige Dinge die NAV verwalten kann. Wie man an diesem Umfang an existierenden Features schon sehen kann, ist NAV für diese Tätigkeit ausgelegt. Dazu hat NAV zusätzlich, und das interessiert uns hier, eine Entwicklungsumgebung. Diese heißt C/Side (Client/Server Integrated Development Environment) in der man C/AL (C/SIDE Application Language) Programmiert. Fazit ist also (und das muss man sich immer vor Augen halten): NAV ist ein ERP System mit einer kleinen Entwicklungsumgebung!

Warum dieser Satz? Wenn man schon einmal außerhalb von NAV entwickelt hat oder sich mit anderen nicht-NAV Entwicklern unterhält fällt schnell auf, dass die NAV-Entwicklungsumgebung relativ eingeschränkt ist. Diese ist nur über diverse Client Extensebility Möglichkeiten erweiterbar. Aber bis dahin dauerts noch ein wenig 😉

Man kann sich NAV gerne als eine Art Lego-Produkt vorstellen: Microsoft gibt einem das fertige Produkt nach Anleitung aufgebaut und wir erweitern/verändern dies mit den aus der Packung gegebenen Mitteln.

Was muss ich wissen?

Um Anfangen zu können solltest du die folgenden Beiträge mindestens überflogen haben (Auswendig lernen ist nicht notwendig 😉 ):

Dies ist ca. Basiswissen mit dem man starten kann.

Wenn man sich eine Datenbank verallgemeinert vorstellen will, ist der Grundsatz nur eine Ansammlung von Tabellen. Natürlich bietet unser Datenbank Management System Microsoft Dynamics NAV noch viel mehr Funktionen aber der Grundsatz ist: es speichert deine Daten.

Jede Tabelle speichert deine Daten anhand von Zeilen und eine Zeile ist ein so genannter Datensatz. In jeder einzelnen Tabelle sollten nur Informationen festgehalten werden, die auch für diese Tabelle interessant ist. Das soll heissen, die Tabelle bekommt einen Namen, z.B. „Mitglieder“ und dann sollten dort keine Informationen zu dem Auto des Mitglieds stehen. Dafür wäre dann eine weitere Tabelle notwendig. In der Mitglieder Tabelle würde somit nur noch ein Verweis zu dem Auto stehen. Hier zum Beispiel:

Autos:

  1. Golf II, Weiß, 1988
  2. Golf IV, Blau, 2001

Mitarbeiter:

  1. John Doe, 1983, Auto 2

Wenn die einzelnen Nummern nun Datensätze wären, hätte der Mitarbeiter 1 nun das Auto 2, einen Golf IV in Blau. Das Stichwort hierzu lautet Datenbank Normalisierung.

Wie entwickle ich in NAV?

Grundsätzlich sollte man, wenn man die Business Logik anpassen will, erst einmal kontrollieren wie man dies im Standard (der vorprogrammierte Code von Microsoft) lösen wurde. Manchmal geht es da sogar nur um das „Look and Feel“ einer Funktion. Als Beispiel: an jedem Auftrag kann ein Kommentar hinterlegt werden. Falls hier eines eingetragen wurde, sieht der Button rechts neben dem „Nr.“ Feld anders aus als ohne Kommentar. Wenn man dies nachprogrammieren möchte, schaut man sich einfach diese Stelle an. Kurz gesagt, sollte man sich zu Anfang die Frage stellen: Wie würde der Standard dieses Problem lösen?

Objekt Orientiertes Programmieren in NAV?

Falls du gerade nur Fragezeichen über dem Kopf hast, überspringe diesen Teil ruhig ODER ließ ihn aus Prinzip zu ende 😉

Grundsätzlich gibt es das OOP nicht in NAV. Es gibt zwar Objekte aber es können keine eigenen neu definiert werden. Sondern nur neue eines Typs (Tabelle, Form, Report, Page …). Allerdings kann man gewisse Prinzipien des OOPs sehr, sehr gut auch in NAV einsetzen.Der folgende Text ist meine derzeitige Meinung, wie man in NAV sauber und gut programmiert:

Eine Tabelle ist eine Klasse und alle enthaltenen Funktionen beziehen sich auf einen Datensatz der Instanz. Bedeutet, wenn für eine Zeile eine Menge an Datensätzen in einer weiteren Tabelle verarbeitet, dessen Parameter alle in dem Datensatz gespeichert sind, sollte diese Funktion in der Tabelle programmiert werden.

Codeunits sind Klassen, die Funktionen bereitstellen die nicht zwingend an einen Datensatz gebunden sind und häufig auch von anderen Codestellen ausgeführt werden müssen.

Forms, Pages sind nur für Ausgaben zuständig und Reports für Ausgaben und Batchläufe (im besten Fall für Funktionen auf den zugrunde liegenden Tabellen).

Wie immer: Das ist die Theorie.

Idee?Inspiration?…womit soll ich nur Anfangen?

Was mache ich als erstes? um etwas Gefühl für den Code zu entwickeln, schlage ich immer gern vor, etwas vollkommen neues zu Programmieren! Der Standard ist zwar Super aber um sich auszulegen (so meine Erfahrung und Meinung) ist man Kreativer in eigener Umgebung 😉

Entweder, du lässt dir nun etwas eigenes einfallen was die folgenden Start-Parameter erfüllt oder du nimmst mein noch kommendes Beispiel. Die Parameter die deine Idee haben sollte:

  • Daten die gespeichert werden
  • Berechnete Daten
  • Benutzer-Interface

Deine eigene Idee muss nun nicht zwingend etwas total neues oder Bahnbrechendes sein, sondern etwas, welches dir am ehesten Vorschwebt oder einfach aus Interesse für dich geeignet ist.

Beispiele, auf die ich nicht weiter eingehen werde: DVD-Sammlung, Bücher-Sammlung, Terminkalender, Quartet-Spiel, Stundenplan, Computerspielfiguren Sammlung (inkl. ingame Werte), etc….

Bitte hinterlasst mir doch einen Kommentar zu diesem Beitrag. Mich würde interessieren wie sinnvoll und Hilfreich dieser Beitrag ist. ich nehme gerne auch Negativ-Kritik und Verbesserungsvorschläge entgegen.