Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Wednesday, 23. August 2006


From Greg’s Head

Filed under: Blogs,Navision — Steffen Forkmann at 17:31 Uhr

Unter http://www.fromgregshead.com/ blogt Greg Price einen interessanten Blog. Besonders die Navision-Kategorie ist empfehlenswert.

Thursday, 17. August 2006


Konfigurationsdateien schnell und flexibel

Filed under: C# — Sebastian Wolf at 17:03 Uhr

Nini ist eine .Net Library mit welcher man besonders schnell hoch flexible Anwendungen mit Konfigurationsdateien erstellen kann. Die Anwendung ist denkbar einfach wie man im folgenden Beispiel sieht:

; MyApp.ini [Logging] File Name = MyApp.log MessageColumns = 5 MaxFileSize = 40000000000000

Und der C# Code zum einlesen sieht folgendermasen aus:

using Nini.Config; IConfigSource source = new IniConfigSource("MyApp.ini"); string fileName = source.Configs["Logging"].Get("File Name"); int columns = source.Configs["Logging"].GetInt("MessageColumns"); long fileSize = source.Configs["Logging"].GetLong("MaxFileSize");

Das war aber noch längst nicht alles. Noch mehr gibt es hier.


Visual Studio 2005 für lau

Filed under: Visual Studio — Steffen Forkmann at 15:52 Uhr

Dank der “Watch & Win”-Kampagne von Microsoft habe ich jetzt für private Zwecke eine Visual Studio 2005 Standard-Version gewonnen. Dabei muss man sich einfach 5 kurze (Einsteiger-)Videos ansehen, die Gewinncodes notieren und dann einfach über das Gewinnformular an Microsoft schicken. Mitmachen lohnt sich da die Gewinner zusätzlich auch noch 6 Monate ASP.NET-Webhosting gewinnen.

Monday, 14. August 2006


Oracle Integration into Dynamics Nav

Filed under: English posts,Navision,Oracle — Steffen Forkmann at 12:29 Uhr

Today I want to describe a way to integrate Oracle into Navision. We use this way to migrate selected Tables and Views (rawdata) completely automatic into Dynamics Nav. This means we generate the Table-Structure (as a copy of the Oracle data dictionary) and import the data on the fly.

Oracle Data Provider

First of all one have to install the ODP.NET (Oracle Data Provider for .NET).

Then create a new C# ClassLibrary-Project and add a reference to the installed OracleDataAccess-Assembly. (see Sample-Project as Reference)

Install your COM-Object. (You can let Visual Studio do this for you)

Then create a Navision-Object which connects to the ClassLibrary and interact with Oracle.

IF g_MigrationHelper.OracleConnect( 
  g_ORAUserName,g_ORAPassword,g_ORADataSource) 
THEN BEGIN 
  IF p_Test THEN BEGIN 
    MESSAGE('Connection open'); 
    g_MigrationHelper.CloseOracleConnection; 
  END 
END ELSE 
  ERROR('Connection failed');
Tags: ,

Saturday, 29. April 2006


Navision: Datenübernahme aus Oracle

Filed under: Navision,Oracle — Steffen Forkmann at 18:04 Uhr

Basierend auf der Idee eines universellen Dataports habe ich nun auch mal die andere Seite genauer betrachtet. Um also den erstellten automatischen Dataport benutzen zu können, benötige ich eine Schema.ini und für jede Tabelle ein CSV-File.

Für dBase-Files und Excel-Tabellen kann man den DBF-View-Lister vom Total Commander benutzen. Dieser erzeugt alles was man braucht.

Bei Oracle gestaltet sich das ein klein wenig schwieriger. Man kann zwar mit vielen Tools ganze Tabellen in CSV exportieren jedoch ist das oftmals zu unflexibel. Des weiteren wird auch keine Schema.ini erzeugt, so dass die Spaltentypen im Navision nicht automatisch angelegt werden würden. Aber man kann sich im Oracle ja auch relativ einfach ein Package schreiben, dass genau das tut.

