Sunday, 9. April 2006
Apr 09
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.
Apr 09
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
Mar 31
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:
ASP.NET
Thursday, 30. March 2006
Mar 30
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
Mar 26
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.

Der allgemeine Arbeitsablauf gestaltet sich nun folgendermaßen:
- Eine Aufgabe aus dem internen Bug & Task Tracker ziehen.
- 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.
- Nun kann man im Navision Quelltext Editor Änderungen vornehmen und evtl. weitere Objekte auschecken.
- 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.)
- 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.

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.

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:
C#,
com,
cvs,
Navision,
perforce,
quellcodeverwaltung,
source-safe,
subversion,
svn,
Tools,
visual-source-safe,
vss
Thursday, 23. February 2006
Feb 23
She sells C/Shells by the C/Shore.
The shells she sells are surely C/Shells.
So if she sells shells on the C/Shore,
I’m sure she sells C/Shore shells.
Wednesday, 15. February 2006
Feb 15
Unter http://www.themenmix.de/b2e/navblog.php schreibt Jörg Dutschke einen interessanten Navision-Blog. Hauptsächlich bringt er interessante Anekdoten aus seinem Support-Alltag.
Wednesday, 25. January 2006
Jan 25
In diesem Nightcast möchte Bernd Marquardt ein interessantes Thema aufgreifen. Er will in einer Stunde einen kleinen Sprach-Compiler entwickeln. Geplant sind ein kleine Einführung in Compilerbau und dann natürlich das Praktische also der Code, der notwendig ist, um einen eigenen Sprach-Compiler mit .NET zu entwickeln.
Wednesday, 18. January 2006
Jan 18
Ein Rename eines Datensatzes ist in Navision aufgrund der Überprüfung von TableRelations sehr langsam. Wenn man jedoch genau weiß was man tut, dann kann man jedoch relativ leicht eine enorme Performancesteigerung erreichen:
xRec := Rec;
DELETE;
INIT;
Rec := xRec;
Rec.MyKeyField := newKeyValue;
Rec.MyField := newValue1;
...
Insert;
Tuesday, 17. January 2006
Jan 17
Wie wäre es denn, wenn man einen .NET WebService auf einen Apache WebServer zum laufen bringen könnte. Eine Möglichkeit besteht darin, sich auf dieser Seite den Apache HTTP Server in der Version 2.0 und außerdem das “mod_aspdotnet Apache HTTP Server 2.0 Module”, was es hier gibt herunterzuladen.
Als einzige Vorraussetzung braucht man das Microsoft .NET Framework in Version 1.0 oder 1.1, welches installiert sein muss. Es funktioniert leider nicht mit der ASP.NET Version 2.0.
Nun zur Vorgehensweise:
- Alles installieren und mit einem Browser testen. Dazu einfach http://localhost/
oder http://localhost:8080/ (je nachdem was man bei der Installation gewählt hat) eingeben und es müsste der folgende Bildschirm erscheinen:

- Als nächstes muss man die httpd.conf mit einem Texteditor öffnen und folgende Zeilen hinzufügen:
LoadModule aspdotnet_module modules/mod_aspdotnet.so
# Use the asp.net handler for all common ASP.NET file types
AddHandler asp.net asax ascx ashx asmx aspx axd config cs csproj licx rem resources resx soap vb vbproj vsdisco webinfo
# Mount the IBuySpy C# example application
AspNetMount /StoreCSVS “C:/StoreCSVS/StoreCSVS”
# Map all requests for /StoreCSVS to the IBuySpy application files
Alias /StoreCSVS “C:/StoreCSVS/StoreCSVS”
# Allow asp.net scripts to be executed in the IBuySpy example
Options FollowSymlinks ExecCGI
Order allow,deny
Allow from all
DirectoryIndex Default.htm Default.aspx
# For all virtual ASP.NET webs, we need the aspnet_client files
# to serve the client-side helper scripts.
AliasMatch /aspnet_client/system_web/(\d+)_(\d+)_(\d+)_(\d+)/(.*) “C:/Windows/Microsoft.NET/Framework/v$1.$2.$3/ASP.NETClientFiles/$4”
Options FollowSymlinks
Order allow,deny
Allow from all
- Die Pfade müssen natürlich entsprechend dem Projekt angepasst werden und wenn alles funktioniert hat erhält man folgende Seite:

Ein Problem ist natürlich, dass es kein ASP.NET 2.0 unterstützt, aber auch hierfür gibt es eine Lösung wenn man kein IIS unter Windows betreiben will. Man läd sich das mod_mono Modul von der Mono Seite und schon ist der Apache Webserver auch für ASP.NET gerüstet (wenn das Mono Framework installiert ist), aber dieses Modul gibt es bis jetzt nur für Linux.
Weitere Informationen zu Webservices
Tags:
ASP.NET,
WCF