...feel the spirit of Microsoft Dynamics AX RSS 2.0
 Friday, June 11, 2010

Ein großer Vorteil des Application Integration Frameworks (AIF) gegenüber “selbst geschriebene” Schnittstellen ist es, dass man sich über Dinge wie Datentyp-Mapping keine Gedanken machen muss.
Das Application Integration Framework verfügt über die entsprechende Logik, um alle Dynamic AX Datentypen automatisch in den jeweils gültigen XSD-Datentyp zu “mappen” (oder umgekehrt).

Zeiten, in denen sich der Entwickler zum Beispiel Gedanken machen musste, wie viele Nachkommastellen eine Zahl haben darf, oder welches Zeichen als Dezimaltrennzeichen verwendet werden muss, sind somit vorbei.
Da alle Daten die aus Dynamics AX exportiert oder nach Dynamics AX importiert werden, in einem XSD-Schema konformen XML-Dokument “transportiert” werden, und das AIF entsprechendes Mapping bereits stellt, geschieht das Datentyp-Mapping automatisch.

Allerdings kann auf Seiten der Anwendung, welche über das Application Integration Framework (AIF) angebunden werden soll, ein wenig “Verwirrung” entstehen.
Durch die von Programmiersprache zu Programmiersprache durchaus unterschiedlichen Datentypen kann es vorkommen, dass Dynamics AX Datentypen nicht in dem erwarteten Datentyp der anderen Programmiersprache erscheinen.
Dies ist allerding kein “wirkliches” Problem des Application Integration Frameworks (AIF), sondern eher eine Frage, welche Datentypen eine Programmiersprache bereit stellt und wie diese in XSD-Datentypen “gemappt” werden.

Ein gutes Beispiel hierfür sind die Dynamics AX Datentypen “Date”, “Time” und “DateTime” (inklusive aller von diesen Basisdatentypen abgeleiteten EDT’s).

Ohne genauere Betrachtung liegt die Annahme nahe, dass ein DateTime Datentyp von Dynamics AX in einen DateTime Datentyp von z.B. C# “gemappt” wird.
Dies ist allerdings nicht richtig. Da nicht direkt zwischen Dynamics AX Datentyp und C# Datentyp gemappt wird, sondern immer von/zu einem XSD-Datentyp gemappt wird, wird in C# eine neue Klasse hierfür erzeugt.

Ein wenig schwieriger wird es bei den beiden Dynamics AX Datentypen “Date” und “Time”. Für diese Datentypen wird z.B. in C# kein direkt vergleichbarer Datentyp bereit gestellt.
Diese Datentypen werden jeweils als C# DateTime Datentypen gemappt.

Das Mapping der Datentypen geschieht wie folgt:

Dynamics AX

XSD Schema