Also ich übergebe nun meinen Package nur noch die zu exportierenden Tabellen und Oracle legt für mich alle CSV’s und die Schema.ini an.

Sunday, 9. April 2006


Microsoft Dynamics–Nav 4.0 SP2

Filed under: Navision — Steffen Forkmann at 10:36 Uhr

Seit kurzem steht das ServicePack 2 für Microsoft Dynamics–Nav 4.0 zum Download in der PartnerSource von Microsoft zur Verfügung. Neben einigen BugFixes am Client selbst (DataItems können jetzt auch im Report Designer verschoben werden ohne das Navision abstürzt) sind vorrangig BugFixes in der Anwendung vorgenommen wurden. Besonders interessant für mich sind die BugFixes in der Anlagenbuchhaltung. Anscheinend läuft der Abschreibungslauf jetzt nicht mehr nur bis zum Datum des letzten gefundenen Posten, sondern bis zu einem vorgegebenen Datum – ein Feature was bei uns ziehmlich weit oben auf der Wunschliste der Kunden war. Offenbar löst sich das jetzt in Wohlgefallen auf und wir brauchen das nicht selbst anzupassen.


Visual Studio Plugin: GhostDoc

Filed under: Visual Studio — Steffen Forkmann at 10:26 Uhr

Unter http://www.roland-weigelt.de/ghostdoc/ kann man mein Lieblingsplugin für das Visual Studio 2005 herunter laden.

Mit GhostDoc kann man durch einfaches Klicken auf den Methodenkopf sich die eine Standard-XML-Dokumentation für die Routine erstellen lassen, die auch alle Parameter und Rückgabewerte dokumentiert. In ungefähr 90% der Fälle (Properties, Standardroutinen wie ToString() usw.) reicht diese automatische Dokumentation schon völlig aus. In den übrigen Fällen braucht man nur noch die entsprechenden Ergänzungen vornehmen.

Ein weiteres nettes Feature ist das die Dokumentation bei geerbter Funktionalität immer aus der Basisklasse übertragen wird. Damit braucht man in abgeleiteten Klassen kaum noch selbst Dokumentation schreiben. Das spart enorm viel Zeit und damit sind alle Ausreden weg auf eine Dokumentation zu verzichten.

Friday, 31. March 2006


AjaxWrite und AjaxSketch

Filed under: ASP.NET — Steffen Forkmann at 14:02 Uhr

Falls mal wieder keine Textverarbeitung installiert ist, kann man jetzt auf die folgende Online Alternative zurückgreifen: AjaxWrite. Funktioniert prima ohne Installation und besser als Wordpad ist es allemal. Desweiteren gibt es von dem gleichen Anbieter jetzt ein Online-Sketch Prgramm namens AjaxSketch, welches auch SVG Export ermöglicht. Benötigt wird lediglich Firefox 1.5 oder neuer. 

Tags:

Thursday, 30. March 2006


Navision: Universeller Dataport

Filed under: Navision — Steffen Forkmann at 15:39 Uhr

Aufgrund eines Artikels vom “Nawischn-Blog” möchte ich hier mal einen Weg aufzeigen, wie man sich einen universellen Dataport für Microsoft Navision bauen kann, mit dem man ein ganzen Satz an Tabellen aus CSV-Tabellen einlesen kann. Interessant ist das vor allem wenn man eine Datenübernahme machen will und im ersten Schritt erstmal alle Daten in Zwischentabellen ins Navision ziehen will.

Um den automatischen Import bewerkstelligen zu können müssen die Zieltabellen angelegt werden. Dafür braucht man jedoch Informationen über die Struktur der Daten – also welches Feld kommt mit welchem Datentyp an welcher Position in welcher Importdatei. Das ist zugleich auch der schwierigste Teil.