.NET (C#)

Date

xs:date System.DateTime

Time

xs:time System.DateTime

DateTime

xs:dateTime new class
i.e. “AxdType_DateTime”


Da die beiden Dynamics AX Datentypen “Date” und “Time” in den C# Datentyp “DateTime” gemappt werden, kann an dieser Stelle leider ein kleines Problem entstehen.
In C# ist nun leider nicht mehr zu erkennen, um was für einen Dynamics AX Datentyp es sich z.B. bei einem Feld handelt, und ob nun ein Datum oder eine Zeit in diesem enthalten ist.

Oftmals entsteht diese Problem dadurch nicht, dass der jeweilige Business-Kontext die Datentypverwendung entsprechend einschränkt und es somit teilweise egal ist ob nun in ein Dynamics AX Date oder Time gemappt wird.
Ist es aber erforderlich zu wissen, um ob ein Feld nun den Dynamics AX Datentyp Date oder Time hat, kann der generierte Code der Proxyklasse Aufschluss geben (oder das XSD-Schema).

Durch die Angabe eines Serialisierungs-Attributes wird bestimmt, welcher “Teil” des DateTime Datentyps verwendet wird.
Für ein Feld, welches in einen Dynamics AX Date Datentyp gemappt wird, wird nur der “Datumsteil” in das XML-Dokument serialisiert.
Entsprechendes geschieht für einen Dynamics AX Time Datentyp.

Mapping eines C# Datetime Datentyps in einen Dynamics AX Date Datentyp (generierter Code der Proxyklasse):

   1:  [System.Xml.Serialization.XmlElementAttribute(DataType="date", IsNullable=true, Order=54)]
   2:  public System.Nullable<System.DateTime> MyDateField {
   3:      get {
   4:          return this.myDateFieldField;
   5:      }
   6:      set {
   7:          this.myDateFieldField = value;
   8:          this.RaisePropertyChanged("MyDateField");
   9:      }
  10:  }

Mapping eines C# Datetime Datentyps in einen Dynamics AX Time Datentyp (generierter Code der Proxyklasse):

   1:  [System.Xml.Serialization.XmlElementAttribute(DataType="time", IsNullable=true, Order=56)]
   2:  public System.Nullable<System.DateTime> MyTimeField {
   3:      get {
   4:          return this.myTimeFieldField;
   5:      }
   6:      set {
   7:          this.myTimeFieldField = value;
   8:          this.RaisePropertyChanged("MyTimeField");
   9:      }
  10:  }

Wie durch den generierten Code der Proxyklasse ersichtlich wird, wird nur der jeweils benötigte “Teil” eines C# Datetime Datentyps serialisiert/deserialisiert und somit verwendet.

Für einen Dynamics AX DateTime Datentyp wird bei Erstellung des Proxys eine neue Klasse generiert. Somit kann der Dynamics AX Datentyp hierbei immer eindeutig identifiziert werden.

   1:  [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.4016")]
   2:  [System.SerializableAttribute()]
   3:  [System.Diagnostics.DebuggerStepThroughAttribute()]
   4:  [System.ComponentModel.DesignerCategoryAttribute("code")]
   5:  [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/Customer")]
   6:  public partial class AxdType_DateTime : object, System.ComponentModel.INotifyPropertyChanged {
   7:          
   8:      private System.DateTime localDateTimeField;
   9:          
  10:      private bool localDateTimeFieldSpecified;
  11:          
  12:      private AxdEnum_Timezone timezoneField;
  13:          
  14:      private bool timezoneFieldSpecified;
  15:          
  16:      private System.DateTime valueField;
  17:         
  18:      [System.Xml.Serialization.XmlAttributeAttribute()]
  19:      public System.DateTime localDateTime ...  
  20:      
  21:      [System.Xml.Serialization.XmlIgnoreAttribute()]
  22:      public bool localDateTimeSpecified...   
  23:      
  24:      [System.Xml.Serialization.XmlAttributeAttribute()]
  25:      public AxdEnum_Timezone timezone...
  26:          
  27:      [System.Xml.Serialization.XmlIgnoreAttribute()]
  28:      public bool timezoneSpecified...
  29:         
  30:      [System.Xml.Serialization.XmlTextAttribute()]
  31:      public System.DateTime Value {
  32:          
  33:      public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
  34:          
  35:      protected void RaisePropertyChanged(string propertyName)...
  36:  }

Dieses Verhalten ist nicht nur mit C# zu beobachten. Auch JAVA oder andere Programmiersprachen verhalten sich ähnlich und muss entsprechend berücksichtigt werden.

Friday, June 11, 2010 8:33:13 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  |  |  |  |  |  |  | 

 Monday, March 02, 2009

Wie in einem Artikel auf der Microsoft Dynamics AX Webseite zu lesen ist wird der "alte" COM Business Connector nicht mehr in zukünftigen Versionen von Dynamics AX enthalten sein.
The COM Business Connector will be discontinued in future releases of Microsoft Dynamics AX

Bereits in der Version 2009 von Microsoft Dynamics AX wird der COM Business Connector vom "normalen" Setup nicht mehr angeboten.
Dieser muss manuell, wie im Microsoft Dynamics AX Developer Center beschrieben, nachinstalliert werden.
How to: Install COM Business Connector using Command-line Options

Somit ist es an der Zeit, bestehende Lösungen welche den COM Business Connector verwenden, auf den neueren .NET Business Connector zu portieren, um diese Lösungen auch in zukünftigen Versionen verwenden zu können.

Alle benötigten Informationen über die Verwendung des .NET Business Connectors können in der Library des Microsoft Dynamics AX Developer Centers gefunden werden
.NET Business Connector Overview

 

Monday, March 02, 2009 8:21:05 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  |  |  | 

Oft ist in Newsgroups und Foren die Frage zu lesen, wie .NET (CLR) Arrays in X++ verwendet, bzw. wie diese deklariert werden können.
Im Großen und Ganzen unterscheidet sich die Syntax für die Verwendung eines .NET Array kaum von der eines reinen X++ Array.
.NET Arrays können in X++ sogar auf zwei verschiedene Arten deklariert werden.

Variante 1:

Die Deklaration eines .NET Arrays erfolgt analog zu der Deklaration eines "reinen" X++ Arrays:

System.Object[] arrayOfObjects;
System.Int32[] arrayOfIntegers;

Die Syntax für die Instanzierung des .NET Array weicht allerdings leicht von der "normalen" X++ Syntax ab:

arrayOfObjects = new System.Object[10]();
arrayOfIntegers = new System.Int32[3]();

Wichtig ist hierbei, dass immer "()" verwendet wird.

Um die Werte eines .NET Arrays zu setzen wird die Methode "SetValue()" verwendet:

arrayOfObjects.SetValue(myObject, 0);
arrayOfIntegers.SetValue(300, 1);

Um Werte aus einem Array abzufragen kann die Methode "GetValue" verwendet werden:

arrayOfObjects.GetValue(0);
arrayOfIntegers.GetValue(1);

Eine weitere sehr nützliche Methode ist die Methode "get_Length()". Diese liefert die Anzahl der Array-Elemente zurück.

Variante 2:

Alternativ zur ersten Variante besteht noch die Möglichkeit, ein .NET Array über die Klasse System.Array zu erzeugen.
Leider stößt man bei diesem Weg immer mal wieder auf kleinere Probleme, weswegen die erste Variante für die Verwendung von .NET Array bevorzugt werden sollte.

Eine etwas ausführlichere Beschreibung der Verwendung von .NET Array in X++ bzw. deren besonderheiten und Abweichungen zur "normalen" X++ Syntax kann im Microsoft Dynamics AX Developer Center gefunden werden.

How to: Use X++ Syntax for CLR Arrays

Monday, March 02, 2009 7:40:39 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  |  | 

 Wednesday, December 19, 2007

Einen ersten Ausblick auf die "neuen" Quellcodeverwaltungsfeatures in Microsoft Dynamics AX 5.0 zeigt der Screencast "Version control in MorphX" auf Channel9.

http://channel9.msdn.com/Showpost.aspx?postid=367024

Ich zitiere:
"This screencast is a preview of the version control system integration options in the next release of MorphX - the IDE of Dynamics AX.
It shows a side-by-side comparison of the integration options with Team Foundation Server, Visual Source Safe, and MorphX VCS. 
The latter is a simple, yet powerful alternative without any additional infrastructure requirements. The last half of the screencast gives a demonstration of MorphX VCS."

Durch die neuen Features die MorphX VCS mit sich bringt, sowie die Möglichkeit Visual Studio Team System, oder genauer der Team Foundation Server, (nicht nur) als Quellcodeverwaltung zu verwenden, sollte nun für jeden ein "passendes" Quellcodeverwaltungsystem bereit stehen.

Vielen Dank an dieser Stelle an Michael Fruergaard Pontoppidan (http://blogs.msdn.com/mfp/default.aspx) für diesen und die bisherigen Screencasts über Microsoft Dynamics AX. 

Wednesday, December 19, 2007 8:24:13 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  |  |  |  | 

 Friday, November 02, 2007

Man kann viel darüber lesen, dass es ab der Version 4.0 von Microsoft Dynamics AX möglich ist auch mit .NET Objekten innerhalb von Dynamics AX zu arbeiten. Leider fehlt es oft an konkreten Beispielen, die einen ersten Überblick geben, wie man was machen muss.

Jeder der sich mit dem Thema schon einmal auseinander setzen musste, wird mit hoher Wahrscheinlichkeit auf eines dieser „Probleme“ gestoßen sein:

  • Wie kann ein Datum zwischen Dynamics AX und .NET ausgetauscht werden?
  • Wie kann die aktuelle Zeit an ein .NET Objekt übermittelt werden?
  • Wie rufe ich eigentlich Werte eines .NET Enums ab?

Diese Liste könnte man noch beliebig erweitern.

Damit man einen kleinen Anhaltspunkt hat, wie die „Arbeit“ mit .NET Objekten gehen kann, soll dies anhand des Beispiels „Anlegen eines Termins in Outlook“ vorgestellt werden.

Zuerst muss eine Referenz zur der .NET Assembly erstellt werden, welche im Weitern verwendet werden soll. Hierzu muss im AOT der Zweig „References“ gewählt werden und über das Kontextmenü „Verweis hinzufügen“ ausgewählt werden.

In der neuen Maske wird die Assembly ausgewählt zu der eine Referenz erstellt werden soll. Hierzu navigiert man zu der entsprechenden Assembly und wählt diese über „Auswählen“ aus. Mit dem Drücken von „OK“ werden zu den ausgewählten Assemblys die Referenzen erstellt.

Bei diesem Beispiel wurde eine Referenz zur Assembly „Microsoft.Office.Interop.Outlook“ erstellt.

Ab jetzt können alle .NET Objekte, die in dieser Assembly enthalten sind, in Dynamics AX verwendet werden.

Wie dies im Einzelnen geschieht kann dem folgenden Beispiel entnommen werden, wo demonstriert wird, wie man aus Dynamics AX heraus ein Outlook Termin erstellt werden kann.

static void CreateOutlookAppointment(Args _args)
{
   //.NET (CLR) Datentypen
   InteropPermission permission;
   Microsoft.Office.Interop.Outlook._Application outlookApplication;
   Microsoft.Office.Interop.Outlook._AppointmentItem outlookAppointment;
   Microsoft.Office.Interop.Outlook.OlItemType outlookItemType;
   System.DateTime appointmentStartTime;
   System.DateTime appointmentEndTime;

   //Dynamics AX Datentypen
   Date1980 startDate, endDate;
   TimeExpected startTime, endTime;
   ;
   permission = new InteropPermission(InteropKind::ClrInterop);
   if (permission == null)
   {
      return;
   }
   //”Unsichere” Aufrufe starten
   permission.assert();

   //Das Outlook Application Objekt instanzieren
   //(Beispiel für Erstellung eines .NET Klassenobjekts)
   outlookApplication = new Microsoft.Office.Interop.Outlook.ApplicationClass();

   //Gewünschten Outlook-Elementtyp auswählen
   //(Beispiel für Zuweisung eines .NET Enum Wertes)
   outlookItemType = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Outlook.OlItemType', 'olAppointmentItem');

   //Gewünschten Outlook-Elemnttyp erstellen (Termin)
   outlookAppointment = outlookApplication.CreateItem(outlookItemType);

   //Den Betreff zuweisen
   //(Beispiel für Zuweisung eines "einfachen" Wertes)
   outlookAppointment.set_Subject("Ein Test aus Dynamics AX");

   startDate = str2Date("25.10.2007", 123);
   startTime = str2Time("10:30:00");
   //"Beginnt um" zuweisen
   //(Beispiel für Konvertierung Dynamics AX Datum/Zeit -> .NET DateTime)
   appointmentStartTime = System.Convert::ToDateTime(strfmt("%1 %2", startDate, time2str(startTime, 0, 0)));
   outlookAppointment.set_Start(appointmentStartTime);

   endDate = str2Date("26.10.2007", 123);
   endTime = str2Time("11:00:00");
   //"Endet um" zuweisen
   appointmentEndTime = System.Convert::ToDateTime(strfmt("%1 %2", endDate, time2str(endTime, 0, 0)));
   outlookAppointment.set_End(appointmentEndTime);

   //Den Termin speichern (ab jetzt ist der Termin in Outlook zu sehen)
   outlookAppointment.Save();

   //”Unsichere” Aufrufe beenden
   CodeAccessPermission::revertAssert();
}

Friday, November 02, 2007 6:06:11 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  |  | 



Translate
Über/Kontakt

     







© Copyright 2013 Axel Kühn
Sign In
Subscribe this blog
Blogroll
 Arijit Basu
 Axapta Blog
Blog around Microsoft Business Solutions Axapta by Helmut Wimmer
 BlaBlubBlog
Der Blog von Kai Gloth
 Dave Bowles
 Dick Wenning
Ax(apta) start pages
 Fred Shen
 Harish Mohanbabu
 jinx´s AX Blog
Everything about Microsoft Dynamcis AX
 Lars Keller
All about .NET, VSTS, VSTO and more
 Max Belugin
 TaReMoTi Blog
Der Blog von Karsten Döring
Archiv
<May 2013>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
Statistik
Total Posts: 138
This Year: 0
This Month: 0
This Week: 0
Comments: 49





All Content © 2013, Axel Kühn
DasBlog theme 'Business' created by Christoph De Baene (delarou)