Glücklicherweise kann man sowas auch teilweise automatisch machen – zum Beispiel für Exceltabellen oder dBase-Datenbanken: Mit einem PlugIn für den Total Commander kann man nämlich Excel-Dateien bzw. eine ganze dBase-Datenbank mit einer Schema.ini exportieren. Bei einzelnen Dateien kann man das natürlich auch schnell per Hand anlegen.

Ab nun läuft alles automatisch. Als erstes müssen die Zieltabellen angelegt werden. Dazu habe ich eine Template-Tabelle angelegt die nur ein Feld für die laufende Datensatznummer enthält, die Zieltabellen werden dann aus dieser Tabelle kopiert:

PROCEDURE CreateTable@1000000007( p_NewObjectID@1000000002 : Integer; p_NewObjectName@1000000003 : Text[250]); VAR l_Object@1000000004 : Record 2000000001; l_NewObject@1000000005 : Record 2000000001; BEGIN // Copy Migration Template Table l_Object.GET(l_Object.Type::Table,'', DATABASE::"Migration Template"); l_Object.CALCFIELDS("BLOB Reference"); l_NewObject.INIT; l_NewObject.COPY(l_Object); l_NewObject.ID := p_NewObjectID; l_NewObject.Name := p_NewObjectName; l_NewObject.INSERT(TRUE); END;

Der Umweg mit der Template-Tabelle kommt dadurch zustande, dass man beim Insert in die Objekt-Tabelle schon einen Primärschlüßel haben muss und den kann man nur anlegen wenn man ein Feld anlegt. Felder können jedoch nur in in existierende Tabellen eingefügt werden. Diesen Konflikt konnte ich bisher nur über den Objekt-Designer auflösen. Als nächstes müssen die Felder aus der Schema.ini in die Zieltabellen eingefügt werden:

PROCEDURE AddFieldToTable@1000000009( p_TableNo@1000000001 : Integer; p_FieldID@1000000003 : Integer; p_FieldName@1000000002 : Text[250]; p_Type@1000000004 : Text[30]; p_Width@1000000005 : Integer); VAR l_Field@1000000000 : Record 2000000041; BEGIN l_Field.INIT; l_Field.TableNo := p_TableNo; l_Field."No." := p_FieldID; l_Field.FieldName:= p_FieldName; CASE p_Type OF 'Text': BEGIN l_Field.Type := l_Field.Type::Text; IF p_Width < 250 THEN l_Field.Len := p_Width ELSE l_Field.Len := 250; END; 'Date': l_Field.Type := l_Field.Type::Date; 'Double': l_Field.Type := l_Field.Type::Decimal; 'Long': l_Field.Type := l_Field.Type::Integer; 'Memo': BEGIN l_Field.Type := l_Field.Type::Text; l_Field.Len := 250; END; ELSE ERROR(Text003,p_Type); END; l_Field.Enabled := TRUE; l_Field.SQLDataType := l_Field.SQLDataType::Varchar; l_Field.INSERT(TRUE); END;

Nachdem nun alle Zieltabellen fertig sind, kann man nun durch die einzelnen CSV-Dateien gehen und die Daten in die entsprechenden Felder transportieren. Dazu durchläuft man die CSV-Tabellen zeilenweise und holt sich zum Beispiel mit folgenden Funktionen die einzelnen Feldwerte (per Index) aus dem Zeilentext:

PROCEDURE GetStringWithDelimiter@1000000011( p_Text@1000000000 : Text[1024]; p_ID@1000000001 : Integer; p_Delimiter@1000000002 : Char) Result : Text[1024]; VAR l_DelimiterCount@1000000003 : Integer; i@1000000004 : Integer; l_StringOpen@1000000005 : Boolean; BEGIN l_DelimiterCount := 1; FOR i := 1 TO STRLEN(p_Text) DO BEGIN IF (p_Text[i] = '"') AND (NOT l_StringOpen) THEN l_StringOpen := TRUE; IF (p_Text[i] = '"') AND l_StringOpen AND ((STRLEN(p_Text) = i) OR (p_Text[i+1] = p_Delimiter)) THEN l_StringOpen := FALSE; IF (p_Text[i] = p_Delimiter) AND NOT l_StringOpen THEN BEGIN l_DelimiterCount := l_DelimiterCount + 1; IF l_DelimiterCount > p_ID THEN EXIT(Result); END ELSE IF (l_DelimiterCount = p_ID) AND (p_Text[i] '"') THEN Result := Result + COPYSTR(p_Text,i,1); END; END; PROCEDURE GetString@1000000010( p_Text@1000000000 : Text[1024]; p_ID@1000000001 : Integer; p_Delimiter@1000000002 : Char) Result : Text[1024]; VAR l_DelimiterCount@1000000003 : Integer; i@1000000004 : Integer; l_StringOpen@1000000005 : Boolean; BEGIN l_DelimiterCount := 1; FOR i := 1 TO STRLEN(p_Text) DO BEGIN IF (p_Text[i] = p_Delimiter) THEN BEGIN l_DelimiterCount := l_DelimiterCount + 1; IF l_DelimiterCount > p_ID THEN EXIT(Result); END ELSE IF (l_DelimiterCount = p_ID) AND (p_Text[i] '"') THEN Result := Result + COPYSTR(p_Text,i,1); END; END;

Sunday, 26. March 2006


Visual SourceSafe (VSS) Integration in Microsoft Dynamics Nav

Filed under: C#,Navision,Tools — Steffen Forkmann at 19:09 Uhr

Da es keine native Möglichkeit gibt ein Quellcode-Versionsverwaltungsprogramm in Microsoft Navision einzubinden, haben wir bei der msu solutions GmbH eine eigene Lösung zum Zugriff auf Visual Source Safe oder Subversion (SVN) implementiert. Die entstandene Lösung ist ein Hybrid aus C# 2.0 COM-Objekten und nativen Navision-Objekten.

ObjectList

Der allgemeine Arbeitsablauf gestaltet sich nun folgendermaßen:

  1. Eine Aufgabe aus dem internen Bug & Task Tracker ziehen.
  2. Statt dem klassischen “Design” im Object Designer einfach im internen Object Designer auf “Auschecken” klicken. Dadurch wird das Objekt im VSS ausgecheckt und die aktuelle Version neu ins Navision importiert und im Designer geöffnet.
  3. Nun kann man im Navision Quelltext Editor Änderungen vornehmen und evtl. weitere Objekte auschecken.
  4. Vor dem Einchecken auf “Compare” klicken. Dadurch wird ein Diff zwischen der bearbeiteten Version und der Version im VSS angezeigt. (Das Diff-Programm kann frei gewählt werden. Standardmäßig ist WinMerge eingestellt.)
  5. Im internen Object Designer auf die ausgecheckten Objekte filtern und die Objekte durch Klick auf “Einchecken” mit dem aus dem Bug & Task Tracker vorgegebenen Checkin-Kommentar ins VSS einchecken.

Als weiteres besonderes Feature ist die Versionsgeschichte zu nennen. Im internen Object Designer kann man einfach auf ein Objekt gehen und durch Druck auf “History” die Versionsgeschichte des Objektes aus dem Visual SourceSafe abrufen. Dort kann man die Checkin-Kommentare ansehen, Version-Pins versetzen und sich Diffs zwischen den verschiedenen Versionen anzeigen lassen.

Versionsgeschichte

Interessant ist auch die interne Suchen nach Objekten (und deren Versionen bzw. Differenz dazwischen) die mit einer bestimmten Aufgabe geändert wurden. So fällt das Portieren von Features zwischen verschiedenen Entwicklungszweigen wesentlich leichter.

Suche in den Versionen

So macht das Programmieren in Navision gleich viel mehr Spaß und die Versionsverwaltung ist damit fast so einfach wie im Visual Studio – da bleiben dann ja nur noch die beiden größten Navision Schwächen: Editor und Debugger 🙂

Tags: , , , , , , , , , , ,