<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Aku's AX Blog - Dynamics Ax|Programmierung</title>
    <link>http://blog.ak-home.net/</link>
    <description>...feel the spirit of Microsoft Dynamics AX</description>
    <language>de</language>
    <copyright>Axel Kühn</copyright>
    <lastBuildDate>Mon, 07 Feb 2011 18:59:20 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>kuehn@ak-home.net</managingEditor>
    <webMaster>kuehn@ak-home.net</webMaster>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=f0ddb444-5f09-4970-9d63-e909bf24edf9</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,f0ddb444-5f09-4970-9d63-e909bf24edf9.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,f0ddb444-5f09-4970-9d63-e909bf24edf9.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=f0ddb444-5f09-4970-9d63-e909bf24edf9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Das Speichern eines Datensatzes in einem Tabellen-Feld ist an sich kein Problem.<br />
Aber leider ist dies eine der nicht so oft verwendeten Sachen in der Dynamics AX Entwicklung
und wird deshalb immer mal gerne wieder vergessen. :-)
</p>
        <p>
Wir haben also eine Tabelle mit einem Feld, welches einen Container als Datentyp hat.<br />
Weiterhin haben wir einen Datensatz welchen wir in diesem Feld speichern wollen.<br />
Wie bekommen wir nun den Datensatz in dem Feld gespeichert? Ein direkte Zuweisung
für hierbei leider zu einem Fehler.
</p>
        <p>
Für diese Operationen stellt der Dynamics AX Standard folgende Funktionen zur Verfügung:
</p>
        <ul>
          <li>
buf2con(common buffer) 
</li>
          <li>
con2buf(container c, common buffer)</li>
        </ul>
        <p>
          <u>
            <strong>Schreiben des Datensatzes in das Tabellenfeld</strong>
          </u>
        </p>
        <p>
Die Funktion “buf2Con” wandelt eine Datensatz in einen Container, welcher entsprechend
in dem Tabellen-Feld gespeichert werden kann.
</p>
        <p>
          <strong>
            <u>Lesen des Datensatzes aus dem Tabellenfeld</u>
          </strong>
        </p>
        <p>
Die Funktion “con2buf” wandelt einen Container (genauer dessen Inhalt) wieder zu einem
Datensatz um.
</p>
        <p>
Allerdings sollte bei der Verwendung dieser beiden Funktionen immer bedacht werden,
dass Änderungen an Tabellen, von denen Datensätze auf diese Art gespeichert werden
zu Problemen führen können.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f0ddb444-5f09-4970-9d63-e909bf24edf9" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Einen Datensatz in einem Tabellenfeld einer anderen Tabelle speichern</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,f0ddb444-5f09-4970-9d63-e909bf24edf9.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,f0ddb444-5f09-4970-9d63-e909bf24edf9.aspx</link>
      <pubDate>Mon, 07 Feb 2011 18:59:20 GMT</pubDate>
      <description>&lt;p&gt;
Das Speichern eines Datensatzes in einem Tabellen-Feld ist an sich kein Problem.&lt;br&gt;
Aber leider ist dies eine der nicht so oft verwendeten Sachen in der Dynamics AX Entwicklung
und wird deshalb immer mal gerne wieder vergessen. :-)
&lt;/p&gt;
&lt;p&gt;
Wir haben also eine Tabelle mit einem Feld, welches einen Container als Datentyp hat.&lt;br&gt;
Weiterhin haben wir einen Datensatz welchen wir in diesem Feld speichern wollen.&lt;br&gt;
Wie bekommen wir nun den Datensatz in dem Feld gespeichert? Ein direkte Zuweisung
für hierbei leider zu einem Fehler.
&lt;/p&gt;
&lt;p&gt;
Für diese Operationen stellt der Dynamics AX Standard folgende Funktionen zur Verfügung:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
buf2con(common buffer) 
&lt;li&gt;
con2buf(container c, common buffer)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;u&gt;&lt;strong&gt;Schreiben des Datensatzes in das Tabellenfeld&lt;/strong&gt;&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Die Funktion “buf2Con” wandelt eine Datensatz in einen Container, welcher entsprechend
in dem Tabellen-Feld gespeichert werden kann.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Lesen des Datensatzes aus dem Tabellenfeld&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Die Funktion “con2buf” wandelt einen Container (genauer dessen Inhalt) wieder zu einem
Datensatz um.
&lt;/p&gt;
&lt;p&gt;
Allerdings sollte bei der Verwendung dieser beiden Funktionen immer bedacht werden,
dass Änderungen an Tabellen, von denen Datensätze auf diese Art gespeichert werden
zu Problemen führen können.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f0ddb444-5f09-4970-9d63-e909bf24edf9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,f0ddb444-5f09-4970-9d63-e909bf24edf9.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=adfe4c38-e6c3-47b3-a644-930be36f1a04</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,adfe4c38-e6c3-47b3-a644-930be36f1a04.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,adfe4c38-e6c3-47b3-a644-930be36f1a04.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=adfe4c38-e6c3-47b3-a644-930be36f1a04</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Mit Microsoft Dynamics AX 2009 wird für die Erstellung neuer dokumentenbasierter AIF-Services
ein Tool/Wizard mitgeliefert, der so genannte “Assistent für AIF-Dokumentendienste”,
welcher den Entwickler bei der Erstellung eines neuen AIF-Services unterstützt.
</p>
        <p>
Wie dieser Wizard verwendet wird, kann zum Beispiel in der MSDN nachgelesen werden:
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/aa609947.aspx">How to: Create a Service
Using the AIF Document Service Wizard</a>
          <br />
          <a href="http://msdn.microsoft.com/en-us/library/cc589855.aspx">Walkthrough: Creating
a Service Using the AIF Document Service Wizard</a>
        </p>
        <p>
In den meisten Fällen funktioniert dieser Wizard auch sehr gut und bietet somit eine
echte Entwicklungsunterstützung.<br />
Es gibt allerdings auch Fälle in denen der Wizard auf einen Fehler läuft, welche auf
den ersten Blick sehr schwer zu verstehen sind.
</p>
        <p>
Ein Beispiel hierfür sind Tabellen, die ein Feld beinhalten welches als Datentyp den
Extended Data Type “InventDimId” definiert hat.<br />
Wird beim Erstellen des Query-Objekts für den AIF-Service nicht darauf geachtet, dass
auch die Tabelle  InventDim mit entsprechender Relation in die Query aufgenommen
wird, erzeugt der Wizard eine Fehlermeldung.
</p>
        <p>
Wird folgende Query für den neuen AIF-Service angelegt und diese für die Generierung
des AIF-Service verwendet
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryNotWorking.jpg" target="_blank">
            <img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="AxdQueryNotWorking" border="0" alt="AxdQueryNotWorking" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryNotWorking_thumb.jpg" width="240" height="244" />
          </a>
        </p>
        <p>
erzeugt der Assistent für AIF-Dokumentendienste folgenden Fehler:
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AifWizardError.jpg" target="_blank">
            <img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="AifWizardError" border="0" alt="AifWizardError" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AifWizardError_thumb.jpg" width="244" height="104" />
          </a>
        </p>
        <p>
Um diesem Problem aus dem Weg zu gehen, muss die Tabelle “InventDim” mit in die Query
aufgenommen werden, selbst wenn diese für den Dokumentkontext nicht von Bedeutung
ist.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryWorking.jpg" target="_blank">
            <img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="AxdQueryWorking" border="0" alt="AxdQueryWorking" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryWorking_thumb.jpg" width="244" height="195" />
          </a>
        </p>
        <p>
Anmerkung:<br />
An dieser Stelle soll auch auf den Punkt hingewiesen werden, dass der Assistent für
AIF-Dokumentendienste keinen vollständig funktionsfähigen AIF-Service erstellt.<br />
Es wird eher mehr das Grundgerüst des AIF-Service angelegt und der Entwickler muss
nach Ausführung des Wizards unter Anderem noch die benötigte Business-Logik ergänzen
um die gewünschte Funktionalität bereit stellen zu können.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=adfe4c38-e6c3-47b3-a644-930be36f1a04" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Assistent für AIF-Dokumentendienste und Tabellen mit InventDimId</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,adfe4c38-e6c3-47b3-a644-930be36f1a04.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,adfe4c38-e6c3-47b3-a644-930be36f1a04.aspx</link>
      <pubDate>Thu, 05 Aug 2010 19:30:32 GMT</pubDate>
      <description>&lt;p&gt;
Mit Microsoft Dynamics AX 2009 wird für die Erstellung neuer dokumentenbasierter AIF-Services
ein Tool/Wizard mitgeliefert, der so genannte “Assistent für AIF-Dokumentendienste”,
welcher den Entwickler bei der Erstellung eines neuen AIF-Services unterstützt.
&lt;/p&gt;
&lt;p&gt;
Wie dieser Wizard verwendet wird, kann zum Beispiel in der MSDN nachgelesen werden:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/aa609947.aspx"&gt;How to: Create a Service
Using the AIF Document Service Wizard&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/cc589855.aspx"&gt;Walkthrough: Creating
a Service Using the AIF Document Service Wizard&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In den meisten Fällen funktioniert dieser Wizard auch sehr gut und bietet somit eine
echte Entwicklungsunterstützung.&lt;br&gt;
Es gibt allerdings auch Fälle in denen der Wizard auf einen Fehler läuft, welche auf
den ersten Blick sehr schwer zu verstehen sind.
&lt;/p&gt;
&lt;p&gt;
Ein Beispiel hierfür sind Tabellen, die ein Feld beinhalten welches als Datentyp den
Extended Data Type “InventDimId” definiert hat.&lt;br&gt;
Wird beim Erstellen des Query-Objekts für den AIF-Service nicht darauf geachtet, dass
auch die Tabelle&amp;nbsp; InventDim mit entsprechender Relation in die Query aufgenommen
wird, erzeugt der Wizard eine Fehlermeldung.
&lt;/p&gt;
&lt;p&gt;
Wird folgende Query für den neuen AIF-Service angelegt und diese für die Generierung
des AIF-Service verwendet
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryNotWorking.jpg" target=_blank&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=AxdQueryNotWorking border=0 alt=AxdQueryNotWorking src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryNotWorking_thumb.jpg" width=240 height=244&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
erzeugt der Assistent für AIF-Dokumentendienste folgenden Fehler:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AifWizardError.jpg" target=_blank&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=AifWizardError border=0 alt=AifWizardError src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AifWizardError_thumb.jpg" width=244 height=104&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Um diesem Problem aus dem Weg zu gehen, muss die Tabelle “InventDim” mit in die Query
aufgenommen werden, selbst wenn diese für den Dokumentkontext nicht von Bedeutung
ist.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryWorking.jpg" target=_blank&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=AxdQueryWorking border=0 alt=AxdQueryWorking src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/AssistentfrAIFDokumentendiensteundTabell_12592/AxdQueryWorking_thumb.jpg" width=244 height=195&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Anmerkung:&lt;br&gt;
An dieser Stelle soll auch auf den Punkt hingewiesen werden, dass der Assistent für
AIF-Dokumentendienste keinen vollständig funktionsfähigen AIF-Service erstellt.&lt;br&gt;
Es wird eher mehr das Grundgerüst des AIF-Service angelegt und der Entwickler muss
nach Ausführung des Wizards unter Anderem noch die benötigte Business-Logik ergänzen
um die gewünschte Funktionalität bereit stellen zu können.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=adfe4c38-e6c3-47b3-a644-930be36f1a04" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,adfe4c38-e6c3-47b3-a644-930be36f1a04.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Tools</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=0af37380-886b-44e0-a6ec-ad04fc527ef8</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,0af37380-886b-44e0-a6ec-ad04fc527ef8.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,0af37380-886b-44e0-a6ec-ad04fc527ef8.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=0af37380-886b-44e0-a6ec-ad04fc527ef8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.<br />
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).
</p>
        <p>
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.<br />
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.
</p>
        <p>
Allerdings kann auf Seiten der Anwendung, welche über das Application Integration
Framework (AIF) angebunden werden soll, ein wenig “Verwirrung” entstehen.<br />
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.<br />
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.
</p>
        <p>
Ein gutes Beispiel hierfür sind die Dynamics AX Datentypen “Date”, “Time” und “DateTime”
(inklusive aller von diesen Basisdatentypen abgeleiteten EDT’s).
</p>
        <p>
Ohne genauere Betrachtung liegt die Annahme nahe, dass ein DateTime Datentyp von Dynamics
AX in einen DateTime Datentyp von z.B. C# “gemappt” wird.<br />
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. 
</p>
        <p>
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.<br />
Diese Datentypen werden jeweils als C# DateTime Datentypen gemappt.
</p>
        <p>
Das Mapping der Datentypen geschieht wie folgt:
</p>
        <table border="0" cellspacing="0" cellpadding="0" width="600">
          <tbody>
            <tr height="20">
              <td width="198" align="middle">
                <p align="center">
                  <strong>Dynamics AX</strong>
                </p>
              </td>
              <td width="198" align="middle">
                <p align="center">
                  <strong>XSD Schema</strong>
                </p>
              </td>
              <td width="202" align="middle">
                <p align="center">
.<strong>NET (C#)</strong></p>
              </td>
            </tr>
            <tr height="20">
              <td width="198" align="middle">
                <p align="center">
Date
</p>
              </td>
              <td width="198" align="middle">
xs:date</td>
              <td width="202" align="middle">
System.DateTime</td>
            </tr>
            <tr height="20">
              <td width="198" align="middle">
                <p align="center">
Time
</p>
              </td>
              <td width="198" align="middle">
xs:time</td>
              <td width="202" align="middle">
System.DateTime</td>
            </tr>
            <tr height="20">
              <td width="198" align="middle">
                <p align="center">
DateTime
</p>
              </td>
              <td width="199" align="middle">
xs:dateTime</td>
              <td width="203" align="middle">
new class<br />
i.e. “AxdType_DateTime”</td>
            </tr>
          </tbody>
        </table>
        <p>
          <br />
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.<br />
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.
</p>
        <p>
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.<br />
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).
</p>
        <p>
Durch die Angabe eines Serialisierungs-Attributes wird bestimmt, welcher “Teil” des
DateTime Datentyps verwendet wird.<br />
Für ein Feld, welches in einen Dynamics AX Date Datentyp gemappt wird, wird nur der
“Datumsteil” in das XML-Dokument serialisiert.<br />
Entsprechendes geschieht für einen Dynamics AX Time Datentyp.
</p>
        <p>
Mapping eines C# Datetime Datentyps in einen Dynamics AX Date Datentyp (generierter
Code der Proxyklasse):
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>[System.Xml.Serialization.XmlElementAttribute(DataType=<span class="str">"date"</span>,
IsNullable=<span class="kwrd">true</span>, Order=54)]</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">public</span> System.Nullable&lt;System.DateTime&gt;
MyDateField {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> get {</pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">this</span>.myDateFieldField;</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> }</pre>
          <pre>
            <span class="lnum"> 6: </span> set {</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <span class="kwrd">this</span>.myDateFieldField
= <span class="kwrd">value</span>;</pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">this</span>.RaisePropertyChanged(<span class="str">"MyDateField"</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> }</pre>
          <pre>
            <span class="lnum"> 10: </span>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Mapping eines C# Datetime Datentyps in einen Dynamics AX Time Datentyp (generierter
Code der Proxyklasse):
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>[System.Xml.Serialization.XmlElementAttribute(DataType=<span class="str">"time"</span>,
IsNullable=<span class="kwrd">true</span>, Order=56)]</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">public</span> System.Nullable&lt;System.DateTime&gt;
MyTimeField {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> get {</pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">return</span>
            <span class="kwrd">this</span>.myTimeFieldField;</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> }</pre>
          <pre>
            <span class="lnum"> 6: </span> set {</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <span class="kwrd">this</span>.myTimeFieldField
= <span class="kwrd">value</span>;</pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">this</span>.RaisePropertyChanged(<span class="str">"MyTimeField"</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> }</pre>
          <pre>
            <span class="lnum"> 10: </span>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>[System.CodeDom.Compiler.GeneratedCodeAttribute(<span class="str">"System.Xml"</span>, <span class="str">"2.0.50727.4016"</span>)]</pre>
          <pre>
            <span class="lnum"> 2: </span>[System.SerializableAttribute()]</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>[System.Diagnostics.DebuggerStepThroughAttribute()]</pre>
          <pre>
            <span class="lnum"> 4: </span>[System.ComponentModel.DesignerCategoryAttribute(<span class="str">"code"</span>)]</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span>[System.Xml.Serialization.XmlTypeAttribute(Namespace=<span class="str">"http://schemas.microsoft.com/dynamics/2008/01/documents/Customer"</span>)]</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">partial</span>
            <span class="kwrd">class</span> AxdType_DateTime
: <span class="kwrd">object</span>, System.ComponentModel.INotifyPropertyChanged {</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">private</span> System.DateTime
localDateTimeField;</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">bool</span> localDateTimeFieldSpecified;</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span>
          </pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="kwrd">private</span> AxdEnum_Timezone
timezoneField;</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span>
          </pre>
          <pre>
            <span class="lnum"> 14: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">bool</span> timezoneFieldSpecified;</pre>
          <pre class="alt">
            <span class="lnum"> 15: </span>
          </pre>
          <pre>
            <span class="lnum"> 16: </span>
            <span class="kwrd">private</span> System.DateTime
valueField;</pre>
          <pre class="alt">
            <span class="lnum"> 17: </span>
          </pre>
          <pre>
            <span class="lnum"> 18: </span> [System.Xml.Serialization.XmlAttributeAttribute()]</pre>
          <pre class="alt">
            <span class="lnum"> 19: </span>
            <span class="kwrd">public</span> System.DateTime
localDateTime ... </pre>
          <pre>
            <span class="lnum"> 20: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 21: </span> [System.Xml.Serialization.XmlIgnoreAttribute()]</pre>
          <pre>
            <span class="lnum"> 22: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">bool</span> localDateTimeSpecified... </pre>
          <pre class="alt">
            <span class="lnum"> 23: </span>
          </pre>
          <pre>
            <span class="lnum"> 24: </span> [System.Xml.Serialization.XmlAttributeAttribute()]</pre>
          <pre class="alt">
            <span class="lnum"> 25: </span>
            <span class="kwrd">public</span> AxdEnum_Timezone
timezone...</pre>
          <pre>
            <span class="lnum"> 26: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 27: </span> [System.Xml.Serialization.XmlIgnoreAttribute()]</pre>
          <pre>
            <span class="lnum"> 28: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">bool</span> timezoneSpecified...</pre>
          <pre class="alt">
            <span class="lnum"> 29: </span>
          </pre>
          <pre>
            <span class="lnum"> 30: </span> [System.Xml.Serialization.XmlTextAttribute()]</pre>
          <pre class="alt">
            <span class="lnum"> 31: </span>
            <span class="kwrd">public</span> System.DateTime
Value {</pre>
          <pre>
            <span class="lnum"> 32: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 33: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">event</span> System.ComponentModel.PropertyChangedEventHandler
PropertyChanged;</pre>
          <pre>
            <span class="lnum"> 34: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 35: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">void</span> RaisePropertyChanged(<span class="kwrd">string</span> propertyName)...</pre>
          <pre>
            <span class="lnum"> 36: </span>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Dieses Verhalten ist nicht nur mit C# zu beobachten. Auch JAVA oder andere Programmiersprachen
verhalten sich ähnlich und muss entsprechend berücksichtigt werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=0af37380-886b-44e0-a6ec-ad04fc527ef8" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX AIF Webservices &amp;ndash; Date, Time und Datetime Datentypen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,0af37380-886b-44e0-a6ec-ad04fc527ef8.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,0af37380-886b-44e0-a6ec-ad04fc527ef8.aspx</link>
      <pubDate>Fri, 11 Jun 2010 19:33:13 GMT</pubDate>
      <description>&lt;p&gt;
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.&lt;br&gt;
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).
&lt;/p&gt;
&lt;p&gt;
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.&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Allerdings kann auf Seiten der Anwendung, welche über das Application Integration
Framework (AIF) angebunden werden soll, ein wenig “Verwirrung” entstehen.&lt;br&gt;
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.&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Ein gutes Beispiel hierfür sind die Dynamics AX Datentypen “Date”, “Time” und “DateTime”
(inklusive aller von diesen Basisdatentypen abgeleiteten EDT’s).
&lt;/p&gt;
&lt;p&gt;
Ohne genauere Betrachtung liegt die Annahme nahe, dass ein DateTime Datentyp von Dynamics
AX in einen DateTime Datentyp von z.B. C# “gemappt” wird.&lt;br&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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.&lt;br&gt;
Diese Datentypen werden jeweils als C# DateTime Datentypen gemappt.
&lt;/p&gt;
&lt;p&gt;
Das Mapping der Datentypen geschieht wie folgt:
&lt;/p&gt;
&lt;table border=0 cellspacing=0 cellpadding=0 width=600&gt;
&lt;tbody&gt;
&lt;tr height=20&gt;
&lt;td width=198 align=middle&gt;
&lt;p align=center&gt;
&lt;strong&gt;Dynamics AX&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=198 align=middle&gt;
&lt;p align=center&gt;
&lt;strong&gt;XSD Schema&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=202 align=middle&gt;
&lt;p align=center&gt;
.&lt;strong&gt;NET (C#)&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr height=20&gt;
&lt;td width=198 align=middle&gt;
&lt;p align=center&gt;
Date
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=198 align=middle&gt;
xs:date&lt;/td&gt;
&lt;td width=202 align=middle&gt;
System.DateTime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr height=20&gt;
&lt;td width=198 align=middle&gt;
&lt;p align=center&gt;
Time
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=198 align=middle&gt;
xs:time&lt;/td&gt;
&lt;td width=202 align=middle&gt;
System.DateTime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr height=20&gt;
&lt;td width=198 align=middle&gt;
&lt;p align=center&gt;
DateTime
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=199 align=middle&gt;
xs:dateTime&lt;/td&gt;
&lt;td width=203 align=middle&gt;
new class&lt;br&gt;
i.e. “AxdType_DateTime”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;br&gt;
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.&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.&lt;br&gt;
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).
&lt;/p&gt;
&lt;p&gt;
Durch die Angabe eines Serialisierungs-Attributes wird bestimmt, welcher “Teil” des
DateTime Datentyps verwendet wird.&lt;br&gt;
Für ein Feld, welches in einen Dynamics AX Date Datentyp gemappt wird, wird nur der
“Datumsteil” in das XML-Dokument serialisiert.&lt;br&gt;
Entsprechendes geschieht für einen Dynamics AX Time Datentyp.
&lt;/p&gt;
&lt;p&gt;
Mapping eines C# Datetime Datentyps in einen Dynamics AX Date Datentyp (generierter
Code der Proxyklasse):
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=lnum&gt; 1: &lt;/span&gt;[System.Xml.Serialization.XmlElementAttribute(DataType=&lt;span class=str&gt;"date"&lt;/span&gt;,
IsNullable=&lt;span class=kwrd&gt;true&lt;/span&gt;, Order=54)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 2: &lt;/span&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; System.Nullable&amp;lt;System.DateTime&amp;gt;
MyDateField {&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 3: &lt;/span&gt; get {&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 4: &lt;/span&gt; &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.myDateFieldField;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 5: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 6: &lt;/span&gt; set {&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 7: &lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.myDateFieldField
= &lt;span class=kwrd&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 8: &lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.RaisePropertyChanged(&lt;span class=str&gt;"MyDateField"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 9: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 10: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Mapping eines C# Datetime Datentyps in einen Dynamics AX Time Datentyp (generierter
Code der Proxyklasse):
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=lnum&gt; 1: &lt;/span&gt;[System.Xml.Serialization.XmlElementAttribute(DataType=&lt;span class=str&gt;"time"&lt;/span&gt;,
IsNullable=&lt;span class=kwrd&gt;true&lt;/span&gt;, Order=56)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 2: &lt;/span&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; System.Nullable&amp;lt;System.DateTime&amp;gt;
MyTimeField {&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 3: &lt;/span&gt; get {&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 4: &lt;/span&gt; &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.myTimeFieldField;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 5: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 6: &lt;/span&gt; set {&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 7: &lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.myTimeFieldField
= &lt;span class=kwrd&gt;value&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 8: &lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.RaisePropertyChanged(&lt;span class=str&gt;"MyTimeField"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 9: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 10: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=lnum&gt; 1: &lt;/span&gt;[System.CodeDom.Compiler.GeneratedCodeAttribute(&lt;span class=str&gt;"System.Xml"&lt;/span&gt;, &lt;span class=str&gt;"2.0.50727.4016"&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 2: &lt;/span&gt;[System.SerializableAttribute()]&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 3: &lt;/span&gt;[System.Diagnostics.DebuggerStepThroughAttribute()]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 4: &lt;/span&gt;[System.ComponentModel.DesignerCategoryAttribute(&lt;span class=str&gt;"code"&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 5: &lt;/span&gt;[System.Xml.Serialization.XmlTypeAttribute(Namespace=&lt;span class=str&gt;"http://schemas.microsoft.com/dynamics/2008/01/documents/Customer"&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 6: &lt;/span&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;partial&lt;/span&gt; &lt;span class=kwrd&gt;class&lt;/span&gt; AxdType_DateTime
: &lt;span class=kwrd&gt;object&lt;/span&gt;, System.ComponentModel.INotifyPropertyChanged {&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 7: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 8: &lt;/span&gt; &lt;span class=kwrd&gt;private&lt;/span&gt; System.DateTime
localDateTimeField;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 9: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 10: &lt;/span&gt; &lt;span class=kwrd&gt;private&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; localDateTimeFieldSpecified;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 11: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 12: &lt;/span&gt; &lt;span class=kwrd&gt;private&lt;/span&gt; AxdEnum_Timezone
timezoneField;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 13: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 14: &lt;/span&gt; &lt;span class=kwrd&gt;private&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; timezoneFieldSpecified;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 15: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 16: &lt;/span&gt; &lt;span class=kwrd&gt;private&lt;/span&gt; System.DateTime
valueField;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 17: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 18: &lt;/span&gt; [System.Xml.Serialization.XmlAttributeAttribute()]&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 19: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; System.DateTime
localDateTime ... &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 20: &lt;/span&gt; &lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 21: &lt;/span&gt; [System.Xml.Serialization.XmlIgnoreAttribute()]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 22: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; localDateTimeSpecified... &lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 23: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 24: &lt;/span&gt; [System.Xml.Serialization.XmlAttributeAttribute()]&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 25: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; AxdEnum_Timezone
timezone...&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 26: &lt;/span&gt; &lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 27: &lt;/span&gt; [System.Xml.Serialization.XmlIgnoreAttribute()]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 28: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; timezoneSpecified...&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 29: &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 30: &lt;/span&gt; [System.Xml.Serialization.XmlTextAttribute()]&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 31: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; System.DateTime
Value {&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 32: &lt;/span&gt; &lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 33: &lt;/span&gt; &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;event&lt;/span&gt; System.ComponentModel.PropertyChangedEventHandler
PropertyChanged;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 34: &lt;/span&gt; &lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=lnum&gt; 35: &lt;/span&gt; &lt;span class=kwrd&gt;protected&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; RaisePropertyChanged(&lt;span class=kwrd&gt;string&lt;/span&gt; propertyName)...&lt;/pre&gt;
&lt;pre&gt;&lt;span class=lnum&gt; 36: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Dieses Verhalten ist nicht nur mit C# zu beobachten. Auch JAVA oder andere Programmiersprachen
verhalten sich ähnlich und muss entsprechend berücksichtigt werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=0af37380-886b-44e0-a6ec-ad04fc527ef8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,0af37380-886b-44e0-a6ec-ad04fc527ef8.aspx</comments>
      <category>.NET;.NET/Compact Framework;Allgemein;Dynamics Ax;Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=50123879-0bcb-46ed-8323-00510cb4dfa9</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,50123879-0bcb-46ed-8323-00510cb4dfa9.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,50123879-0bcb-46ed-8323-00510cb4dfa9.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=50123879-0bcb-46ed-8323-00510cb4dfa9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Macros werden innerhalb von Dynamics AX z.B. für die Best-Practice konforme Verwendung
von festen Zeichenfolgen innerhalb des X++ Quellcodes verwendet.<br />
An vielen Stellen im System finden sich Quellcodezeilen wie diese:
</p>
        <pre class="csharpcode">#define.MySimpleMacro(<span class="str">'The string value'</span>)</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Dies ist die am meist verwendete Art der Macrodefinition innerhalb von Dynamics AX.<br />
So weit, so gut.
</p>
        <p>
Es gibt allerdings Konstellationen von “Werten”, welche bei dieser Art der Macrodefinition
zu einer Fehlermeldung beim speichern führen.<br />
Es bei dieser Art der Macrodefinition z.B. nicht möglich, eine schließende Klammer
als Macrowert zu definieren.<br />
Dies ist auch so im <a href="http://msdn.microsoft.com/en-us/library/cc197110.aspx">MSDN </a>dokumentiert: <a title="http://msdn.microsoft.com/en-us/library/cc197110.aspx" href="http://msdn.microsoft.com/en-us/library/cc197110.aspx">http://msdn.microsoft.com/en-us/library/cc197110.aspx</a></p>
        <p>
Gerade bei der Verwendung von Regular Expressions (Regex) kann dies zu regelmäßiger
Verwirrung führen, da man gerne die weiteren Macrodefinitions-Möglichkeiten vergisst
und oder diese nicht so präsent sind.
</p>
        <p>
Die Syntax 
</p>
        <pre class="csharpcode">#define.Macroname(Wert)</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
sollte eigentlich nur verwendet werden um (einfache) Konstanten innerhalb des Quellcodes
zu definieren.<br />
Für alle anderen Fälle und wenn ein Macro mit mehr als einer Zeile benötigt wird,
sollte folgende Syntax zu Definition eines Macros verwendet werden:
</p>
        <pre class="csharpcode">#localmacro.AnExample

<span class="rem">// Some statements
or text</span> #endmacro</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Die Verwendung von #localmacro anstelle eines "(einfachen) #define erlaubt es nun
auch mit schließenden Klammern als Macrowert zu arbeiten oder sogar ganze SQL oder
X++ Codeblöcke zu verwenden.<br />
Eine genauere Beschreibung von Dynamics AX Macros (deren Möglichkeiten und Einsatzgebiete)
ist im MSDN dokumentiert:
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/cc197107.aspx">Macros in X++</a>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=50123879-0bcb-46ed-8323-00510cb4dfa9" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX &amp;ndash; Macros und schlie&amp;szlig;ende Klammern</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,50123879-0bcb-46ed-8323-00510cb4dfa9.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,50123879-0bcb-46ed-8323-00510cb4dfa9.aspx</link>
      <pubDate>Fri, 04 Jun 2010 17:10:52 GMT</pubDate>
      <description>&lt;p&gt;
Macros werden innerhalb von Dynamics AX z.B. für die Best-Practice konforme Verwendung
von festen Zeichenfolgen innerhalb des X++ Quellcodes verwendet.&lt;br&gt;
An vielen Stellen im System finden sich Quellcodezeilen wie diese:
&lt;/p&gt;
&lt;pre class=csharpcode&gt;#define.MySimpleMacro(&lt;span class=str&gt;'The string value'&lt;/span&gt;)&lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Dies ist die am meist verwendete Art der Macrodefinition innerhalb von Dynamics AX.&lt;br&gt;
So weit, so gut.
&lt;/p&gt;
&lt;p&gt;
Es gibt allerdings Konstellationen von “Werten”, welche bei dieser Art der Macrodefinition
zu einer Fehlermeldung beim speichern führen.&lt;br&gt;
Es bei dieser Art der Macrodefinition z.B. nicht möglich, eine schließende Klammer
als Macrowert zu definieren.&lt;br&gt;
Dies ist auch so im &lt;a href="http://msdn.microsoft.com/en-us/library/cc197110.aspx"&gt;MSDN &lt;/a&gt;dokumentiert: &lt;a title=http://msdn.microsoft.com/en-us/library/cc197110.aspx href="http://msdn.microsoft.com/en-us/library/cc197110.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc197110.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Gerade bei der Verwendung von Regular Expressions (Regex) kann dies zu regelmäßiger
Verwirrung führen, da man gerne die weiteren Macrodefinitions-Möglichkeiten vergisst
und oder diese nicht so präsent sind.
&lt;/p&gt;
&lt;p&gt;
Die Syntax 
&lt;/p&gt;
&lt;pre class=csharpcode&gt;#define.Macroname(Wert)&lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
sollte eigentlich nur verwendet werden um (einfache) Konstanten innerhalb des Quellcodes
zu definieren.&lt;br&gt;
Für alle anderen Fälle und wenn ein Macro mit mehr als einer Zeile benötigt wird,
sollte folgende Syntax zu Definition eines Macros verwendet werden:
&lt;/p&gt;
&lt;pre class=csharpcode&gt;#localmacro.AnExample

&lt;span class=rem&gt;// Some statements
or text&lt;/span&gt; #endmacro&lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Die Verwendung von #localmacro anstelle eines "(einfachen) #define erlaubt es nun
auch mit schließenden Klammern als Macrowert zu arbeiten oder sogar ganze SQL oder
X++ Codeblöcke zu verwenden.&lt;br&gt;
Eine genauere Beschreibung von Dynamics AX Macros (deren Möglichkeiten und Einsatzgebiete)
ist im MSDN dokumentiert:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/cc197107.aspx"&gt;Macros in X++&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=50123879-0bcb-46ed-8323-00510cb4dfa9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,50123879-0bcb-46ed-8323-00510cb4dfa9.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=cb09a7f7-edac-451d-8abe-26145ed8cb05</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,cb09a7f7-edac-451d-8abe-26145ed8cb05.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,cb09a7f7-edac-451d-8abe-26145ed8cb05.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=cb09a7f7-edac-451d-8abe-26145ed8cb05</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Beim Entwickeln und/oder Testen von AIF-Service, welche als Webservice bereit gestellt
werden, entstehen oftmals (mindestens) 2 Fragestellungen.
</p>
        <ol>
          <li>
Wie kann die Nachricht betrachtet werden, welche zwischen den System über den Webservice
ausgetauscht wird? 
</li>
          <li>
Wie lässt sich der Webservice-Aufruf debuggen?</li>
        </ol>
        <p>
Leider werden diese Fragen bei einer Suche im Internet oft mit “Geht nicht” beantwortet.<br />
Dies ist so allerdings nicht richtig.
</p>
        <p>
Es ist z.B. möglich, für alle Webserviceaufrufe eine Tracing-File zu erzeugen, welches
u.A. auch die Nachricht protokolliert, die von oder zu Dynamics AX geschickt wurde.<br />
Um das Tracing zu aktivieren müssen nur entsprechende Einstellungen in der web.config
des Webservices vorgenommen werden.
</p>
        <p>
Wie dies im Detail funktioniert beschreibt dieses kleine <a href="http://msdn.microsoft.com/en-us/library/cc967372.aspx">How-To</a> des
Microsoft Dynamics Developer Centers im MSDN.<br /><a title="http://msdn.microsoft.com/en-us/library/cc967372.aspx" href="http://msdn.microsoft.com/en-us/library/cc967372.aspx">http://msdn.microsoft.com/en-us/library/cc967372.aspx</a></p>
        <p>
Es ist ebenfalls möglich, die Webserviceaufrufe zu debuggen.
</p>
        <p>
Allerdings müssten hierfür einige Schritte beachtet werden, damit das Debuggen von
Webserviceaufrufen auch für X++ Code funktioniert.<br />
Eine detaillierte Anleitung hierzu ist am Ende des Whitepapers “<a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2">Tips
for Creating Services in Microsoft Dynamics AX 2009</a>” zu finden.<br /><a title="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2" href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2">http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2</a></p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=cb09a7f7-edac-451d-8abe-26145ed8cb05" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX AIF Webservices &amp;ndash; Entwickeln und Testen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,cb09a7f7-edac-451d-8abe-26145ed8cb05.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,cb09a7f7-edac-451d-8abe-26145ed8cb05.aspx</link>
      <pubDate>Sat, 27 Feb 2010 15:21:20 GMT</pubDate>
      <description>&lt;p&gt;
Beim Entwickeln und/oder Testen von AIF-Service, welche als Webservice bereit gestellt
werden, entstehen oftmals (mindestens) 2 Fragestellungen.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Wie kann die Nachricht betrachtet werden, welche zwischen den System über den Webservice
ausgetauscht wird? 
&lt;li&gt;
Wie lässt sich der Webservice-Aufruf debuggen?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Leider werden diese Fragen bei einer Suche im Internet oft mit “Geht nicht” beantwortet.&lt;br&gt;
Dies ist so allerdings nicht richtig.
&lt;/p&gt;
&lt;p&gt;
Es ist z.B. möglich, für alle Webserviceaufrufe eine Tracing-File zu erzeugen, welches
u.A. auch die Nachricht protokolliert, die von oder zu Dynamics AX geschickt wurde.&lt;br&gt;
Um das Tracing zu aktivieren müssen nur entsprechende Einstellungen in der web.config
des Webservices vorgenommen werden.
&lt;/p&gt;
&lt;p&gt;
Wie dies im Detail funktioniert beschreibt dieses kleine &lt;a href="http://msdn.microsoft.com/en-us/library/cc967372.aspx"&gt;How-To&lt;/a&gt; des
Microsoft Dynamics Developer Centers im MSDN.&lt;br&gt;
&lt;a title=http://msdn.microsoft.com/en-us/library/cc967372.aspx href="http://msdn.microsoft.com/en-us/library/cc967372.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc967372.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Es ist ebenfalls möglich, die Webserviceaufrufe zu debuggen.
&lt;/p&gt;
&lt;p&gt;
Allerdings müssten hierfür einige Schritte beachtet werden, damit das Debuggen von
Webserviceaufrufen auch für X++ Code funktioniert.&lt;br&gt;
Eine detaillierte Anleitung hierzu ist am Ende des Whitepapers “&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2"&gt;Tips
for Creating Services in Microsoft Dynamics AX 2009&lt;/a&gt;” zu finden.&lt;br&gt;
&lt;a title=http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2 href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=90388b14-fb8c-4633-a255-28ff7146c5b2&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=cb09a7f7-edac-451d-8abe-26145ed8cb05" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,cb09a7f7-edac-451d-8abe-26145ed8cb05.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=cea0552b-b96e-48ba-884b-c82bd2538b07</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,cea0552b-b96e-48ba-884b-c82bd2538b07.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,cea0552b-b96e-48ba-884b-c82bd2538b07.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=cea0552b-b96e-48ba-884b-c82bd2538b07</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Um Datensätze in Microsoft Dynamics AX, welche z.B. auf einer Maske angezeigt werden,
entsprechend seiner Anforderungen einzuschränken (zu filtern) muss die Query (Abfrageobjekt)
durch Erstellung von Ranges (Abfrageeinschränkungsobjekt) entsprechend “manipuliert”
werden.<br />
Hierfür wird z.B. die Query einer Maskendatenquell (DataSource) verwendet und für
diese eine neue Range definiert:
</p>
        <p>
Beispiel:
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> init()</pre>
          <pre>{</pre>
          <pre class="alt">    QueryBuildRange     range;</pre>
          <pre>    ;</pre>
          <pre class="alt">    super();</pre>
          <pre>
          </pre>
          <pre class="alt">    range = CustTable_ds.query().dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, AccountNum));</pre>
          <pre>    range.<span class="kwrd">value</span>(<span class="str">"1101"</span>);</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Im Dynamics AX Standard kann ähnlicher X++ Quelltext in vielen Masken gefunden werden,
da dies der “Standard-Weg” zum Einschränken von Datensatzabfragen bei Masken oder
auch Reports ist.<br />
Ebenso wird dieses Vorgehen auch in den Schulungsunterlagen, in der Entwicklerhilfe
und anderen Stellen beschrieben.
</p>
        <p>
Leider hat dieses Vorgehen eine kleine aber teilweise sehr störende Beschränkung.<br />
Über diesen Weg ist es nicht möglich, alle Abfrageeinschränkungen welche durch X++
Quellcode “gesetzt” wurden und Einschränkungen, welche durch einen Benutzer mittels
der Standardfilterfunktion von Dynamics AX definiert wurden, zu berücksichtigen. Beim
einer Datenaktualisierung (Aufruf von DataSource.executeQuery) gehen die von einem
Benutzer definierten Abfrageeinschränkungen verloren. 
</p>
        <p>
Dies ist darin begründet, dass es nicht nur ein DataSoucre.query-Objekt, sondern auch
ein DataSource.queryrun().query-Objekt gibt.<br />
Diese beiden “Query-Objekte” sind jeweils unterschiedliche Objekte, bzw. Objektinstanzen.
</p>
        <p>
Das DataSource.query-Objekt ist das “Basisabfrageobjekt”, welches durch einen Benutzer,
mittels der Filterfunktionalität des Standards, nicht verändert werden kann (nur durch
X++ Code).<br />
Alle durch den Benutzer vorgenommenen Änderungen an der “Basisabfrage” werden in dem
Query-Objekt von DataSource-queryrun() “gespeichert”.<br />
Dies kann unter Anderem durch Betrachtung des SQL-Statements, welches durch ein Query-Objekt
bereit gestellt wird nachgewiesen werden.
</p>
        <p>
Beispiel:
</p>
        <p>
Aufruf einer Maske mit einer durch X++ Code modifizierten Abfrage (Query).<br />
Anmerkung: Beim Aufruf der Maske wird in der “Init-Methode” eine Range (CustGroup
= “10”) gesetzt.
</p>
        <pre class="csharpcode">range = CustTable_ds.query().dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, CustGroup));
range.<span class="kwrd">value</span>(<span class="str">"10"</span>);</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_1.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="QueryVSQueryRunQuery_1" border="0" alt="QueryVSQueryRunQuery_1" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_1_thumb.jpg" width="244" height="110" />
          </a>
        </p>
        <p>
Durch den Benutzer wird nun mittels der Dynamics AX Standard-Filterfunktion die Abfrage
bzw. deren Einschränkung(en) angepasst/verändert.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_2.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="QueryVSQueryRunQuery_2" border="0" alt="QueryVSQueryRunQuery_2" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_2_thumb.jpg" width="244" height="111" />
          </a>
        </p>
        <p>
Hierdurch ist zu beobachten, das sich zwar das SQL-Statement des DataSource.queryrun().query-Objekts,
aber nicht das SQL-Statement des DataSoucre.query-Objekts ändert.<br />
Da bei einem Aufruf von DataSource.executeQuery allerdings immer das DataSource.query-Objekt
verwendet wird, gehen die durch den Benutzer gewählten Abfrageeinschränkungen verloren.
</p>
        <p>
Wie ist es nun aber möglich, die von einem Benutzer gewählten Abfrageeinschränkungen/Filtereinstellung
doch zu berücksichtigen?
</p>
        <p>
Da alle Abfrageeinschränkungen, welche von einem Benutzer gewählt wurden, in dem Query-Objekt
von DataSource.queryrun() “gespeichert” werden und somit auch im X++ Code zur Verfügung
stehen ist dies recht einfach.<br />
Es muss einfach das Query-Objekt von DataSource.queryrun() genommen werden, um die
gewünschten Ranges ergenzt werden und schließlich dass Query-Objekt der DataSource
überschrieben werden.
</p>
        <p>
Beispiel:
</p>
        <p>
Basis ist eine einfach Maske, welche alle Kundendatensätze anzeigt.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_1.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="ShowQuery_1" border="0" alt="ShowQuery_1" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_1_thumb.jpg" width="244" height="74" />
          </a>
        </p>
        <p>
Dieser Maske/Abfrage wird nun durch die Standard-Filterfunktion (Benutzerfilter) eine
neue Abfrageeinschränkung hinzugefügt (Kundennummer = 1101 und 2001).
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_2.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="ShowQuery_2" border="0" alt="ShowQuery_2" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_2_thumb.jpg" width="244" height="68" />
          </a>
        </p>
        <p>
        </p>
        <p>
Wie zuvor beschrieben, wird nun eine neue Abfrageeinschränkung mit X++ Code auf dem
Query-Objekt von DataSource.queryrun “gesetzt” und das Query-Objekt der DataSource
mit diesem überschrieben. 
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span> clicked()</pre>
          <pre>{</pre>
          <pre class="alt">    Query               query;</pre>
          <pre>    QueryBuildRange     range;</pre>
          <pre class="alt">    ;</pre>
          <pre>    super();</pre>
          <pre class="alt"> </pre>
          <pre>    query = CustTable_ds.queryRun().query();</pre>
          <pre class="alt"> </pre>
          <pre>    range = query.dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, CustGroup));</pre>
          <pre class="alt">    range.<span class="kwrd">value</span>(<span class="str">"10"</span>);</pre>
          <pre> </pre>
          <pre class="alt">    CustTable_ds.query(query);</pre>
          <pre> </pre>
          <pre class="alt">    CustTable_ds.executeQuery();</pre>
          <pre>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Dies hat zur Folge, dass die durch den Benutzer gewählten Abfrageeinschränkungen,
wie zu sehen, weiterhin berücksichtigt werden.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/AddRange_2.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="AddRange_2" border="0" alt="AddRange_2" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/AddRange_2_thumb.jpg" width="244" height="69" />
          </a>
        </p>
        <p>
Alternativ zur Verwendung der Abfrageeinschränkung (Range) “direkt” über das Query-Objekt
kann auch mit einem oder mehreren Filtern gearbeitet werden.<br />
Diese unterliegen im Gegensatz zu den Query-Objekt aber einigen Einschränkungen, sodass
diese nicht in jeder Situation verwendet werden können.
</p>
        <p>
Der folgende X++ Code zeigt, wie ein Filter gesetzt werden kann.
</p>
        <p>
        </p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span> clicked()</pre>
          <pre>{</pre>
          <pre class="alt">    Query               query;</pre>
          <pre>    QueryBuildRange     range;</pre>
          <pre class="alt">    ;</pre>
          <pre>    super();</pre>
          <pre class="alt"> </pre>
          <pre>    CustTable_ds.filter(fieldnum(CustTable, CustGroup), <span class="str">"10"</span>);</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Wird eine Abfrage auf diese Art und Weise eingeschränkt, ist der Aufruf von DataSource.executeQuery()
unnötig, da die Datenaktualisierung bereits im Hintergrund durch den Filter-Aufruf
durchgeführt wird.<br />
Filter einer DataSource funktionieren vom Prinzip her wie die Standardfilter, welche
durch einen Benutzer in Dynamics AX gesetzt werden können.<br />
Dies hat zur Folge, dass sich diese ebenfalls nur auf das Query-Objekt von DataSource.queryrun()
auswirken und somit DataSource.query nicht beeinflussen.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/Add_Filter.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Add_Filter" border="0" alt="Add_Filter" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/Add_Filter_thumb.jpg" width="244" height="68" />
          </a>
        </p>
        <p>
Mit der Methode DataSource.removeFilter können die gesetzten Filter wieder gelöscht
werden.<br />
Leider werden hierdurch alle gesetzten Filter gelöscht, sodass nach diesem Aufruf
unter Umständen einige bereits gesetzte Filter erneut gesetzt werden müssen, um das
gewünschte Abfrageergebnis zu erhalten.
</p>
        <p>
Welche der gezeigten Methoden, zum Einschränken von Abfragen, aber nun der beste oder
bessere Weg ist, muss von Fall zu Fall entschieden werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=cea0552b-b96e-48ba-884b-c82bd2538b07" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX &amp;ndash; Query-Ranges und Filtereinstellungen des Benutzers</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,cea0552b-b96e-48ba-884b-c82bd2538b07.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,cea0552b-b96e-48ba-884b-c82bd2538b07.aspx</link>
      <pubDate>Wed, 03 Feb 2010 19:49:23 GMT</pubDate>
      <description>&lt;p&gt;
Um Datensätze in Microsoft Dynamics AX, welche z.B. auf einer Maske angezeigt werden,
entsprechend seiner Anforderungen einzuschränken (zu filtern) muss die Query (Abfrageobjekt)
durch Erstellung von Ranges (Abfrageeinschränkungsobjekt) entsprechend “manipuliert”
werden.&lt;br&gt;
Hierfür wird z.B. die Query einer Maskendatenquell (DataSource) verwendet und für
diese eine neue Range definiert:
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; init()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    QueryBuildRange     range;&lt;/pre&gt;
&lt;pre&gt;    ;&lt;/pre&gt;
&lt;pre class=alt&gt;    super();&lt;/pre&gt;
&lt;pre&gt;    &lt;/pre&gt;
&lt;pre class=alt&gt;    range = CustTable_ds.query().dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, AccountNum));&lt;/pre&gt;
&lt;pre&gt;    range.&lt;span class=kwrd&gt;value&lt;/span&gt;(&lt;span class=str&gt;"1101"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Im Dynamics AX Standard kann ähnlicher X++ Quelltext in vielen Masken gefunden werden,
da dies der “Standard-Weg” zum Einschränken von Datensatzabfragen bei Masken oder
auch Reports ist.&lt;br&gt;
Ebenso wird dieses Vorgehen auch in den Schulungsunterlagen, in der Entwicklerhilfe
und anderen Stellen beschrieben.
&lt;/p&gt;
&lt;p&gt;
Leider hat dieses Vorgehen eine kleine aber teilweise sehr störende Beschränkung.&lt;br&gt;
Über diesen Weg ist es nicht möglich, alle Abfrageeinschränkungen welche durch X++
Quellcode “gesetzt” wurden und Einschränkungen, welche durch einen Benutzer mittels
der Standardfilterfunktion von Dynamics AX definiert wurden, zu berücksichtigen. Beim
einer Datenaktualisierung (Aufruf von DataSource.executeQuery) gehen die von einem
Benutzer definierten Abfrageeinschränkungen verloren. 
&lt;/p&gt;
&lt;p&gt;
Dies ist darin begründet, dass es nicht nur ein DataSoucre.query-Objekt, sondern auch
ein DataSource.queryrun().query-Objekt gibt.&lt;br&gt;
Diese beiden “Query-Objekte” sind jeweils unterschiedliche Objekte, bzw. Objektinstanzen.
&lt;/p&gt;
&lt;p&gt;
Das DataSource.query-Objekt ist das “Basisabfrageobjekt”, welches durch einen Benutzer,
mittels der Filterfunktionalität des Standards, nicht verändert werden kann (nur durch
X++ Code).&lt;br&gt;
Alle durch den Benutzer vorgenommenen Änderungen an der “Basisabfrage” werden in dem
Query-Objekt von DataSource-queryrun() “gespeichert”.&lt;br&gt;
Dies kann unter Anderem durch Betrachtung des SQL-Statements, welches durch ein Query-Objekt
bereit gestellt wird nachgewiesen werden.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
Aufruf einer Maske mit einer durch X++ Code modifizierten Abfrage (Query).&lt;br&gt;
Anmerkung: Beim Aufruf der Maske wird in der “Init-Methode” eine Range (CustGroup
= “10”) gesetzt.
&lt;/p&gt;
&lt;pre class=csharpcode&gt;range = CustTable_ds.query().dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, CustGroup));
range.&lt;span class=kwrd&gt;value&lt;/span&gt;(&lt;span class=str&gt;"10"&lt;/span&gt;);&lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_1.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=QueryVSQueryRunQuery_1 border=0 alt=QueryVSQueryRunQuery_1 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_1_thumb.jpg" width=244 height=110&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Durch den Benutzer wird nun mittels der Dynamics AX Standard-Filterfunktion die Abfrage
bzw. deren Einschränkung(en) angepasst/verändert.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=QueryVSQueryRunQuery_2 border=0 alt=QueryVSQueryRunQuery_2 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/QueryVSQueryRunQuery_2_thumb.jpg" width=244 height=111&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Hierdurch ist zu beobachten, das sich zwar das SQL-Statement des DataSource.queryrun().query-Objekts,
aber nicht das SQL-Statement des DataSoucre.query-Objekts ändert.&lt;br&gt;
Da bei einem Aufruf von DataSource.executeQuery allerdings immer das DataSource.query-Objekt
verwendet wird, gehen die durch den Benutzer gewählten Abfrageeinschränkungen verloren.
&lt;/p&gt;
&lt;p&gt;
Wie ist es nun aber möglich, die von einem Benutzer gewählten Abfrageeinschränkungen/Filtereinstellung
doch zu berücksichtigen?
&lt;/p&gt;
&lt;p&gt;
Da alle Abfrageeinschränkungen, welche von einem Benutzer gewählt wurden, in dem Query-Objekt
von DataSource.queryrun() “gespeichert” werden und somit auch im X++ Code zur Verfügung
stehen ist dies recht einfach.&lt;br&gt;
Es muss einfach das Query-Objekt von DataSource.queryrun() genommen werden, um die
gewünschten Ranges ergenzt werden und schließlich dass Query-Objekt der DataSource
überschrieben werden.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
Basis ist eine einfach Maske, welche alle Kundendatensätze anzeigt.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_1.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ShowQuery_1 border=0 alt=ShowQuery_1 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_1_thumb.jpg" width=244 height=74&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Dieser Maske/Abfrage wird nun durch die Standard-Filterfunktion (Benutzerfilter) eine
neue Abfrageeinschränkung hinzugefügt (Kundennummer = 1101 und 2001).
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ShowQuery_2 border=0 alt=ShowQuery_2 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/ShowQuery_2_thumb.jpg" width=244 height=68&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Wie zuvor beschrieben, wird nun eine neue Abfrageeinschränkung mit X++ Code auf dem
Query-Objekt von DataSource.queryrun “gesetzt” und das Query-Objekt der DataSource
mit diesem überschrieben. 
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;void&lt;/span&gt; clicked()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    Query               query;&lt;/pre&gt;
&lt;pre&gt;    QueryBuildRange     range;&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    super();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    query = CustTable_ds.queryRun().query();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    range = query.dataSourceTable(tablenum(CustTable)).addRange(fieldnum(CustTable, CustGroup));&lt;/pre&gt;
&lt;pre class=alt&gt;    range.&lt;span class=kwrd&gt;value&lt;/span&gt;(&lt;span class=str&gt;"10"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    CustTable_ds.query(query);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    CustTable_ds.executeQuery();&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Dies hat zur Folge, dass die durch den Benutzer gewählten Abfrageeinschränkungen,
wie zu sehen, weiterhin berücksichtigt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/AddRange_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=AddRange_2 border=0 alt=AddRange_2 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/AddRange_2_thumb.jpg" width=244 height=69&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Alternativ zur Verwendung der Abfrageeinschränkung (Range) “direkt” über das Query-Objekt
kann auch mit einem oder mehreren Filtern gearbeitet werden.&lt;br&gt;
Diese unterliegen im Gegensatz zu den Query-Objekt aber einigen Einschränkungen, sodass
diese nicht in jeder Situation verwendet werden können.
&lt;/p&gt;
&lt;p&gt;
Der folgende X++ Code zeigt, wie ein Filter gesetzt werden kann.
&lt;/p&gt;
&lt;p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;void&lt;/span&gt; clicked()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    Query               query;&lt;/pre&gt;
&lt;pre&gt;    QueryBuildRange     range;&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    super();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    CustTable_ds.filter(fieldnum(CustTable, CustGroup), &lt;span class=str&gt;"10"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Wird eine Abfrage auf diese Art und Weise eingeschränkt, ist der Aufruf von DataSource.executeQuery()
unnötig, da die Datenaktualisierung bereits im Hintergrund durch den Filter-Aufruf
durchgeführt wird.&lt;br&gt;
Filter einer DataSource funktionieren vom Prinzip her wie die Standardfilter, welche
durch einen Benutzer in Dynamics AX gesetzt werden können.&lt;br&gt;
Dies hat zur Folge, dass sich diese ebenfalls nur auf das Query-Objekt von DataSource.queryrun()
auswirken und somit DataSource.query nicht beeinflussen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/Add_Filter.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Add_Filter border=0 alt=Add_Filter src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXQueryRangesundFiltereinstellun_10B74/Add_Filter_thumb.jpg" width=244 height=68&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Mit der Methode DataSource.removeFilter können die gesetzten Filter wieder gelöscht
werden.&lt;br&gt;
Leider werden hierdurch alle gesetzten Filter gelöscht, sodass nach diesem Aufruf
unter Umständen einige bereits gesetzte Filter erneut gesetzt werden müssen, um das
gewünschte Abfrageergebnis zu erhalten.
&lt;/p&gt;
&lt;p&gt;
Welche der gezeigten Methoden, zum Einschränken von Abfragen, aber nun der beste oder
bessere Weg ist, muss von Fall zu Fall entschieden werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=cea0552b-b96e-48ba-884b-c82bd2538b07" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,cea0552b-b96e-48ba-884b-c82bd2538b07.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=74734dd3-3ce8-4ad9-bc29-2503a0f866aa</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,74734dd3-3ce8-4ad9-bc29-2503a0f866aa.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,74734dd3-3ce8-4ad9-bc29-2503a0f866aa.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=74734dd3-3ce8-4ad9-bc29-2503a0f866aa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In Microsoft Dynamics AX wird das Args-Objekt dazu verwendet, Informationen z.B. an
eine aufzurufende Maske oder Klasse zu übergeben.
</p>
        <p>
Mittels des Args-Objektes ist es z.B. möglich, den auf einer Maske ausgewählten Datensatz
an die Aufzurufende (Unter)Maske zu übergeben, um mit diesem die Darstellung und/oder
Funktionen der Maske anzupassen.<br />
Oft wird dieses Vorgehen dazu verwendet, Abfragen (Queries) entsprechend einzugrenzen,
damit nur relevante Informationen verarbeitet werden.<br />
Eine beispielhafte Anforderung hierfür könnte sein, alle Aufträge des zuvor ausgewählten
Kunden in einer neuen Maske anzuzeigen.
</p>
        <p>
Manchmal ist aber notwendig, nicht nur den Aufrufer (oder den gewählten Datensatz),
sondern auch dessen Aufrufer zu kennen, um bestimme Funktionalitäten erstellen oder
implementieren zu können.<br />
Herbei kann es sein, dass der ausgewählter Datensatz über mehrere Aufrufebenen übergeben
werden muss und der direkte Aufrufer dennoch bekannt sein muss.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller_Schema.jpg" target="_blank">
            <img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="GetTheCallerOfTheCaller_Schema" border="0" alt="GetTheCallerOfTheCaller_Schema" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller_Schema_thumb.jpg" width="244" height="105" />
          </a>
        </p>
        <p>
Nehmen wir an, es existiert eine Hauptmaske, auf der ein Kundendatensatz ausgewählten
werden kann. Auf einer weiteren Maske (1. Maske), sollen nun alle Aufträge des ausgewählten
Kunden angezeigt werden. Diese Maske soll über die Hauptmaske aufgerufen werden. Über
eine 2. Maske, welche über die 1. Maske aufgerufen werden soll, sollen die Adressdaten
des Kunden angezeigt werden.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller2_2.jpg" target="_blank">
            <img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="GetTheCallerOfTheCaller2" border="0" alt="GetTheCallerOfTheCaller2" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller2_thumb.jpg" width="244" height="107" />
          </a>
        </p>
        <p>
Um nun die benötigten Information, ausgewählter Kunden in der Hauptmaske, auf der
2. Maske zur Verfügung zu haben, muss über das FormRun-Objekt der 1. Maske der Aufrufer
(Caller) dieser Maske bestimmt werden.
</p>
        <p>
Beispiel (Init-Methode der 2. Maske):
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> init()</pre>
          <pre>{</pre>
          <pre class="alt">    Object          callerDataSource;</pre>
          <pre>    FormRun         callerFormRun;</pre>
          <pre class="alt">    common          callerRecord;</pre>
          <pre>    common          callerRecordOfCallerRecord;</pre>
          <pre class="alt">    ;</pre>
          <pre>    super();</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="kwrd">if</span>(element.args() &amp;&amp; element.args().dataset())</pre>
          <pre class="alt">    {</pre>
          <pre>        callerRecord = element.args().record();</pre>
          <pre class="alt">        callerDataSource = callerRecord.dataSource();</pre>
          <pre>        callerFormRun = element.args().caller();</pre>
          <pre class="alt"> </pre>
          <pre>        callerRecordOfCallerRecord = callerFormRun.args().record();</pre>
          <pre class="alt"> </pre>
          <pre>        CtrlCallerTable.text(tableid2name(callerRecord.TableId));</pre>
          <pre class="alt">        CtrlCallerOdCallerTable.text(tableid2name(callerRecordOfCallerRecord.TableId));</pre>
          <pre>    }</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
 
</p>
        <p>
        </p>
        <p>
Sicherlicht läßt sich das in dem Beispiel beschriebene Verhalten auch anders (oder
eleganter) Lösen. Dieses Beispiel wurde nur gewählt, um den Ablauf oder die notwendigen
Schritte zu demonstrieren, wie Aufrufer über mehrere Ebenen bestimmt werden können.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=74734dd3-3ce8-4ad9-bc29-2503a0f866aa" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX &amp;ndash; Den Aufrufer des Aufrufers bestimmen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,74734dd3-3ce8-4ad9-bc29-2503a0f866aa.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,74734dd3-3ce8-4ad9-bc29-2503a0f866aa.aspx</link>
      <pubDate>Sun, 24 Jan 2010 19:00:59 GMT</pubDate>
      <description>&lt;p&gt;
In Microsoft Dynamics AX wird das Args-Objekt dazu verwendet, Informationen z.B. an
eine aufzurufende Maske oder Klasse zu übergeben.
&lt;/p&gt;
&lt;p&gt;
Mittels des Args-Objektes ist es z.B. möglich, den auf einer Maske ausgewählten Datensatz
an die Aufzurufende (Unter)Maske zu übergeben, um mit diesem die Darstellung und/oder
Funktionen der Maske anzupassen.&lt;br&gt;
Oft wird dieses Vorgehen dazu verwendet, Abfragen (Queries) entsprechend einzugrenzen,
damit nur relevante Informationen verarbeitet werden.&lt;br&gt;
Eine beispielhafte Anforderung hierfür könnte sein, alle Aufträge des zuvor ausgewählten
Kunden in einer neuen Maske anzuzeigen.
&lt;/p&gt;
&lt;p&gt;
Manchmal ist aber notwendig, nicht nur den Aufrufer (oder den gewählten Datensatz),
sondern auch dessen Aufrufer zu kennen, um bestimme Funktionalitäten erstellen oder
implementieren zu können.&lt;br&gt;
Herbei kann es sein, dass der ausgewählter Datensatz über mehrere Aufrufebenen übergeben
werden muss und der direkte Aufrufer dennoch bekannt sein muss.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller_Schema.jpg" target=_blank&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=GetTheCallerOfTheCaller_Schema border=0 alt=GetTheCallerOfTheCaller_Schema src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller_Schema_thumb.jpg" width=244 height=105&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Nehmen wir an, es existiert eine Hauptmaske, auf der ein Kundendatensatz ausgewählten
werden kann. Auf einer weiteren Maske (1. Maske), sollen nun alle Aufträge des ausgewählten
Kunden angezeigt werden. Diese Maske soll über die Hauptmaske aufgerufen werden. Über
eine 2. Maske, welche über die 1. Maske aufgerufen werden soll, sollen die Adressdaten
des Kunden angezeigt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller2_2.jpg" target=_blank&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=GetTheCallerOfTheCaller2 border=0 alt=GetTheCallerOfTheCaller2 src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/DynamicsAXDenAufruferdesAufrufersbestimm_10DB3/GetTheCallerOfTheCaller2_thumb.jpg" width=244 height=107&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Um nun die benötigten Information, ausgewählter Kunden in der Hauptmaske, auf der
2. Maske zur Verfügung zu haben, muss über das FormRun-Objekt der 1. Maske der Aufrufer
(Caller) dieser Maske bestimmt werden.
&lt;/p&gt;
&lt;p&gt;
Beispiel (Init-Methode der 2. Maske):
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; init()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    Object          callerDataSource;&lt;/pre&gt;
&lt;pre&gt;    FormRun         callerFormRun;&lt;/pre&gt;
&lt;pre class=alt&gt;    common          callerRecord;&lt;/pre&gt;
&lt;pre&gt;    common          callerRecordOfCallerRecord;&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    super();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;if&lt;/span&gt;(element.args() &amp;amp;&amp;amp; element.args().dataset())&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        callerRecord = element.args().record();&lt;/pre&gt;
&lt;pre class=alt&gt;        callerDataSource = callerRecord.dataSource();&lt;/pre&gt;
&lt;pre&gt;        callerFormRun = element.args().caller();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        callerRecordOfCallerRecord = callerFormRun.args().record();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        CtrlCallerTable.text(tableid2name(callerRecord.TableId));&lt;/pre&gt;
&lt;pre class=alt&gt;        CtrlCallerOdCallerTable.text(tableid2name(callerRecordOfCallerRecord.TableId));&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Sicherlicht läßt sich das in dem Beispiel beschriebene Verhalten auch anders (oder
eleganter) Lösen. Dieses Beispiel wurde nur gewählt, um den Ablauf oder die notwendigen
Schritte zu demonstrieren, wie Aufrufer über mehrere Ebenen bestimmt werden können.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=74734dd3-3ce8-4ad9-bc29-2503a0f866aa" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,74734dd3-3ce8-4ad9-bc29-2503a0f866aa.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Notizen, Dokumente oder Dateien werden in Dynamics AX mithilfe des “Dokumentenmanagement-Systems”
verwaltet.
</p>
        <p>
Zu jedem beliebigen Datensatz einer beliebigen Tabelle (z.B. CustTable -&gt; Debitoren)
können beliebig viele Notizen oder Dokumente hinterlegt werden.<br />
Per Benutzeroberfläche kann die entsprechende Funktionalität über die Menüleiste der
Masken aufgerufen werden.
</p>
        <p>
Das folgende Beispiel zeigt wie dies auch per Programmcode erfolgen kann:
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> AKU_CreateDocuRefNote(Args
_args)</pre>
          <pre>{</pre>
          <pre class="alt">    CustTable       custTable;</pre>
          <pre>    DocuRef         docuRef;</pre>
          <pre class="alt">    DocuType        docuType;</pre>
          <pre>    ;</pre>
          <pre class="alt">    custTable = CustTable::find(<span class="str">"1101"</span>);</pre>
          <pre>    docuType  = DocuType::find(<span class="str">"Note"</span>);</pre>
          <pre class="alt">
          </pre>
          <pre>
            <span class="kwrd">if</span>(custTable &amp;&amp; docuType)</pre>
          <pre class="alt">    {</pre>
          <pre>        docuRef.initValue();</pre>
          <pre class="alt">
          </pre>
          <pre>        docuRef.RefTableId   = custTable.TableId;</pre>
          <pre class="alt">        docuRef.RefRecId     = custTable.RecId;</pre>
          <pre>        docuRef.RefCompanyId = custTable.dataAreaId;</pre>
          <pre class="alt"> </pre>
          <pre>        docuRef.TypeId       = docuType.TypeId;</pre>
          <pre class="alt">
          </pre>
          <pre>        docuRef.Restriction  = DocuRestriction::External;</pre>
          <pre class="alt">
          </pre>
          <pre>        docuRef.Name         = <span class="str">"Name der Notiz"</span>;</pre>
          <pre class="alt">        docuRef.Notes        = <span class="str">"Text (Inhalt) der
Notiz"</span>;</pre>
          <pre>        docuRef.insert();</pre>
          <pre class="alt">    }</pre>
          <pre>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX - Erstellen von Notizen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86.aspx</link>
      <pubDate>Fri, 22 Jan 2010 18:29:40 GMT</pubDate>
      <description>&lt;p&gt;
Notizen, Dokumente oder Dateien werden in Dynamics AX mithilfe des “Dokumentenmanagement-Systems”
verwaltet.
&lt;/p&gt;
&lt;p&gt;
Zu jedem beliebigen Datensatz einer beliebigen Tabelle (z.B. CustTable -&amp;gt; Debitoren)
können beliebig viele Notizen oder Dokumente hinterlegt werden.&lt;br&gt;
Per Benutzeroberfläche kann die entsprechende Funktionalität über die Menüleiste der
Masken aufgerufen werden.
&lt;/p&gt;
&lt;p&gt;
Das folgende Beispiel zeigt wie dies auch per Programmcode erfolgen kann:
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; AKU_CreateDocuRefNote(Args
_args)&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    CustTable       custTable;&lt;/pre&gt;
&lt;pre&gt;    DocuRef         docuRef;&lt;/pre&gt;
&lt;pre class=alt&gt;    DocuType        docuType;&lt;/pre&gt;
&lt;pre&gt;    ;&lt;/pre&gt;
&lt;pre class=alt&gt;    custTable = CustTable::find(&lt;span class=str&gt;"1101"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    docuType  = DocuType::find(&lt;span class=str&gt;"Note"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;if&lt;/span&gt;(custTable &amp;amp;&amp;amp; docuType)&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        docuRef.initValue();&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;/pre&gt;
&lt;pre&gt;        docuRef.RefTableId   = custTable.TableId;&lt;/pre&gt;
&lt;pre class=alt&gt;        docuRef.RefRecId     = custTable.RecId;&lt;/pre&gt;
&lt;pre&gt;        docuRef.RefCompanyId = custTable.dataAreaId;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        docuRef.TypeId       = docuType.TypeId;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;/pre&gt;
&lt;pre&gt;        docuRef.Restriction  = DocuRestriction::External;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;/pre&gt;
&lt;pre&gt;        docuRef.Name         = &lt;span class=str&gt;"Name der Notiz"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class=alt&gt;        docuRef.Notes        = &lt;span class=str&gt;"Text (Inhalt) der Notiz"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;        docuRef.insert();&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,a0f445dc-1961-43b9-a7ff-fdfdbfb2cb86.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=6395e9fa-5f88-4509-a72e-0df74954fddf</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,6395e9fa-5f88-4509-a72e-0df74954fddf.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,6395e9fa-5f88-4509-a72e-0df74954fddf.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=6395e9fa-5f88-4509-a72e-0df74954fddf</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Für Debitoren (Kunden) kann in Microsoft Dynamics AX ein Kreditlimit vergeben/eingestellt
werden.
</p>
        <p>
In der Auftragsmaske wird bei Anlage eines Auftrag (in Abhängigkeit der Kreditlimit-Einstellungen)
das verbleibende Kreditlimit berechnet und der Auftragswert gegen dieses geprüft.<br />
Bei Überschreitung des Kreditlimits wird eine entsprechende Warnung oder ein entsprechender
Fehler ausgegeben.
</p>
        <p>
Die Funktion zur Überprüfung des Kreditlimits kann auch manuell, durch  eine
entsprechende Funktion auf der Auftragsmaske, aufgerufen werden.
</p>
        <p>
Soll das verbleibende Kreditlimit mit X++ Code berechnet werden, muss leider eine
“Kleinigkeit” beachtet werden, die so auf den ersten Blick nicht immer ersichtlich
ist bzw. für Verwirrung sorgen kann.
</p>
        <p>
Die Berechnung des verfügbaren Kreditrahmens oder des verbleibenden Kreditlimits ist
durch die alleinige Angabe eines Debitors nicht möglich.<br />
Es muss immer ein entsprechender Auftrag “vorhanden” sein um diese auszuführen zu
können.
</p>
        <p>
Berechtigterweise stellt sich die Frage, wie das verbleibende Kreditlimit eines Debitors
berechnet werden kann, wenn keine “Beziehung” zu einem Auftrag besteht bzw. wenn kein
Auftrag angegeben werden kann.<br />
Hierfür muss ein kleiner “Trick” angewendet werden, der nichts anderes macht, als
einen neuen “SalesTable” Datensatz zu initialisieren, diesen aber nicht zu speichern.<br />
Ist der “SalesTable” Datensatz initialisiert kann mithilfe der beiden Klassen “SalesTotals”
und “CustCreditLimit” der verfügbare Kreditrahmen berechnet werden.
</p>
        <p>
Beispiel:
</p>
        <div class="csharpcode">
          <pre class="alt">    CustTable               custTable = CustTable::find(<span class="str">"1101"</span>);</pre>
          <pre>    CustCreditLimit         custCreditLimit;</pre>
          <pre class="alt">    SalesTotals             salesTotals;</pre>
          <pre>    SalesTable              salesTable;</pre>
          <pre class="alt">    AmountMST               balanceEstimate;</pre>
          <pre>    AmountMst               creditRemain;</pre>
          <pre class="alt">    ;</pre>
          <pre>    salesTable.CustAccount  = custTable.AccountNum;</pre>
          <pre class="alt">    salesTable.initFromCustTable();</pre>
          <pre> </pre>
          <pre class="alt">    salesTotals = SalesTotals::construct(salesTable);</pre>
          <pre>    salesTotals.calc();</pre>
          <pre class="alt"> </pre>
          <pre>    custCreditLimit = CustCreditLimit::construct(salesTable);</pre>
          <pre class="alt">    balanceEstimate = custCreditLimit.balanceEstimate();</pre>
          <pre>
            <span class="kwrd">if</span>(custCreditLimit.useEstimated())</pre>
          <pre class="alt">    {</pre>
          <pre>        creditRemain -= balanceEstimate;</pre>
          <pre class="alt">    }</pre>
          <pre> </pre>
          <pre class="alt">    creditRemain += conpeek(salesTotals.displayFieldsCurrency(CustTable.Currency), TradeTotals::posFreeValue());</pre>
          <pre> </pre>
          <pre class="alt"> </pre>
          <pre>    info(strfmt(<span class="str">"Verbleibendes Kreditlimit: %1"</span>, creditRemain));</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=6395e9fa-5f88-4509-a72e-0df74954fddf" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Ermittlung des verbleibenden Kreditlimits</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,6395e9fa-5f88-4509-a72e-0df74954fddf.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,6395e9fa-5f88-4509-a72e-0df74954fddf.aspx</link>
      <pubDate>Wed, 30 Dec 2009 10:16:18 GMT</pubDate>
      <description>&lt;p&gt;
Für Debitoren (Kunden) kann in Microsoft Dynamics AX ein Kreditlimit vergeben/eingestellt
werden.
&lt;/p&gt;
&lt;p&gt;
In der Auftragsmaske wird bei Anlage eines Auftrag (in Abhängigkeit der Kreditlimit-Einstellungen)
das verbleibende Kreditlimit berechnet und der Auftragswert gegen dieses geprüft.&lt;br&gt;
Bei Überschreitung des Kreditlimits wird eine entsprechende Warnung oder ein entsprechender
Fehler ausgegeben.
&lt;/p&gt;
&lt;p&gt;
Die Funktion zur Überprüfung des Kreditlimits kann auch manuell, durch&amp;nbsp; eine
entsprechende Funktion auf der Auftragsmaske, aufgerufen werden.
&lt;/p&gt;
&lt;p&gt;
Soll das verbleibende Kreditlimit mit X++ Code berechnet werden, muss leider eine
“Kleinigkeit” beachtet werden, die so auf den ersten Blick nicht immer ersichtlich
ist bzw. für Verwirrung sorgen kann.
&lt;/p&gt;
&lt;p&gt;
Die Berechnung des verfügbaren Kreditrahmens oder des verbleibenden Kreditlimits ist
durch die alleinige Angabe eines Debitors nicht möglich.&lt;br&gt;
Es muss immer ein entsprechender Auftrag “vorhanden” sein um diese auszuführen zu
können.
&lt;/p&gt;
&lt;p&gt;
Berechtigterweise stellt sich die Frage, wie das verbleibende Kreditlimit eines Debitors
berechnet werden kann, wenn keine “Beziehung” zu einem Auftrag besteht bzw. wenn kein
Auftrag angegeben werden kann.&lt;br&gt;
Hierfür muss ein kleiner “Trick” angewendet werden, der nichts anderes macht, als
einen neuen “SalesTable” Datensatz zu initialisieren, diesen aber nicht zu speichern.&lt;br&gt;
Ist der “SalesTable” Datensatz initialisiert kann mithilfe der beiden Klassen “SalesTotals”
und “CustCreditLimit” der verfügbare Kreditrahmen berechnet werden.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    CustTable               custTable = CustTable::find(&lt;span class=str&gt;"1101"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    CustCreditLimit         custCreditLimit;&lt;/pre&gt;
&lt;pre class=alt&gt;    SalesTotals             salesTotals;&lt;/pre&gt;
&lt;pre&gt;    SalesTable              salesTable;&lt;/pre&gt;
&lt;pre class=alt&gt;    AmountMST               balanceEstimate;&lt;/pre&gt;
&lt;pre&gt;    AmountMst               creditRemain;&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    salesTable.CustAccount  = custTable.AccountNum;&lt;/pre&gt;
&lt;pre class=alt&gt;    salesTable.initFromCustTable();&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    salesTotals = SalesTotals::construct(salesTable);&lt;/pre&gt;
&lt;pre&gt;    salesTotals.calc();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    custCreditLimit = CustCreditLimit::construct(salesTable);&lt;/pre&gt;
&lt;pre class=alt&gt;    balanceEstimate = custCreditLimit.balanceEstimate();&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;if&lt;/span&gt;(custCreditLimit.useEstimated())&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        creditRemain -= balanceEstimate;&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    creditRemain += conpeek(salesTotals.displayFieldsCurrency(CustTable.Currency), TradeTotals::posFreeValue());&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    info(strfmt(&lt;span class=str&gt;"Verbleibendes Kreditlimit: %1"&lt;/span&gt;, creditRemain));&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=6395e9fa-5f88-4509-a72e-0df74954fddf" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,6395e9fa-5f88-4509-a72e-0df74954fddf.aspx</comments>
      <category>Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=463091a5-37b1-4375-9b57-6501ff8a1962</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,463091a5-37b1-4375-9b57-6501ff8a1962.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,463091a5-37b1-4375-9b57-6501ff8a1962.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=463091a5-37b1-4375-9b57-6501ff8a1962</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In Microsoft Dynamics AX beziehen Masken ihre Daten, oder anders gesagt die Daten
welche sie anzeigen, über so genannte DataSources.<br />
In einer DataSource sind somit die aktuellen auf der Maske angezeigten Daten (lokal)
gespeichert.
</p>
        <p>
Zugriff auf den jeweils aktuell ausgewählten Datensatz erhält man üblicherweise über
genau diese DataSource.<br />
Der ausgewählte Datensatz kann unter anderem auch, z.B. durch ein MenuItem(Button),
an eine Funktion oder andere Maske übergeben werden.<br />
Hierfür muss nur die Eigenschaft “DataSource”, in diesem Beispiel des MenuItem(Button),
entsprechend eingestellt sein.
</p>
        <p>
Ist keine DataSource in den Eigenschaften hinterlegt wird immer die erste DataSource
der Query verwendet bzw. dessen aktiver Datensatz übergeben.<br />
In der Regel ist dies die DataSource, welche beim Erstellen der Maske als erstes hinzugefügt
oder erstellt wurde (Ausnahme ist hier eine eventuelle Manipulation der Query per
Programmcode).
</p>
        <p>
Dieses Vorgehen ist für 90% aller Fälle das wohl am besten geeignete Vorgehen und
wird in dieser Weise auch vom Dynamics AX Standard verwendet.<br />
Leider gibt es Anwendungsfälle, bei denen diese “starre Verbindung” von DataSource
und z.B. Button oder MenuItem nicht funktioniert, beziehungsweise nicht zum gewünschten
Ergebnis führt.
</p>
        <p>
Angenommen man hat eine Maske mit zwei DataSources (CustTable und SalesTable), deren
Daten über zwei Grids angezeigt werden, sowie einen Button, welcher eine Operation
mit dem zuletzt ausgewählten Datensatz (unabhängig von der DataSource) durchführen
soll.<br />
Wenn ein Datensatz der DataSource “CustTable” selektiert wurde, soll dieser verarbeitet
werden.<br />
Ist zuletzt ein Datensatz der DataSource “SalesTable” selektiert wurden, soll die
Operation mit diesem Datensatz erfolgen.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_2.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Maske" border="0" alt="Maske" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_thumb.jpg" width="187" height="244" />
          </a>
        </p>
        <p>
Bei dieser Anforderung ergibt sich das Problem, dass die Standardvorgehensweise zur
Abfrage des selektierten Datensatzes nicht funktioniert, da hierfür eine der DataSources
“direkt” angesprochen werden muss.<br />
Welche DataSource nun aber die “aktive” ist, lässt sich leider nicht ermitteln, da
standardmäßig jede DataSource einen “aktiven” Datensatz hat und somit eine Unterscheidung,
ob der Aufruf für die “CustTable” oder “SalesTable” erfolgen soll, nicht möglich ist.
</p>
        <p>
Über die Methode “docCursor” der Klasse FormRun bietet sich eine zweite Möglichkeit,
den aktiven (ausgewählten) Datensatz zu ermitteln.<br />
Dieses Vorgehen wird z.B. vom Dokumentenmangement (Form “DocuView”) verwendet, um
den zuletzt gewählten Datensatz zu ermitteln und somit die dem Datensatz zugeordneten
Dokumente anzuzeigen.
</p>
        <p>
Leider scheidet dieser Weg ebenfalls aus, da ein “Click” auf den Button zur Folge
hat, dass der jeweils aktive Datensatz der “Button-DataSource” durch die Methode “docCursor”
zurück geben wird.<br />
Dies ist soweit auch logisch, da ein Button immer einer DataSource zugeordnet ist
(entweder über Angabe in der entsprechenden Eigenschaft des Buttons oder, wenn nicht
festgelegt, die erste DataSource der Query). 
</p>
        <p>
Wie ist es nun aber möglich, dennoch den zuletzt selektierten (ausgewählten) Datensatz
zu ermitteln, wenn die im Standard verwendeten Wege nicht funktionieren?
</p>
        <p>
Um das gewünschte Ziel zu erfüllen (bestimmen, welcher der zuletzt selektierte Datensatz
ist) muss eine kleine funktionale Erweiterung der “Info” Klasse durchgeführt werden.
</p>
        <p>
Zuerst müssen in der “classDeclaration” der Klasse “Info” zwei neue Variablen/Buffer
zum Speichern des selektierten Datensatzes erstellt werden. 
<br /></p>
        <div class="csharpcode">
          <pre class="alt">final <span class="kwrd">class</span> Info
extends xInfo</pre>
          <pre>{</pre>
          <pre class="alt">    #SysTaskRecorderMacro</pre>
          <pre> </pre>
          <pre class="alt">    ObjectIdent         docuView;</pre>
          <pre>    ObjectIdent         lastActivatedForm;</pre>
          <pre class="alt"> </pre>
          <pre>    ...</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="rem">// New code --&gt; </span>
          </pre>
          <pre class="alt">    Common                  lastSelectedRecord;</pre>
          <pre>    Common                  selectedRecord;</pre>
          <pre class="alt">
            <span class="rem">//New code &lt;--</span>
          </pre>
          <pre> </pre>
          <pre class="alt">    #Define.CurrentVersion(1)</pre>
          <pre>}</pre>
          <pre> </pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Nun müssen noch einige neue Methoden für die Klasse “Info” erstellt werden, damit
die Variablen/Buffer geschrieben, abgefragt und gelöscht werden können.<br /></p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">private</span>
            <span class="kwrd">void</span> setLastSelectedRecord(FormRun
_formRun)</pre>
          <pre>{</pre>
          <pre class="alt">    ;</pre>
          <pre>
            <span class="kwrd">if</span>(_formRun.docCursor())</pre>
          <pre class="alt">    {</pre>
          <pre>
            <span class="kwrd">if</span>(lastSelectedRecord)</pre>
          <pre class="alt">        {</pre>
          <pre>            lastSelectedRecord = selectedRecord;</pre>
          <pre class="alt">        }</pre>
          <pre>
            <span class="kwrd">else</span>
          </pre>
          <pre class="alt">        {</pre>
          <pre>
            <span class="rem">//Only get the record data, not the cursor</span>
          </pre>
          <pre class="alt">            lastSelectedRecord = _formRun.docCursor().data();</pre>
          <pre>        }</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="rem">//Only get the record data, not the cursor</span>
          </pre>
          <pre class="alt">        selectedRecord = _formRun.docCursor().data();</pre>
          <pre>    }</pre>
          <pre class="alt">}</pre>
        </div>
        <div class="csharpcode"> 
</div>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">private</span>
            <span class="kwrd">void</span> clearLastSelectedRecord()</pre>
          <pre>{</pre>
          <pre class="alt">    ;</pre>
          <pre>    lastSelectedRecord.clear();</pre>
          <pre class="alt">    selectedRecord.clear();</pre>
          <pre>}</pre>
          <pre> </pre>
          <div class="csharpcode">
            <pre class="alt">common lastSelectedRecord()</pre>
            <pre>{</pre>
            <pre class="alt">    ;</pre>
            <pre>
              <span class="kwrd">return</span> lastSelectedRecord;</pre>
            <pre class="alt">}</pre>
          </div>
          <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        </div>
        <p>
 
</p>
        <p>
Zum Schluss müssen diese neu erstellten Methoden noch entsprechend in der Methode
“formNotify” aufgerufen werden.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span> formNotify(FormRun
formRun,FormNotify <span class="kwrd">event</span>)</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">switch</span> (<span class="kwrd">event</span>)</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">case</span> FormNotify::Activate:</pre>
          <pre>
            <span class="kwrd">this</span>.activate(formRun);</pre>
          <pre class="alt">
            <span class="kwrd">if</span> (docu)</pre>
          <pre>                docu.reSearch(formRun);</pre>
          <pre class="alt">
            <span class="rem">//New code --&gt;</span>
          </pre>
          <pre>
            <span class="kwrd">this</span>.setLastSelectedRecord(formRun);</pre>
          <pre class="alt">
            <span class="rem">//New code &lt;--</span>
          </pre>
          <pre>
            <span class="kwrd">break</span>;</pre>
          <pre class="alt">
            <span class="kwrd">case</span> FormNotify::DeActivate:</pre>
          <pre>
            <span class="kwrd">break</span>;</pre>
          <pre class="alt">
            <span class="kwrd">case</span> FormNotify::Open:</pre>
          <pre>
            <span class="kwrd">this</span>.open(formRun);</pre>
          <pre class="alt">
            <span class="kwrd">if</span> (docu)</pre>
          <pre>                docu.set(formRun);</pre>
          <pre class="alt">
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="kwrd">case</span> FormNotify::Close:</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.close(formRun);</pre>
          <pre>
            <span class="kwrd">if</span> (docu)</pre>
          <pre class="alt">                docu.clear(formRun);</pre>
          <pre>
            <span class="rem">//New code --&gt;</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">this</span>.clearLastSelectedRecord();</pre>
          <pre>
            <span class="rem">//New code &lt;--</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">break</span>;</pre>
          <pre>
            <span class="kwrd">case</span> FormNotify::RecordChange:</pre>
          <pre class="alt">
            <span class="kwrd">if</span> (docu)</pre>
          <pre>                docu.reSearch(formRun);</pre>
          <pre class="alt">
            <span class="rem">//New code --&gt;</span>
          </pre>
          <pre>
            <span class="kwrd">this</span>.setLastSelectedRecord(formRun);</pre>
          <pre class="alt">
            <span class="rem">//New code &lt;--</span>
          </pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">if</span> (formRun.isWorkflowEnabled())</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="rem">// only refresh controls if current
ds equals workflow data source</span>
          </pre>
          <pre>
            <span class="kwrd">if</span> (formRun.objectSet().name() == formRun.workflowDataSource().name())</pre>
          <pre class="alt">                    formRun.updateWorkflowControls();</pre>
          <pre>            }</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="kwrd">break</span>;</pre>
          <pre class="alt">
            <span class="kwrd">case</span> FormNotify::NoteClicked:</pre>
          <pre>
            <span class="kwrd">if</span> (docu)</pre>
          <pre class="alt">                docu.note(formRun);</pre>
          <pre>
            <span class="kwrd">break</span>;</pre>
          <pre class="alt">    }</pre>
          <pre>}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <pre class="csharpcode">Durch diese kleine Codeänderung kann nun der zuletzt ausgewählte Datensatz, unabhängig von einer DataSource, abgefragt werden.<br /></pre>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span> clicked()</pre>
          <pre>{</pre>
          <pre class="alt">    Common      currentRecord;</pre>
          <pre>    DictTable   dictTable;</pre>
          <pre class="alt">    ;</pre>
          <pre>    super();</pre>
          <pre class="alt">
            <span class="rem">//Get the last selected record</span>
          </pre>
          <pre>    currentRecord = infolog.lastSelectedRecord();</pre>
          <pre class="alt"> </pre>
          <pre>    dictTable = <span class="kwrd">new</span> DictTable(currentRecord.TableId);</pre>
          <pre class="alt"> </pre>
          <pre>    setPrefix(tableid2name(currentRecord.TableId));</pre>
          <pre class="alt">    info(strfmt(<span class="str">"%1 - %2"</span>, currentRecord.(dictTable.titleField1()),
currentRecord.(dictTable.titleField2())));</pre>
          <pre>}</pre>
          <pre>
            <br />
Bezogen auf die zuvor beschrieben Anforderung könnte das Ergebnis so aussehen.</pre>
          <pre> </pre>
        </div>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_CustTable_2.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Maske_CustTable" border="0" alt="Maske_CustTable" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_CustTable_thumb.jpg" width="244" height="184" />
          </a>  <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_SalesTable_2.jpg" target="_blank"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Maske_SalesTable" border="0" alt="Maske_SalesTable" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_SalesTable_thumb.jpg" width="244" height="184" /></a></p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=463091a5-37b1-4375-9b57-6501ff8a1962" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX &amp;ndash; Den zuletzt ausgew&amp;auml;hlten Datensatz ermitteln</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,463091a5-37b1-4375-9b57-6501ff8a1962.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,463091a5-37b1-4375-9b57-6501ff8a1962.aspx</link>
      <pubDate>Sat, 24 Oct 2009 16:45:25 GMT</pubDate>
      <description>&lt;p&gt;
In Microsoft Dynamics AX beziehen Masken ihre Daten, oder anders gesagt die Daten
welche sie anzeigen, über so genannte DataSources.&lt;br&gt;
In einer DataSource sind somit die aktuellen auf der Maske angezeigten Daten (lokal)
gespeichert.
&lt;/p&gt;
&lt;p&gt;
Zugriff auf den jeweils aktuell ausgewählten Datensatz erhält man üblicherweise über
genau diese DataSource.&lt;br&gt;
Der ausgewählte Datensatz kann unter anderem auch, z.B. durch ein MenuItem(Button),
an eine Funktion oder andere Maske übergeben werden.&lt;br&gt;
Hierfür muss nur die Eigenschaft “DataSource”, in diesem Beispiel des MenuItem(Button),
entsprechend eingestellt sein.
&lt;/p&gt;
&lt;p&gt;
Ist keine DataSource in den Eigenschaften hinterlegt wird immer die erste DataSource
der Query verwendet bzw. dessen aktiver Datensatz übergeben.&lt;br&gt;
In der Regel ist dies die DataSource, welche beim Erstellen der Maske als erstes hinzugefügt
oder erstellt wurde (Ausnahme ist hier eine eventuelle Manipulation der Query per
Programmcode).
&lt;/p&gt;
&lt;p&gt;
Dieses Vorgehen ist für 90% aller Fälle das wohl am besten geeignete Vorgehen und
wird in dieser Weise auch vom Dynamics AX Standard verwendet.&lt;br&gt;
Leider gibt es Anwendungsfälle, bei denen diese “starre Verbindung” von DataSource
und z.B. Button oder MenuItem nicht funktioniert, beziehungsweise nicht zum gewünschten
Ergebnis führt.
&lt;/p&gt;
&lt;p&gt;
Angenommen man hat eine Maske mit zwei DataSources (CustTable und SalesTable), deren
Daten über zwei Grids angezeigt werden, sowie einen Button, welcher eine Operation
mit dem zuletzt ausgewählten Datensatz (unabhängig von der DataSource) durchführen
soll.&lt;br&gt;
Wenn ein Datensatz der DataSource “CustTable” selektiert wurde, soll dieser verarbeitet
werden.&lt;br&gt;
Ist zuletzt ein Datensatz der DataSource “SalesTable” selektiert wurden, soll die
Operation mit diesem Datensatz erfolgen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Maske border=0 alt=Maske src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_thumb.jpg" width=187 height=244&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Bei dieser Anforderung ergibt sich das Problem, dass die Standardvorgehensweise zur
Abfrage des selektierten Datensatzes nicht funktioniert, da hierfür eine der DataSources
“direkt” angesprochen werden muss.&lt;br&gt;
Welche DataSource nun aber die “aktive” ist, lässt sich leider nicht ermitteln, da
standardmäßig jede DataSource einen “aktiven” Datensatz hat und somit eine Unterscheidung,
ob der Aufruf für die “CustTable” oder “SalesTable” erfolgen soll, nicht möglich ist.
&lt;/p&gt;
&lt;p&gt;
Über die Methode “docCursor” der Klasse FormRun bietet sich eine zweite Möglichkeit,
den aktiven (ausgewählten) Datensatz zu ermitteln.&lt;br&gt;
Dieses Vorgehen wird z.B. vom Dokumentenmangement (Form “DocuView”) verwendet, um
den zuletzt gewählten Datensatz zu ermitteln und somit die dem Datensatz zugeordneten
Dokumente anzuzeigen.
&lt;/p&gt;
&lt;p&gt;
Leider scheidet dieser Weg ebenfalls aus, da ein “Click” auf den Button zur Folge
hat, dass der jeweils aktive Datensatz der “Button-DataSource” durch die Methode “docCursor”
zurück geben wird.&lt;br&gt;
Dies ist soweit auch logisch, da ein Button immer einer DataSource zugeordnet ist
(entweder über Angabe in der entsprechenden Eigenschaft des Buttons oder, wenn nicht
festgelegt, die erste DataSource der Query). 
&lt;/p&gt;
&lt;p&gt;
Wie ist es nun aber möglich, dennoch den zuletzt selektierten (ausgewählten) Datensatz
zu ermitteln, wenn die im Standard verwendeten Wege nicht funktionieren?
&lt;/p&gt;
&lt;p&gt;
Um das gewünschte Ziel zu erfüllen (bestimmen, welcher der zuletzt selektierte Datensatz
ist) muss eine kleine funktionale Erweiterung der “Info” Klasse durchgeführt werden.
&lt;/p&gt;
&lt;p&gt;
Zuerst müssen in der “classDeclaration” der Klasse “Info” zwei neue Variablen/Buffer
zum Speichern des selektierten Datensatzes erstellt werden. 
&lt;br&gt;
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;final &lt;span class=kwrd&gt;class&lt;/span&gt; Info extends
xInfo&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    #SysTaskRecorderMacro&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    ObjectIdent         docuView;&lt;/pre&gt;
&lt;pre&gt;    ObjectIdent         lastActivatedForm;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    ...&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=rem&gt;// New code --&amp;gt; &lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;    Common                  lastSelectedRecord;&lt;/pre&gt;
&lt;pre&gt;    Common                  selectedRecord;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=rem&gt;//New code &amp;lt;--&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    #Define.CurrentVersion(1)&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Nun müssen noch einige neue Methoden für die Klasse “Info” erstellt werden, damit
die Variablen/Buffer geschrieben, abgefragt und gelöscht werden können.&lt;br&gt;
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;private&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; setLastSelectedRecord(FormRun
_formRun)&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;if&lt;/span&gt;(_formRun.docCursor())&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt;(lastSelectedRecord)&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            lastSelectedRecord = selectedRecord;&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=rem&gt;//Only get the record data, not the cursor&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            lastSelectedRecord = _formRun.docCursor().data();&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=rem&gt;//Only get the record data, not the cursor&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        selectedRecord = _formRun.docCursor().data();&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=csharpcode&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;private&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; clearLastSelectedRecord()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    lastSelectedRecord.clear();&lt;/pre&gt;
&lt;pre class=alt&gt;    selectedRecord.clear();&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;common lastSelectedRecord()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;return&lt;/span&gt; lastSelectedRecord;&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Zum Schluss müssen diese neu erstellten Methoden noch entsprechend in der Methode
“formNotify” aufgerufen werden.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;void&lt;/span&gt; formNotify(FormRun
formRun,FormNotify &lt;span class=kwrd&gt;event&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;switch&lt;/span&gt; (&lt;span class=kwrd&gt;event&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::Activate:&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.activate(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (docu)&lt;/pre&gt;
&lt;pre&gt;                docu.reSearch(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;//New code --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.setLastSelectedRecord(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;//New code &amp;lt;--&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::DeActivate:&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::Open:&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.open(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (docu)&lt;/pre&gt;
&lt;pre&gt;                docu.set(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::Close:&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.close(formRun);&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (docu)&lt;/pre&gt;
&lt;pre class=alt&gt;                docu.clear(formRun);&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=rem&gt;//New code --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.clearLastSelectedRecord();&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=rem&gt;//New code &amp;lt;--&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::RecordChange:&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (docu)&lt;/pre&gt;
&lt;pre&gt;                docu.reSearch(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;//New code --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.setLastSelectedRecord(formRun);&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;//New code &amp;lt;--&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (formRun.isWorkflowEnabled())&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=rem&gt;// only refresh controls if current
ds equals workflow data source&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;                &lt;span class=kwrd&gt;if&lt;/span&gt; (formRun.objectSet().name() == formRun.workflowDataSource().name())&lt;/pre&gt;
&lt;pre class=alt&gt;                    formRun.updateWorkflowControls();&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;case&lt;/span&gt; FormNotify::NoteClicked:&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;if&lt;/span&gt; (docu)&lt;/pre&gt;
&lt;pre class=alt&gt;                docu.note(formRun);&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;pre class=csharpcode&gt;Durch diese kleine Codeänderung kann nun der zuletzt ausgewählte Datensatz, unabhängig von einer DataSource, abgefragt werden.&lt;br&gt;
&lt;/pre&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;void&lt;/span&gt; clicked()&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    Common      currentRecord;&lt;/pre&gt;
&lt;pre&gt;    DictTable   dictTable;&lt;/pre&gt;
&lt;pre class=alt&gt;    ;&lt;/pre&gt;
&lt;pre&gt;    super();&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=rem&gt;//Get the last selected record&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    currentRecord = infolog.lastSelectedRecord();&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    dictTable = &lt;span class=kwrd&gt;new&lt;/span&gt; DictTable(currentRecord.TableId);&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    setPrefix(tableid2name(currentRecord.TableId));&lt;/pre&gt;
&lt;pre class=alt&gt;    info(strfmt(&lt;span class=str&gt;"%1 - %2"&lt;/span&gt;, currentRecord.(dictTable.titleField1()),
currentRecord.(dictTable.titleField2())));&lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;pre&gt;
&lt;br&gt;
Bezogen auf die zuvor beschrieben Anforderung könnte das Ergebnis so aussehen.&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_CustTable_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Maske_CustTable border=0 alt=Maske_CustTable src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_CustTable_thumb.jpg" width=244 height=184&gt;&lt;/a&gt;&amp;nbsp; &lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_SalesTable_2.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Maske_SalesTable border=0 alt=Maske_SalesTable src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/MicrosoftDynamicsAXDenzuletztausgewhlten_10F66/Maske_SalesTable_thumb.jpg" width=244 height=184&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=463091a5-37b1-4375-9b57-6501ff8a1962" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,463091a5-37b1-4375-9b57-6501ff8a1962.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=337a6675-9f17-45f8-b620-c47081ec4e8e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,337a6675-9f17-45f8-b620-c47081ec4e8e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,337a6675-9f17-45f8-b620-c47081ec4e8e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=337a6675-9f17-45f8-b620-c47081ec4e8e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In mehreren Artikeln wurde bereits beschrieben, wie LookupForms erstellt werden müssen,
um alle Funktionen bereit zu stellen, die auch durch einen Standard-Lookup bereit
gestellt werden.
</p>
        <p>
Ein guter <a href="http://axaptapedia.com/Lookup_Form">Artikel</a> ist zum Beispiel
auf <a href="http://axaptapedia.com">Axaptapedia</a> zu finden:<br /><a href="http://axaptapedia.com/Lookup_Form">http://axaptapedia.com/Lookup_Form</a></p>
        <p>
Leider wurde in diesem Artikel auf eine Kleinigkeit nicht hingewiesen, die allerdings
für sehr viel Verwirrung sorgen kann.
</p>
        <p>
Um beim Öffnen des Lookups den bereits eingetragenen Wert zu selektieren (in dem Control
der aufrufenden Maske), müssen wie in dem Artikel beschrieben, die Methoden „executeQuery“
und „init“ der DataSource der Lookup-Maske überschrieben werden.
</p>
        <p>
Beispiel:
</p>
        <p>
        </p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">void</span> executeQuery()
{ FormStringControl callerControl = SysTableLookup::getCallerStringControl(element.args());
; super(); xyz_ds.findValue(fieldnum(xyz,id),callerControl.text()); } <span class="kwrd">public</span><span class="kwrd">void</span> init()
{ Query q = <span class="kwrd">new</span> Query(); QueryBuildDataSource qbds; ; super();
qbds = q.addDataSource(tablenum(xyz)); qbds.orderMode(OrderMode::OrderBy); qbds.addSortField(fieldNum(xyz,some_other_field)); <span class="kwrd">this</span>.query(q);
} </pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Es wird auch beschrieben, dass in der Methode “init” der Datasource eigene Ranges
oder Sortings definiert werden können.<br />
Dies ist soweit auch richtig, allerdings mit einer Ausnahme.
</p>
        <p>
Wird auf dem Feld, welches bei dem Aufruf von „Datasource.findValue“ in der Methode
„init“ angegeben wurde (sollte auch immer das Feld sein, dessen Wert durch den Lookup
ausgewählt wird), eine Range definiert, so funktioniert die Selektion des zuvor gewählten
Wertes nicht mehr und es wird immer der erste Wert im Lookup selektiert bzw. ausgewählt.
</p>
        <p>
Beispiel:
</p>
        <p>
        </p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">void</span> executeQuery()
{ FormStringControl callerControl = SysTableLookup::getCallerStringControl(element.args());
; super(); xyz_ds.findValue(fieldnum(xyz,id),callerControl.text()); } <span class="kwrd">public</span><span class="kwrd">void</span> init()
{ Query q = <span class="kwrd">new</span> Query(); QueryBuildDataSource qbds; QueryBuildRange
range; ; super(); qbds = q.addDataSource(tablenum(xyz)); qbds.orderMode(OrderMode::OrderBy);
qbds.addSortField(fieldNum(xyz,some_other_field)); range = qbds.addRange(fieldnum(xyz,id));
range.<span class="kwrd">value</span>(SysQuery::valueNot(&lt;someValue&gt;)); <span class="kwrd">this</span>.query(q);
} </pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <p>
Dieses Verhalten lässt sich allerdings umgehen, wenn anstelle des Aufrufs von “DataSource.findValue”
in der „ExecuteQuery“ Methode der DataSource der Aufruf von „DataSoucre.findRecord“
verwendet wird.<br />
Hierfür muss aber der entsprechende Datensatz des zuvor oder bereits ausgewählten
Wertes ermittelt werden um diesen beim Aufruf von „DataSource.findRecord“ als Parameter
zu übergeben.
</p>
        <p>
Beispiel:
</p>
        <pre class="csharpcode">
          <span class="kwrd">public</span>
          <span class="kwrd">void</span> executeQuery()
{ FormStringControl callerControl; Xyz xyzRecord; ; callerControl = SysTableLookup::getCallerStringControl(element.args());
xyzRecord = Xyz::find(callerControl.text()); super(); xyz_ds.findRecord(xyzRecord);
} <span class="kwrd">public</span><span class="kwrd">void</span> init() { Query q
= <span class="kwrd">new</span> Query(); QueryBuildDataSource qbds; QueryBuildRange
range; ; super(); qbds = q.addDataSource(tablenum(xyz)); qbds.orderMode(OrderMode::OrderBy);
qbds.addSortField(fieldNum(xyz,some_other_field)); range = qbds.addRange(fieldnum(xyz,id));
range.<span class="kwrd">value</span>(SysQuery::valueNot(&lt;someValue&gt;)); <span class="kwrd">this</span>.query(q);
}</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Es muss also darauf geachtet werden, ob eine Einschränkung (Range) auf dem „ID-Feld“
benötigt wird oder nicht.
</p>
        <p>
Wird keine Einschränkung benötigt, kann, wie in dem Artikel auf Axaptapedia beschrieben,
mit „DataSource.findValue“ gearbeitet werden um den entsprechenden Datensatz zu selektieren.<br />
Wird aber eine solche Einschränkung benötigt, muss mit „DataSoucre.findRecord“ gearbeitet
werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=337a6675-9f17-45f8-b620-c47081ec4e8e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX LookupForms &amp;ndash; FindValue und Range auf gleichem Feld</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,337a6675-9f17-45f8-b620-c47081ec4e8e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,337a6675-9f17-45f8-b620-c47081ec4e8e.aspx</link>
      <pubDate>Thu, 17 Sep 2009 20:48:11 GMT</pubDate>
      <description>&lt;p&gt;
In mehreren Artikeln wurde bereits beschrieben, wie LookupForms erstellt werden müssen,
um alle Funktionen bereit zu stellen, die auch durch einen Standard-Lookup bereit
gestellt werden.
&lt;/p&gt;
&lt;p&gt;
Ein guter &lt;a href="http://axaptapedia.com/Lookup_Form"&gt;Artikel&lt;/a&gt; ist zum Beispiel
auf &lt;a href="http://axaptapedia.com"&gt;Axaptapedia&lt;/a&gt; zu finden:&lt;br&gt;
&lt;a href="http://axaptapedia.com/Lookup_Form"&gt;http://axaptapedia.com/Lookup_Form&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Leider wurde in diesem Artikel auf eine Kleinigkeit nicht hingewiesen, die allerdings
für sehr viel Verwirrung sorgen kann.
&lt;/p&gt;
&lt;p&gt;
Um beim Öffnen des Lookups den bereits eingetragenen Wert zu selektieren (in dem Control
der aufrufenden Maske), müssen wie in dem Artikel beschrieben, die Methoden „executeQuery“
und „init“ der DataSource der Lookup-Maske überschrieben werden.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; executeQuery()
{ FormStringControl callerControl = SysTableLookup::getCallerStringControl(element.args());
; super(); xyz_ds.findValue(fieldnum(xyz,id),callerControl.text()); } &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; init()
{ Query q = &lt;span class=kwrd&gt;new&lt;/span&gt; Query(); QueryBuildDataSource qbds; ; super();
qbds = q.addDataSource(tablenum(xyz)); qbds.orderMode(OrderMode::OrderBy); qbds.addSortField(fieldNum(xyz,some_other_field)); &lt;span class=kwrd&gt;this&lt;/span&gt;.query(q);
} &lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Es wird auch beschrieben, dass in der Methode “init” der Datasource eigene Ranges
oder Sortings definiert werden können.&lt;br&gt;
Dies ist soweit auch richtig, allerdings mit einer Ausnahme.
&lt;/p&gt;
&lt;p&gt;
Wird auf dem Feld, welches bei dem Aufruf von „Datasource.findValue“ in der Methode
„init“ angegeben wurde (sollte auch immer das Feld sein, dessen Wert durch den Lookup
ausgewählt wird), eine Range definiert, so funktioniert die Selektion des zuvor gewählten
Wertes nicht mehr und es wird immer der erste Wert im Lookup selektiert bzw. ausgewählt.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; executeQuery()
{ FormStringControl callerControl = SysTableLookup::getCallerStringControl(element.args());
; super(); xyz_ds.findValue(fieldnum(xyz,id),callerControl.text()); } &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; init()
{ Query q = &lt;span class=kwrd&gt;new&lt;/span&gt; Query(); QueryBuildDataSource qbds; QueryBuildRange
range; ; super(); qbds = q.addDataSource(tablenum(xyz)); qbds.orderMode(OrderMode::OrderBy);
qbds.addSortField(fieldNum(xyz,some_other_field)); range = qbds.addRange(fieldnum(xyz,id));
range.&lt;span class=kwrd&gt;value&lt;/span&gt;(SysQuery::valueNot(&amp;lt;someValue&amp;gt;)); &lt;span class=kwrd&gt;this&lt;/span&gt;.query(q);
} &lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Dieses Verhalten lässt sich allerdings umgehen, wenn anstelle des Aufrufs von “DataSource.findValue”
in der „ExecuteQuery“ Methode der DataSource der Aufruf von „DataSoucre.findRecord“
verwendet wird.&lt;br&gt;
Hierfür muss aber der entsprechende Datensatz des zuvor oder bereits ausgewählten
Wertes ermittelt werden um diesen beim Aufruf von „DataSource.findRecord“ als Parameter
zu übergeben.
&lt;/p&gt;
&lt;p&gt;
Beispiel:&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; executeQuery()
{ FormStringControl callerControl; Xyz xyzRecord; ; callerControl = SysTableLookup::getCallerStringControl(element.args());
xyzRecord = Xyz::find(callerControl.text()); super(); xyz_ds.findRecord(xyzRecord);
} &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; init() { Query q = &lt;span class=kwrd&gt;new&lt;/span&gt; Query();
QueryBuildDataSource qbds; QueryBuildRange range; ; super(); qbds = q.addDataSource(tablenum(xyz));
qbds.orderMode(OrderMode::OrderBy); qbds.addSortField(fieldNum(xyz,some_other_field));
range = qbds.addRange(fieldnum(xyz,id)); range.&lt;span class=kwrd&gt;value&lt;/span&gt;(SysQuery::valueNot(&amp;lt;someValue&amp;gt;)); &lt;span class=kwrd&gt;this&lt;/span&gt;.query(q);
}&lt;/pre&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Es muss also darauf geachtet werden, ob eine Einschränkung (Range) auf dem „ID-Feld“
benötigt wird oder nicht.
&lt;/p&gt;
&lt;p&gt;
Wird keine Einschränkung benötigt, kann, wie in dem Artikel auf Axaptapedia beschrieben,
mit „DataSource.findValue“ gearbeitet werden um den entsprechenden Datensatz zu selektieren.&lt;br&gt;
Wird aber eine solche Einschränkung benötigt, muss mit „DataSoucre.findRecord“ gearbeitet
werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=337a6675-9f17-45f8-b620-c47081ec4e8e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,337a6675-9f17-45f8-b620-c47081ec4e8e.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=35934578-3dff-4555-b3d3-8ca2338ca6ed</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,35934578-3dff-4555-b3d3-8ca2338ca6ed.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,35934578-3dff-4555-b3d3-8ca2338ca6ed.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=35934578-3dff-4555-b3d3-8ca2338ca6ed</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wie schon die erste Auflage des Buches „Inside Dynamics AX“ ist dieses Buch eine sehr
gute Ergänzung zu den von Microsoft angebotenen Schulungsunterlagen (Development 1-4). 
<br /><br />
Angefangen bei der Architektur, der Entwicklungsumgebung und –Tools, bis hin zu Code
Upgrades beschreibt dieses Buch alle Themen die für einen AX Entwickler von Bedeutung
sind.<br /><br />
Nicht nur alle neuen Features von Dynamics AX 2009, z.B. Dynamics AX Reporting Services
oder Workflows, sondern auch ältere Features wie z.B. das Application Integration
Framework (AIF), werden wesentlich detaillierter beschrieben als an anderen Stellen.<br /><br />
Leider gibt es auch Bereiche, die nicht so detailliert besprochen werden bzw. wo einige
Fragen nicht gänzlich beantwortet werden.<br />
Ein Beispiel hierfür ist die .NET Integration. Zwar wird der Business Connector ausreichend
beschrieben, aber das Thema CLR-Interoperability wird leider nur sehr knapp behandelt. 
<br /><br />
Einige Kapitel wurden im Vergleich zu der ersten Auflage des Buches gänzlich überarbeitet.<br />
Beispielhaft sei das Kapitel über Form Customizations genannt, welches komplett neu
geschrieben wurde.<br /><br />
Leider hat dies auch zur Folge, dass einige sehr gut Beschriebene Themen, wie Beispielweise
das dynamische Anpassungen von Masken mit X++,<br />
jetzt nicht mehr behandelt werden.<br /><br />
Was dieses Buch aber nicht beschreibt oder behandelt, sind die Klassen, Tabellen,
API‘s, etc. des Microsoft Dynamics AX Standards.<br />
Dies würde allerdings auch den Rahmen des Buches mehr als sprengen.<br /><br />
In der Gesamtbetrachtung ist die neue Auflage von Inside Microsoft Dynamics AX eins
der besten technischen Bücher über Microsoft Dynamics AX.<br />
Kein Buch geht soweit in die Tiefe wie dieses. Egal ob Anfänger oder erfahrener Entwickler,
für jeden ist etwas dabei.<br /><br />
Auch wer schon die erste Auflage von Inside Microsoft Dynamics AX gelesen hat, wird
viele neue Themen finden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35934578-3dff-4555-b3d3-8ca2338ca6ed" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Inside Microsoft Dynamics AX 2009 &amp;ndash; Rezension</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,35934578-3dff-4555-b3d3-8ca2338ca6ed.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,35934578-3dff-4555-b3d3-8ca2338ca6ed.aspx</link>
      <pubDate>Thu, 30 Jul 2009 12:28:50 GMT</pubDate>
      <description>&lt;p&gt;
Wie schon die erste Auflage des Buches „Inside Dynamics AX“ ist dieses Buch eine sehr
gute Ergänzung zu den von Microsoft angebotenen Schulungsunterlagen (Development 1-4). 
&lt;br&gt;
&lt;br&gt;
Angefangen bei der Architektur, der Entwicklungsumgebung und –Tools, bis hin zu Code
Upgrades beschreibt dieses Buch alle Themen die für einen AX Entwickler von Bedeutung
sind.&lt;br&gt;
&lt;br&gt;
Nicht nur alle neuen Features von Dynamics AX 2009, z.B. Dynamics AX Reporting Services
oder Workflows, sondern auch ältere Features wie z.B. das Application Integration
Framework (AIF), werden wesentlich detaillierter beschrieben als an anderen Stellen.&lt;br&gt;
&lt;br&gt;
Leider gibt es auch Bereiche, die nicht so detailliert besprochen werden bzw. wo einige
Fragen nicht gänzlich beantwortet werden.&lt;br&gt;
Ein Beispiel hierfür ist die .NET Integration. Zwar wird der Business Connector ausreichend
beschrieben, aber das Thema CLR-Interoperability wird leider nur sehr knapp behandelt. 
&lt;br&gt;
&lt;br&gt;
Einige Kapitel wurden im Vergleich zu der ersten Auflage des Buches gänzlich überarbeitet.&lt;br&gt;
Beispielhaft sei das Kapitel über Form Customizations genannt, welches komplett neu
geschrieben wurde.&lt;br&gt;
&lt;br&gt;
Leider hat dies auch zur Folge, dass einige sehr gut Beschriebene Themen, wie Beispielweise
das dynamische Anpassungen von Masken mit X++,&lt;br&gt;
jetzt nicht mehr behandelt werden.&lt;br&gt;
&lt;br&gt;
Was dieses Buch aber nicht beschreibt oder behandelt, sind die Klassen, Tabellen,
API‘s, etc. des Microsoft Dynamics AX Standards.&lt;br&gt;
Dies würde allerdings auch den Rahmen des Buches mehr als sprengen.&lt;br&gt;
&lt;br&gt;
In der Gesamtbetrachtung ist die neue Auflage von Inside Microsoft Dynamics AX eins
der besten technischen Bücher über Microsoft Dynamics AX.&lt;br&gt;
Kein Buch geht soweit in die Tiefe wie dieses. Egal ob Anfänger oder erfahrener Entwickler,
für jeden ist etwas dabei.&lt;br&gt;
&lt;br&gt;
Auch wer schon die erste Auflage von Inside Microsoft Dynamics AX gelesen hat, wird
viele neue Themen finden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35934578-3dff-4555-b3d3-8ca2338ca6ed" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,35934578-3dff-4555-b3d3-8ca2338ca6ed.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=77377305-e7da-4288-a90b-0e32ac3aad0d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,77377305-e7da-4288-a90b-0e32ac3aad0d.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,77377305-e7da-4288-a90b-0e32ac3aad0d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=77377305-e7da-4288-a90b-0e32ac3aad0d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wird die Eigenschaft(Property) “AllowEditOnCreate” eines Tabellenfeldes auf den Wert
“No” gesetzt, ist es nicht möglich,<br />
Werte für dieses Tabellenfeld über das AIF (Application Integration Framework) zu
schreiben (Insert-Operation).
</p>
        <p>
Alle Tabellenfelder, welche diese Eigenschaft auf “No” gesetzt haben, werden durch
das AIF automatisch auf deren Default-Wert gesetzt und jegliche Wert der AIF Nachricht
werden ignoriert.<br />
Dies hat zur Folge, dass wenn das Tabellenfeld kein Enum ist, das Tabellenfeld immer
leer ist.
</p>
        <p>
Da dieser Automatismus schon vor Ausführung der AX&lt;Table&gt; Klasse greift, der
Wert also schon beim Ausführen der entsprechenden Parm-Methode “leer” ist,<br />
kann dieses Verhalten ohne Änderung der AIF-Basis Klassen nicht geändert werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=77377305-e7da-4288-a90b-0e32ac3aad0d" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Tabellenfeldeigenschaft AllowEditOnCreate und das Application Integration Framework</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,77377305-e7da-4288-a90b-0e32ac3aad0d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,77377305-e7da-4288-a90b-0e32ac3aad0d.aspx</link>
      <pubDate>Wed, 29 Jul 2009 23:09:08 GMT</pubDate>
      <description>&lt;p&gt;
Wird die Eigenschaft(Property) “AllowEditOnCreate” eines Tabellenfeldes auf den Wert
“No” gesetzt, ist es nicht möglich,&lt;br&gt;
Werte für dieses Tabellenfeld über das AIF (Application Integration Framework) zu
schreiben (Insert-Operation).
&lt;/p&gt;
&lt;p&gt;
Alle Tabellenfelder, welche diese Eigenschaft auf “No” gesetzt haben, werden durch
das AIF automatisch auf deren Default-Wert gesetzt und jegliche Wert der AIF Nachricht
werden ignoriert.&lt;br&gt;
Dies hat zur Folge, dass wenn das Tabellenfeld kein Enum ist, das Tabellenfeld immer
leer ist.
&lt;/p&gt;
&lt;p&gt;
Da dieser Automatismus schon vor Ausführung der AX&amp;lt;Table&amp;gt; Klasse greift, der
Wert also schon beim Ausführen der entsprechenden Parm-Methode “leer” ist,&lt;br&gt;
kann dieses Verhalten ohne Änderung der AIF-Basis Klassen nicht geändert werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=77377305-e7da-4288-a90b-0e32ac3aad0d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,77377305-e7da-4288-a90b-0e32ac3aad0d.aspx</comments>
      <category>Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=43c4e152-1290-400d-a404-8f4f16cf195c</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,43c4e152-1290-400d-a404-8f4f16cf195c.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,43c4e152-1290-400d-a404-8f4f16cf195c.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=43c4e152-1290-400d-a404-8f4f16cf195c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Egal ob Anfänger oder schon erfahrener Dynamics AX Entwickler.<br />
Von Zeit zu Zeit tauchen immer die gleichen Fragen und/oder Problemstellungen auf.
</p>
        <p>
Was immer mal wieder in Foren oder Newsgroups zu lesen ist, ist die Frage, wie die
Berechnung des Artikelpreises für eine Debitor mit X++ Code durchgeführt werden kann.<br />
Der Standard von Microsoft Dynamics AX bringt zwar eine Maske zur “Preisabfrage” mit
sich, welche diese Problemstellung eigentlich schon löst, allerdings ist es manchmal<br />
notwendig, die Preisberechnung z.B. in einer Klasse durchzuführen, um mit dem Ergebnis
weitere Operationen durchführen zu können.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/PreisberechnungeninMicrosoftDynamicsAX_10349/Maske_Preise.jpg" target="_blank">
            <img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Maske zur Preisberechnung" border="0" alt="Maske zur Preisberechnung" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/PreisberechnungeninMicrosoftDynamicsAX_10349/Maske_Preise_thumb.jpg" width="244" height="127" />
          </a>
        </p>
        <p>
Da in Dynamics AX Preise für einen Artikel nicht nur “direkt” im Artikelstamm, sondern
auch in den Handelsvereinbarungen, hinterlegt werden können, stellt der Standard von<br />
Dynamics AX die Klasse “PriceDisc” zur Verfügung, welche alle Möglichkeiten der Preispflege
berücksichtig.<br />
Unter Anderem werden auch Rabatte bzw. Zuschläge der Handelsvereinbarungen durch diese
Klasse berücksichtigt.
</p>
        <p>
Die Klasse “PriceDisc” stellt die statische Methode “actualSalesPriceDisc” bereit.
Mit dieser können z.B. der Verkaufspreis pro Preiseinheit, der Rabatt oder die Zuschläge<br />
berechnet und/oder ermittelt werden.<br />
Durch eine zweite statische Methode “price2Amount” lässt sich anschließend der Nettobetrag
eines Artikels ausrechnen.
</p>
        <p>
Beispiel:<br /></p>
        <div class="csharpcode">
          <pre class="alt">CustTable               custTable = CustTable::find(<span class="str">"5010"</span>);</pre>
          <pre>InventTable             inventTable = InventTable::find(<span class="str">"1000"</span>);</pre>
          <pre class="alt">Qty                     qty = 1.00;</pre>
          <pre> </pre>
          <pre class="alt">SalesPrice              salesPrice; <span class="rem">// Verkaufspreis
je Preiseinheit</span></pre>
          <pre>PriceMarkup             salesMarkup; <span class="rem">//Preis sonst. Zuschläge</span></pre>
          <pre class="alt">PriceUnit               priceUnit; <span class="rem">// Preiseinheit</span></pre>
          <pre>SalesLineDisc           salesLineDisc; <span class="rem">// Rabatt</span></pre>
          <pre class="alt">SalesLinePercent        salesLinePercent;</pre>
          <pre>DiscPct                 percent1;</pre>
          <pre class="alt">DiscPct                 percent2;</pre>
          <pre>PriceDiscTable          actualPrice; <span class="rem">// Gefundener Datensatz
der Handelsvereinbarung (Verkaufspreis)</span></pre>
          <pre class="alt">PriceDiscTable          actualDisc; <span class="rem">// Gefundener
Datensatz der Handelsvereinbarung (Rabatte)</span></pre>
          <pre>AmountCur               lineAmount; <span class="rem">// Nettobetrag</span></pre>
          <pre class="alt">;</pre>
          <pre>[salesPrice, salesMarkup, priceUnit,</pre>
          <pre class="alt"> salesLineDisc, salesLinePercent, percent1,</pre>
          <pre> percent2, actualPrice, actualDisc] = PriceDisc::actualSalesPriceDisc(custTable, inventTable, qty);</pre>
          <pre class="alt"> </pre>
          <pre>lineAmount = PriceDisc::price2Amount(salesPrice, priceUnit, salesLineDisc, qty,</pre>
          <pre class="alt">                                     qty, salesMarkup, salesLinePercent,</pre>
          <pre>                                     custTable.Currency, 0);</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=43c4e152-1290-400d-a404-8f4f16cf195c" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Preisberechnungen in Microsoft Dynamics AX</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,43c4e152-1290-400d-a404-8f4f16cf195c.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,43c4e152-1290-400d-a404-8f4f16cf195c.aspx</link>
      <pubDate>Wed, 29 Jul 2009 16:48:40 GMT</pubDate>
      <description>&lt;p&gt;
Egal ob Anfänger oder schon erfahrener Dynamics AX Entwickler.&lt;br&gt;
Von Zeit zu Zeit tauchen immer die gleichen Fragen und/oder Problemstellungen auf.
&lt;/p&gt;
&lt;p&gt;
Was immer mal wieder in Foren oder Newsgroups zu lesen ist, ist die Frage, wie die
Berechnung des Artikelpreises für eine Debitor mit X++ Code durchgeführt werden kann.&lt;br&gt;
Der Standard von Microsoft Dynamics AX bringt zwar eine Maske zur “Preisabfrage” mit
sich, welche diese Problemstellung eigentlich schon löst, allerdings ist es manchmal&lt;br&gt;
notwendig, die Preisberechnung z.B. in einer Klasse durchzuführen, um mit dem Ergebnis
weitere Operationen durchführen zu können.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/PreisberechnungeninMicrosoftDynamicsAX_10349/Maske_Preise.jpg" target=_blank&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Maske zur Preisberechnung" border=0 alt="Maske zur Preisberechnung" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/PreisberechnungeninMicrosoftDynamicsAX_10349/Maske_Preise_thumb.jpg" width=244 height=127&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Da in Dynamics AX Preise für einen Artikel nicht nur “direkt” im Artikelstamm, sondern
auch in den Handelsvereinbarungen, hinterlegt werden können, stellt der Standard von&lt;br&gt;
Dynamics AX die Klasse “PriceDisc” zur Verfügung, welche alle Möglichkeiten der Preispflege
berücksichtig.&lt;br&gt;
Unter Anderem werden auch Rabatte bzw. Zuschläge der Handelsvereinbarungen durch diese
Klasse berücksichtigt.
&lt;/p&gt;
&lt;p&gt;
Die Klasse “PriceDisc” stellt die statische Methode “actualSalesPriceDisc” bereit.
Mit dieser können z.B. der Verkaufspreis pro Preiseinheit, der Rabatt oder die Zuschläge&lt;br&gt;
berechnet und/oder ermittelt werden.&lt;br&gt;
Durch eine zweite statische Methode “price2Amount” lässt sich anschließend der Nettobetrag
eines Artikels ausrechnen.
&lt;/p&gt;
&lt;p&gt;
Beispiel:&lt;br&gt;
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;CustTable               custTable = CustTable::find(&lt;span class=str&gt;"5010"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;InventTable             inventTable = InventTable::find(&lt;span class=str&gt;"1000"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;Qty                     qty = 1.00;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;SalesPrice              salesPrice; &lt;span class=rem&gt;// Verkaufspreis
je Preiseinheit&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;PriceMarkup             salesMarkup; &lt;span class=rem&gt;//Preis sonst. Zuschläge&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;PriceUnit               priceUnit; &lt;span class=rem&gt;// Preiseinheit&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;SalesLineDisc           salesLineDisc; &lt;span class=rem&gt;// Rabatt&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;SalesLinePercent        salesLinePercent;&lt;/pre&gt;
&lt;pre&gt;DiscPct                 percent1;&lt;/pre&gt;
&lt;pre class=alt&gt;DiscPct                 percent2;&lt;/pre&gt;
&lt;pre&gt;PriceDiscTable          actualPrice; &lt;span class=rem&gt;// Gefundener Datensatz
der Handelsvereinbarung (Verkaufspreis)&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;PriceDiscTable          actualDisc; &lt;span class=rem&gt;// Gefundener Datensatz
der Handelsvereinbarung (Rabatte)&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;AmountCur               lineAmount; &lt;span class=rem&gt;// Nettobetrag&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;;&lt;/pre&gt;
&lt;pre&gt;[salesPrice, salesMarkup, priceUnit,&lt;/pre&gt;
&lt;pre class=alt&gt; salesLineDisc, salesLinePercent, percent1,&lt;/pre&gt;
&lt;pre&gt; percent2, actualPrice, actualDisc] = PriceDisc::actualSalesPriceDisc(custTable, inventTable, qty);&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;lineAmount = PriceDisc::price2Amount(salesPrice, priceUnit, salesLineDisc, qty,&lt;/pre&gt;
&lt;pre class=alt&gt;                                     qty, salesMarkup, salesLinePercent,&lt;/pre&gt;
&lt;pre&gt;                                     custTable.Currency, 0);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=43c4e152-1290-400d-a404-8f4f16cf195c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,43c4e152-1290-400d-a404-8f4f16cf195c.aspx</comments>
      <category>Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=38a9bff0-2bfd-492b-b323-9cb6f4750289</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,38a9bff0-2bfd-492b-b323-9cb6f4750289.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,38a9bff0-2bfd-492b-b323-9cb6f4750289.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=38a9bff0-2bfd-492b-b323-9cb6f4750289</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Die neue oder zweite Auflage von "Inside Mircosoft Dynamics AX" ist vor wenigen Tage
erschienen.
</p>
        <p>
          <a href="http://www.amazon.de/Inside-Microsoft-Dynamics%C2%AE-AX-2009/dp/0735626456/ref=sr_1_1?ie=UTF8&amp;s=books-intl-de&amp;qid=1245351262&amp;sr=8-1">Inside
Mircosoft Dynamics AX 2009</a>
        </p>
        <p>
Wie auch schon die erste Auflage des Buches, welche auf der Version 4.0 von Microsoft
Dynamics AX basierte, ist diese Buch in erster Linie für Entwickler gedacht.<br />
Die aktuelle Auflage umfasst gut 100 Seiten mehr als die erste Auflage und ist leider
auch im Preis etwas teurer.
</p>
        <p>
Weitere Informationen über den Inhalt können z.B. auf den Seiten von <a href="http://www.amazon.de/Inside-Microsoft-Dynamics%C2%AE-AX-2009/dp/0735626456/ref=sr_1_1?ie=UTF8&amp;s=books-intl-de&amp;qid=1245351262&amp;sr=8-1">Amazon</a> entnommen
werden.
</p>
        <p>
Es ist zu hoffen, dass sich diese Auflage auf gleichem Level wie die erste Auflage
bewegt und somit zu einem "Must-Have" oder "Must-Read" für AX Entwickler wird.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=38a9bff0-2bfd-492b-b323-9cb6f4750289" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Neues Buch - Inside Microsoft Dynamics AX 2009</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,38a9bff0-2bfd-492b-b323-9cb6f4750289.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,38a9bff0-2bfd-492b-b323-9cb6f4750289.aspx</link>
      <pubDate>Thu, 18 Jun 2009 18:56:05 GMT</pubDate>
      <description>&lt;p&gt;
Die neue oder zweite Auflage von "Inside Mircosoft Dynamics AX" ist vor wenigen Tage
erschienen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.amazon.de/Inside-Microsoft-Dynamics%C2%AE-AX-2009/dp/0735626456/ref=sr_1_1?ie=UTF8&amp;amp;s=books-intl-de&amp;amp;qid=1245351262&amp;amp;sr=8-1"&gt;Inside
Mircosoft Dynamics AX 2009&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Wie auch schon die erste Auflage des Buches, welche auf der Version 4.0 von Microsoft
Dynamics AX basierte, ist diese Buch in erster Linie für Entwickler gedacht.&lt;br&gt;
Die aktuelle Auflage umfasst gut 100 Seiten mehr als die erste Auflage und ist leider
auch im Preis etwas teurer.
&lt;/p&gt;
&lt;p&gt;
Weitere Informationen über den Inhalt können z.B. auf den Seiten von &lt;a href="http://www.amazon.de/Inside-Microsoft-Dynamics%C2%AE-AX-2009/dp/0735626456/ref=sr_1_1?ie=UTF8&amp;amp;s=books-intl-de&amp;amp;qid=1245351262&amp;amp;sr=8-1"&gt;Amazon&lt;/a&gt; entnommen
werden.
&lt;/p&gt;
&lt;p&gt;
Es ist zu hoffen, dass sich diese Auflage auf gleichem Level wie die erste Auflage
bewegt und somit zu einem "Must-Have" oder "Must-Read" für AX Entwickler wird.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=38a9bff0-2bfd-492b-b323-9cb6f4750289" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,38a9bff0-2bfd-492b-b323-9cb6f4750289.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=06d4c0c2-9748-4a05-bcae-0925f08fee2f</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,06d4c0c2-9748-4a05-bcae-0925f08fee2f.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,06d4c0c2-9748-4a05-bcae-0925f08fee2f.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=06d4c0c2-9748-4a05-bcae-0925f08fee2f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In dem Artikel "<a href="http://blog.ak-home.net/PermaLink,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx">Anzeige
von Lagerdimensionen auf Masken</a>" wurde bereits gezeigt, was zu tun ist, um
die Anzeige von Lagerdimensionen auf Masken dynamisch anpassen zu können bzw. das
Standardverhalten für die Anzeige von Lagerdimensionen zu implementieren.
</p>
        <p>
Manchmal soll eine ähnliche Funktionalität auch für Berichte bereit gestellt werden,
um zum Beispiel vor der Berichtserstellung auswählen zu können, welche Lagerdimensionen
auf dem Bericht(Report) angedruckt werden.<br />
Auch hierfür sind im Dynamics AX Standard die entsprechenden Funktionalitäten (oder
besser Klassen) bereits vorhanden, sodass diese nur verwendet werden müssen.
</p>
        <p>
Als Ausgangsbasis für den Bericht dient ebenfalls die Tabelle „AKU_DemoTable“.<br /><img border="0" src="http://blog.ak-home.net/content/binary/Tabelle.jpg" /></p>
        <p>
Der Bericht soll nun, die in dieser Tabelle gespeicherten Datensätze andrucken/ausgeben.<br /><img border="0" src="http://blog.ak-home.net/content/binary/Report.jpg" /></p>
        <p>
Wie bei Masken, muss auch für einen Bericht, die Query entsprechend um die Tabelle
InventDim ergänzt werden.<br />
Hierbei ist zu beachten, dass die Eigenschaften (Properties) „FetchMode“ auf „1:1“
und „Relations“ auf „Yes“ gesetzt werden.<br /><img border="0" src="http://blog.ak-home.net/content/binary/Report_Datasource_Properties.jpg" /></p>
        <p>
Als nächstes muss nun, ebenfalls analog zu dem Vorgehen bei Masken, die Feldgruppe
„InventoryDimensions“ in den Designzweig des Reports aufgenommen werden.<br />
Beispielhaft wird diese in einem Body-Element erstellt.<br /><img border="0" src="http://blog.ak-home.net/content/binary/Report_Body.jpg" /></p>
        <p>
Nun müssen noch einige Anpassungen an den Methoden des Berichts durchgeführt werden,
damit das gewünschte Ergebnis erreicht werden kann.<br />
Bezogen auf die Möglichkeit, die zu druckenden Lagerdimensionen bestimmen zu können,
müssen die Methoden „classDeclaration“, „run“, „dialog“ und „getFromDialog“ wie folgt
überschrieben werden.<br />
Auch das Überschreiben der Methoden „pack“ und „unpack“ ist hilfreich (für die Lagerdimensionsanzeige
nicht zwingend erforderlich), da über diese die Speicherung der „Nutzungsdaten“ realisiert
wird.
</p>
        <p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">class</span> ReportRun
extends ObjectRun<br />
{<br />
   InventDimParm inventDimParm;<br />
   DialogRunbase dialog;<br />
   DialogGroup dialogInventoryDimensions;<br /><br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   #define</span>.CurrentVersion(1)<br />
   #localmacro.CurrentList<br />
      inventDimParm<br />
   #endmacro<br />
}</span>
        </p>
        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
          <p>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> updateDesign()<br />
{<br />
   ;<br />
   InventDimCtrl::updateReportVisible(element, inventDimParm);<br />
}</span>
          </p>
          <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
            <p>
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span>
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">void</span> run()<br />
{<br />
   ;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   this</span>.updateDesign();<br />
   super();<br />
}</span>
            </p>
            <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
              <p>
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                  <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span> Object
dialog(Object _dialog)<br />
{<br />
   ;<br />
   dialog <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> _dialog;<br />
   dialogInventoryDimensions <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> inventDimParm.addFieldsToDialog(dialog,<span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@SYS53654"</span>,<span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>, <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">false</span>, <span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px">"@SYS102592"</span>);<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   return</span> dialog;<br />
}</span>
              </p>
              <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                <p>
                  <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span> boolean
getFromDialog()<br />
{<br />
   ;<br />
   inventDimParm.getFromDialog(dialog, dialogInventoryDimensions);<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   return</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>;<br />
}</span>
                </p>
                <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                  <p>
                    <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                      <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span> container
pack()<br />
{<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   return</span> [#CurrentVersion,
#CurrentList];<br />
}</span>
                  </p>
                  <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                    <p>
                      <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px">
                        <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">public</span> boolean
unpack(container packedClass)<br />
{<br />
   Version version <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> RunBase::getVersion(packedClass);<br />
   ;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   switch</span>(version)<br />
   {<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">      case</span> #CurrentVersion:<br />
         [version,#CurrentList] <span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px">=</span> packedClass;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">         break</span>;<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">      default</span>:<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">         return</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">false</span>;<br />
   }<br /><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">   return</span><span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px">true</span>;<br />
}</span>
                    </p>
                  </span>
                </span>
              </span>
            </span>
          </span>
        </span>
        <p>
Wird nun der Bericht geöffnet, zum Beispiel über ein MenuItem, kann in einem Dialog
ausgewählt werden, welche Lagerdimensionen auf dem Report angedruckt werden sollen.<br /></p>
        <p>
          <img border="0" src="http://blog.ak-home.net/content/binary/Report_Dialog.jpg" />
        </p>
        <p>
Der ausgegebene Bericht(Report) sieht, unter Berücksichtigung der im Dialog gewählten
Einstellungen, wie folgt aus.<br /><img border="0" src="http://blog.ak-home.net/content/binary/Report_Ausgabe.jpg" /></p>
        <p>
Das vorgestellt Bespiel steht <a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimRep.rar"><font color="#000099">hier</font></a> als
Download bereit um die einzelnen Schritte genau ansehen/nachvollziehen zu können.<br /></p>
        <a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimRep.rar">AKU_Demo_InventDimRep.rar
(1,99 KB)</a>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=06d4c0c2-9748-4a05-bcae-0925f08fee2f" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Anzeige von Lagerdimensionen auf Berichten</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,06d4c0c2-9748-4a05-bcae-0925f08fee2f.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,06d4c0c2-9748-4a05-bcae-0925f08fee2f.aspx</link>
      <pubDate>Sat, 04 Apr 2009 17:24:53 GMT</pubDate>
      <description>&lt;p&gt;
In dem&amp;nbsp;Artikel "&lt;a href="http://blog.ak-home.net/PermaLink,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx"&gt;Anzeige
von Lagerdimensionen auf Masken&lt;/a&gt;"&amp;nbsp;wurde bereits gezeigt, was zu tun ist, um
die Anzeige von Lagerdimensionen auf Masken dynamisch anpassen zu können bzw. das
Standardverhalten für die Anzeige von Lagerdimensionen zu implementieren.
&lt;/p&gt;
&lt;p&gt;
Manchmal soll eine ähnliche Funktionalität auch für Berichte bereit gestellt werden,
um zum Beispiel vor der Berichtserstellung auswählen zu können, welche Lagerdimensionen
auf dem Bericht(Report)&amp;nbsp;angedruckt werden.&lt;br&gt;
Auch hierfür sind im Dynamics AX Standard die entsprechenden Funktionalitäten (oder
besser Klassen) bereits vorhanden, sodass diese nur verwendet werden müssen.
&lt;/p&gt;
&lt;p&gt;
Als Ausgangsbasis für den Bericht dient ebenfalls die Tabelle „AKU_DemoTable“.&lt;br&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Tabelle.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Der Bericht soll nun, die in dieser Tabelle gespeicherten Datensätze andrucken/ausgeben.&lt;br&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Report.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Wie bei Masken, muss auch für einen Bericht, die Query entsprechend um die Tabelle
InventDim ergänzt werden.&lt;br&gt;
Hierbei ist zu beachten, dass die Eigenschaften (Properties) „FetchMode“ auf „1:1“
und „Relations“ auf „Yes“ gesetzt werden.&lt;br&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Report_Datasource_Properties.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Als nächstes muss nun, ebenfalls analog zu dem Vorgehen bei Masken, die Feldgruppe
„InventoryDimensions“ in den Designzweig des Reports aufgenommen werden.&lt;br&gt;
Beispielhaft wird diese in einem Body-Element erstellt.&lt;br&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Report_Body.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Nun müssen noch einige Anpassungen an den Methoden des Berichts durchgeführt werden,
damit das gewünschte Ergebnis erreicht werden kann.&lt;br&gt;
Bezogen auf die Möglichkeit, die zu druckenden Lagerdimensionen bestimmen zu können,
müssen die Methoden „classDeclaration“, „run“, „dialog“ und „getFromDialog“ wie folgt
überschrieben werden.&lt;br&gt;
Auch das Überschreiben der Methoden „pack“ und „unpack“ ist hilfreich (für die Lagerdimensionsanzeige
nicht zwingend erforderlich), da über diese die Speicherung der „Nutzungsdaten“ realisiert
wird.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;class&lt;/span&gt; ReportRun
extends ObjectRun&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;InventDimParm inventDimParm;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;DialogRunbase dialog;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;DialogGroup dialogInventoryDimensions;&lt;br&gt;
&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;#define&lt;/span&gt;.CurrentVersion(1)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;#localmacro.CurrentList&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inventDimParm&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;#endmacro&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; updateDesign()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;InventDimCtrl::updateReportVisible(element, inventDimParm);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;void&lt;/span&gt; run()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/span&gt;.updateDesign();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;super();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; Object
dialog(Object _dialog)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;dialog &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; _dialog;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;dialogInventoryDimensions &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; inventDimParm.addFieldsToDialog(dialog,&lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@SYS53654"&lt;/span&gt;,&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;false&lt;/span&gt;, &lt;span style="BACKGROUND-COLOR: #e4e4e4; FONT-FAMILY: Courier New; COLOR: #666666; FONT-SIZE: 11px"&gt;"@SYS102592"&lt;/span&gt;);&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; dialog;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; boolean
getFromDialog()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;inventDimParm.getFromDialog(dialog, dialogInventoryDimensions);&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; container
pack()&lt;br&gt;
{&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; [#CurrentVersion,
#CurrentList];&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt; 
&lt;p&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 11px"&gt;&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;public&lt;/span&gt; boolean
unpack(container packedClass)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Version version &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; RunBase::getVersion(packedClass);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&lt;/span&gt;(version)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&lt;/span&gt; #CurrentVersion:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[version,#CurrentList] &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: red; FONT-SIZE: 11px"&gt;=&lt;/span&gt; packedClass;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;/span&gt;;&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default&lt;/span&gt;:&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;false&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; &lt;span style="BACKGROUND-COLOR: transparent; FONT-FAMILY: Courier New; COLOR: blue; FONT-SIZE: 11px"&gt;true&lt;/span&gt;;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
&lt;p&gt;
Wird nun der Bericht geöffnet, zum Beispiel über ein MenuItem, kann in einem Dialog
ausgewählt werden, welche Lagerdimensionen auf dem Report angedruckt werden sollen.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Report_Dialog.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Der ausgegebene Bericht(Report) sieht, unter Berücksichtigung der im Dialog gewählten
Einstellungen, wie folgt aus.&lt;br&gt;
&lt;img border=0 src="http://blog.ak-home.net/content/binary/Report_Ausgabe.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Das vorgestellt Bespiel steht &lt;a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimRep.rar"&gt;&lt;font color=#000099&gt;hier&lt;/font&gt;&lt;/a&gt; als
Download bereit um die einzelnen Schritte genau ansehen/nachvollziehen zu können.&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimRep.rar"&gt;AKU_Demo_InventDimRep.rar
(1,99 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=06d4c0c2-9748-4a05-bcae-0925f08fee2f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,06d4c0c2-9748-4a05-bcae-0925f08fee2f.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung, Dynamics Ax/HowTo</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8</wfw:commentRss>
      <title>Anzeige von Lagerdimensionen auf Masken</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx</link>
      <pubDate>Fri, 13 Mar 2009 16:50:59 GMT</pubDate>
      <description>&lt;p&gt;
Im Standard von Microsoft Dynamics AX besteht auf jeder Maske, auf der Artikel und
deren Lagerdimensionen angezeigt werden, die Möglichkeit, die Lagerdimensionen, bzw.
die angezeigten Felder der Lagerdimensionen, über die Funktion "Lager-Dimensionenanzeige"
entsprechend zu steuern.
&lt;/p&gt;
&lt;p&gt;
Die einzelnen Elemente (Felder) der Lagerdimension können über diese Funktion ein-
bzw. ausgebledet werden.
&lt;/p&gt;
&lt;p&gt;
Weiterhin ist es auch möglich, durch Parametrisierung zu bestimmen, ob ein Feld einer
Lagerdimension eingeben werden muss (Mussfeld) oder ob überhaupt eine Eingabe möglich
ist.
&lt;/p&gt;
&lt;p&gt;
Ein gutes Beispiel hierfür ist die Maske "Aufträge".
&lt;/p&gt;
&lt;p&gt;
Wie ist es nun, wenn eine neue&amp;nbsp;Maske erstellt werden soll, welche Artikelinformation
und Lagerdimensionen anzeigen soll?&lt;br&gt;
Wie genau muss vorgegangen werden,&amp;nbsp;um die bereits an vielen Stellen im Standard
verwendete Funktionalität auch für die selbst erstellte Maske bereitzustellen?&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Gehen wir einmal davon aus, es wurde eine neue Tabelle erstellt, welche die Artikelnummer
(ItemId)&amp;nbsp;und die Lagerdimensionsnummer (InventDimId)&amp;nbsp;speichert.&lt;br&gt;
Für diese Tabelle soll eine Maske erstellt werden, úm dem Benutzer die Möglichkeit
zu geben, Datensätze zu erfassen, zu ändern oder einfach nur anzuzeigen.
&lt;/p&gt;
&lt;p&gt;
Dies könnte z.B. so aussehen:&lt;br&gt;
&lt;img src="http://blog.ak-home.net/content/binary/CreateTableAndForm.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Um nun die Funktion der Lagerdimensionensteuerung einzubauen muss zuerst die Tabelle
InventDim als DataSource der Maske hinzugefügt werden.&lt;br&gt;
Anschließend müssen die Eigenschaften (Properties)&amp;nbsp;der DataSource noch auf folgende
Werte geändert werden.
&lt;/p&gt;
&lt;p&gt;
&lt;table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-yfti-tbllook: 1184; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt" cellspacing=0 cellpadding=0 border=1&gt;
&lt;tbody&gt;
&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;Name&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InventDim&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;JoinSource&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;Haupt-Datenquelle (hier: AKUDemoTable)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 2"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;LinkType&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InnerJoin&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 3"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;DelayActive&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;No&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 4"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InsertAtEnd&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;No&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 5; mso-yfti-lastrow: yes"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InsertIfEmpty&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;No&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/InventDimProperties.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Nun muss&amp;nbsp;eine neue ButtonGroup (Name: "Inventory") im Designzweig der Maske erstellt
werden. Diese sollte das LAbel "Lager" zugewiesen werden.&lt;br&gt;
Nun noch das MenuItem "InventDimParmFixed" in diese ButtonGroup ziehen (z.B. per drag
&amp;amp; drop aus dem AOT) und dem so erstellten MenuItemButton folgende Eigenschaften
zuweisen.
&lt;/p&gt;
&lt;p&gt;
&lt;table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-yfti-tbllook: 1184; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt" cellspacing=0 cellpadding=0 border=1&gt;
&lt;tbody&gt;
&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;Name&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InventDimParmFixed&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;MenuItemName&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;InventDimParmFixed&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 2; mso-yfti-lastrow: yes"&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: black 1pt solid; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;DataSource&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ebe9ed; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ebe9ed; WIDTH: 230.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; mso-border-bottom-themecolor: text1; mso-border-right-themecolor: text1" valign=top width=307&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal"&gt;
&lt;font color=#000000&gt;&lt;font face=Calibri&gt;Haupt-Datenquelle (hier: AKUDemoTable)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/MenuItemButtonInventDimParmFixed.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Über das MenuItem (oder genauer über den erstellten MenuItemButton) wird nun wie im
Standard, die Maske "Lagerdimensionen" zu öffnen.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/FormWithDimSelection.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Allerdings öffnet sich die Maske „Lagerdimensionen“ noch nicht wie gewünscht über
den MenuItemButton. Hierfür sind noch weitere Anpassungen notwendig.
&lt;/p&gt;
&lt;p&gt;
Damit sich die Maske „Lagerdimensionen“ wie gewünscht öffnet muss die neue Maske die
Methode „inventDimSetupObject“ implementieren welche eine Instanz von „InventDimCtrl_Frm“
zurück gibt.
&lt;/p&gt;
&lt;p&gt;
Die Klasse „InventDimCtrl_Frm“, bzw. eine der von ihr abgeleiteten Klassen, steuert
z.B. welche Lagerdimensionen für den aktuellen Datensatz zulässig sind oder welche
Dimensionen für den aktuellen Datensatz angegeben werden müssen, damit dieser gespeichert
werden kann.
&lt;/p&gt;
&lt;p&gt;
Da über die Parametrisierung der Lagersteuerungsgruppen und der Modulparameter hierfür
durchaus unterschiedliche Einstellungen gewählt werden können, sind in Dynamics AX
etliche Ableitungen dieser Klasse vorhanden (jede wird für eine oder mehrere andere
Masken verwendet).
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/InventDimCtrl_Frm.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Je nachdem, was für eine Funktionalität bzw. was für ein Business-Prozess erstellt
werden soll, kann entweder eine der bereits im Standard vorhandenen Klassen verwendet
werden oder es muss eine neue Klasse geschrieben werden, um die benötigte Funktionalität
zu liefern (z.B. welche Dimensionen immer angezeigt werden müssen).
&lt;/p&gt;
&lt;p&gt;
Das Erstellen einer neuen Klasse, welche von „InventDimCtrl_Frm“ abgeleitet&amp;nbsp;
ist, ist recht einfach.
&lt;/p&gt;
&lt;p&gt;
Es sollte immer die Methode „new“ überschrieben werden und mindestens die statischen
Methoden „construct“ und „newFromForm“ erstellt werden. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; AKUInventDimCtrl_Frm_Demo
extends InventDimCtrl_Frm&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt;()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; super();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; AKUInventDimCtrl_Frm_Demo
construct()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; AKUInventDimCtrl_Frm_Demo();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; AKUInventDimCtrl_Frm_Demo
newFromForm(FormRun _formRun)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; AKUInventDimCtrl_Frm_Demo inventDimCtrl &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; AKUInventDimCtrl_Frm_Demo::construct();&lt;br&gt;
&amp;nbsp; InventDimAxFormAdapter adapter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; InventDimAxFormAdapter::newFromForm(_formRun);&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; inventDimCtrl.parmCallingElement(adapter);&lt;br&gt;
&amp;nbsp; inventDimCtrl.init();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; inventDimCtrl;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Weiterhin können noch andere Methoden überschrieben werden, um z.B. zu steuern, welche
Felder der Tabelle „InventDim“ beim Aufruf der Maske angezeigt werden sollen.&lt;br&gt;
Weitere Informationen hierzu sind im Microsoft Dynamics AX Developer Center zu finden: &lt;a href="http://msdn.microsoft.com/en-us/library/cc618009.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc618009.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;NoYes
mustShowGridField(fieldId _dimFieldId)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; NoYes ret;&lt;br&gt;
&lt;br&gt;
&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; super(_dimFieldId);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
//always show InventLocationId in Grid&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
if&lt;/span&gt;(_dimfieldId == fieldnum(InventDim, InventLocationId))&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; NoYes::Yes;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; ret;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Wie zuvor beschrieben muss nun die Methode „inventDimSetupObject“ auf der Maske implementiert
werden. Das diese eine Instanz von „InventDimCtrl_Frm“ zurück geben muss, ist diese
ebenfalls zu erzeugen. Als erstes muss eine Objektvariable für das „InventDimCtrl_Frm“
Objekt erstellt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; FormRun
extends ObjectRun&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; InventDimCtrl_Frm inventDimFormSetup;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Anschließend kann die Methode „inventDimSetupObject“ erstellt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Object
inventDimSetupObject()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; inventDimFormSetup;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Da die Objektvariable durch diesen Quelltext noch nicht initialisiert wird, muss noch
entsprechender Code zur Initialisierung geschrieben werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; updateDesign(InventDimFormDesignUpdate
mode)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; inventDimParm inventDimParmShow;&lt;br&gt;
&amp;nbsp; inventDimParm inventDimParmEnabled;&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
switch&lt;/span&gt; (mode)&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
case&lt;/span&gt; InventDimFormDesignUpdate::Init :&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (!inventDimFormSetup)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; AKUInventDimCtrl_Frm_Demo::newFromForm(element);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup.parmSkipOnHandLookUp(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
case&lt;/span&gt; InventDimFormDesignUpdate::Active :&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup.formActiveSetup(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventTable::find(AKUDemoTable.ItemId).dimGroupId);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup.formSetControls(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
break&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
case&lt;/span&gt; InventDimFormDesignUpdate::FieldChange :&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup.formActiveSetup(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventTable::find(AKUDemoTable.ItemId).dimGroupId);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDim.clearNotSelectedDim(inventDimFormSetup.parmDimParmEnabled());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventDimFormSetup.formSetControls(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
break&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
default&lt;/span&gt; :&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
throw&lt;/span&gt; error(strfmt(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@SYS54195"&lt;/span&gt;,funcname()));&lt;br&gt;
&amp;nbsp; } 
&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; init()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; super();&lt;br&gt;
&amp;nbsp; element.updateDesign(InventDimFormDesignUpdate::Init);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Da die Logik, welche durch die Methode „updateDesign“ bereit gestellt wird, mehrfach
benötigt wird, erfolgt die Initialisierung des „InventDimCtrl_Frm“ Objekts nicht direkt
in der „init“ Methode.
&lt;/p&gt;
&lt;p&gt;
Damit die in der Maske erstellten Datensätze auch richtig gespeichert werden können,
müssen nun noch einige weitere Anpassungen an den Methoden der Datenquellen vorgenommen
werden.&lt;br&gt;
&lt;br&gt;
Datasource „AKUDemoTable“ (Hauptdatenquelle):&lt;br&gt;
Hier sind die Methoden „write“, „validateWrite“ und „active“ zu überschreiben.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; write()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; ttsbegin;&lt;br&gt;
&lt;br&gt;
&amp;nbsp; AKUDemoTable.inventDimId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; InventDim::findOrCreate(InventDim).inventDimId;&lt;br&gt;
&lt;br&gt;
&amp;nbsp; super();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
if&lt;/span&gt;(AKUDemoTable.inventDimId !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; InventDim.inventDimId)&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; InventDim.data(InventDim::find(AKUDemoTable.inventDimId));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; InventDim_ds.setCurrent();&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp; ttscommit;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; boolean
validateWrite()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; boolean ret;&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; AKUDemoTable.InventDimId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; inventDim::findOrCreate(InventDim).inventDimId;&lt;br&gt;
&lt;br&gt;
&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; super();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; ret;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; active()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
int&lt;/span&gt; ret;&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; super();&lt;br&gt;
&lt;br&gt;
&amp;nbsp; element.updateDesign(InventDimFormDesignUpdate::Active);&lt;br&gt;
&lt;br&gt;
&amp;nbsp; inventDim_DS.active();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
return&lt;/span&gt; ret;&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;
&gt; 
&lt;p&gt;
Datasource „InventDim“:&lt;br&gt;
Hier müssen die Methoden „initValue“ und „write“ überschrieben werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; initValue()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; InventDim.data(InventDim::find(AKUDemoTable.inventDimId));&lt;br&gt;
&lt;br&gt;
&amp;nbsp; super();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; write()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
//super();&lt;/span&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Hierbei muss unbedingt beachtet werden, dass der „super“ Aufruf in der „write“ Methode
der Datasource „InventDim“ auskommentiert wird, um das Speichern von falschen InventDim
Datensätzen zu verhindern.
&lt;/p&gt;
&lt;p&gt;
Als letzte Methode sollte nun noch die Methode „modified“ des DataSource-Field „ItemId“
der Datasource „AKUDemoTable“ überschrieben werden, damit auf eine Änderung der Artikelnummer
reagiert werden kann (z.B. Artikelabhängige Anzeige der Lagerdimensionen).
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; modified()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; ;&lt;br&gt;
&amp;nbsp; super();&lt;br&gt;
&amp;nbsp; element.updateDesign(InventDimFormDesignUpdate::FieldChange);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Somit sind alle benötigten Quelltextanpassungen durchgeführt, sodass nur noch die
Feldgruppe „InventoryDimensions“ der DataSource „InventDim“ mit in das Grid gezogen
werden muss um die Lagerdimensionen auf der Maske anzuzeigen. Optional kann diese
auch in die TabPage „Dimensions“ gezogen werden um ein standardkonformes Aussehen
der Maske zu erhalten.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/FiledgorupInventoryDimensions.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Das vorgestellt Bespiel steht &lt;a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimFrm.rar"&gt;hier&lt;/a&gt; als
Download bereit um die einzelnen Schritte genau ansehen/nachvollziehen zu können.&lt;br&gt;
&lt;a href="http://blog.ak-home.net/content/binary/AKU_Demo_InventDimFrm.rar"&gt;AKU_Demo_InventDimFrm.rar
(2,71 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,3d8d3d4a-130a-4b2f-8a9e-1328ea6d50c8.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=24601242-7843-49f8-9fee-821f57ac7d55</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,24601242-7843-49f8-9fee-821f57ac7d55.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,24601242-7843-49f8-9fee-821f57ac7d55.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=24601242-7843-49f8-9fee-821f57ac7d55</wfw:commentRss>
      <title>Dynamics AX 2009 - Ungewollt den Sys Layer ändern</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,24601242-7843-49f8-9fee-821f57ac7d55.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,24601242-7843-49f8-9fee-821f57ac7d55.aspx</link>
      <pubDate>Wed, 11 Mar 2009 19:22:18 GMT</pubDate>
      <description>&lt;p&gt;
Leider scheint es ein Problem mit duplizierten Tabellen in Dynamics AX 2009 zu geben.&lt;br&gt;
Unter gewissen "Umständen" ist es möglich, Quelltext der in einem andern Layer (z.B.
CUS oder BUS) geschrieben wurde, in den SYS Layer zu "verschieben". 
&lt;/p&gt;
&lt;p&gt;
Dieser Verhalten ist sehr unschön, da viele Entwickler, z.B. für Testzwecke, mal ein
Objekt duplizieren, neuen Quelltext testen und anschließen diesen&amp;nbsp;auf das orginale
Objekt übernehmen oder verschieben. Leider taucht genau an dieser Stelle das Problem
auf (es kann sein, dass dieses "Verschieben" den Quelltext in den SYS Layer schreibt).
&lt;/p&gt;
&lt;p&gt;
Das genaue Verhalten ist in einem Video von "elranu"&amp;nbsp;auf YouTube beschrieben
(&lt;a href="http://www.youtube.com/watch?v=4HEwNyVAwtI"&gt;Link zum Video&lt;/a&gt;):
&lt;/p&gt;
&lt;p&gt;
&lt;object height=344 width=425&gt;
&lt;param name="movie" value="http://www.youtube.com/v/4HEwNyVAwtI&amp;amp;hl=de&amp;amp;fs=1"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;embed src="http://www.youtube.com/v/4HEwNyVAwtI&amp;hl=de&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;
In den Newsgroups ist auch ein entsprechender Thread zu finden: &lt;a href="http://www.microsoft.com/Businesssolutions/Community/NewsGroups/dgbrowser/en-us/default.mspx?&amp;amp;query=ax+2009+sys+layer&amp;amp;lang=en&amp;amp;cr=US&amp;amp;guid=&amp;amp;sloc=en-us&amp;amp;dg=microsoft.public.axapta.programming&amp;amp;p=1&amp;amp;tid=9165d668-001b-4d67-8f7c-10569306bbb7&amp;amp;mid=bd0fc4ff-701a-4bed-8c30-ef00687bfbc5"&gt;&lt;strong&gt;Ax
2009 bug in Sys L&lt;wbr&gt;ayer &lt;/strong&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=24601242-7843-49f8-9fee-821f57ac7d55" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,24601242-7843-49f8-9fee-821f57ac7d55.aspx</comments>
      <category>Dynamics Ax;Dynamics AX/Dynamics AX 2009;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=dcaffcda-fd12-4fec-984d-97ded22c5517</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,dcaffcda-fd12-4fec-984d-97ded22c5517.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,dcaffcda-fd12-4fec-984d-97ded22c5517.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=dcaffcda-fd12-4fec-984d-97ded22c5517</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.<br /><a href="http://www.microsoft.com/dynamics/ax/using/ax_combizconnector.mspx">The COM
Business Connector will be discontinued in future releases of Microsoft Dynamics AX</a></p>
        <p>
Bereits in der Version 2009 von Microsoft Dynamics AX wird der COM Business Connector
vom "normalen" Setup nicht mehr angeboten.<br />
Dieser muss manuell, wie im Microsoft Dynamics AX Developer Center beschrieben, nachinstalliert
werden.<br /><a href="http://msdn.microsoft.com/en-us/library/cc624322.aspx">How to: Install COM
Business Connector using Command-line Options</a></p>
        <p>
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.
</p>
        <p>
Alle benötigten Informationen über die Verwendung des .NET Business Connectors können
in der Library des Microsoft Dynamics AX Developer Centers gefunden werden<br /><a href="http://msdn.microsoft.com/en-us/library/aa659581.aspx">.NET Business Connector
Overview</a></p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=dcaffcda-fd12-4fec-984d-97ded22c5517" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX - Der COM Business Connector wird in zukünftigen Versionen nicht mehr unterstützt</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,dcaffcda-fd12-4fec-984d-97ded22c5517.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,dcaffcda-fd12-4fec-984d-97ded22c5517.aspx</link>
      <pubDate>Mon, 02 Mar 2009 19:21:05 GMT</pubDate>
      <description>&lt;p&gt;
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.&lt;br&gt;
&lt;a href="http://www.microsoft.com/dynamics/ax/using/ax_combizconnector.mspx"&gt;The COM
Business Connector will be discontinued in future releases of Microsoft Dynamics AX&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Bereits in der Version 2009 von Microsoft Dynamics AX wird der COM Business Connector
vom "normalen" Setup nicht mehr angeboten.&lt;br&gt;
Dieser muss manuell, wie im Microsoft Dynamics AX Developer Center beschrieben,&amp;nbsp;nachinstalliert
werden.&lt;br&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/cc624322.aspx"&gt;How to: Install COM
Business Connector using Command-line Options&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Alle benötigten Informationen über die Verwendung des .NET Business Connectors können
in der Library des Microsoft Dynamics AX Developer Centers gefunden werden&lt;br&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/aa659581.aspx"&gt;.NET Business Connector
Overview&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=dcaffcda-fd12-4fec-984d-97ded22c5517" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,dcaffcda-fd12-4fec-984d-97ded22c5517.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/Administration;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=514153a0-b0ff-4af7-b6f3-73645f99f656</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,514153a0-b0ff-4af7-b6f3-73645f99f656.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,514153a0-b0ff-4af7-b6f3-73645f99f656.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=514153a0-b0ff-4af7-b6f3-73645f99f656</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Oft ist in Newsgroups und Foren die Frage zu lesen, wie .NET (CLR) Arrays in X++ verwendet,
bzw. wie diese deklariert werden können.<br />
Im Großen und Ganzen unterscheidet sich die Syntax für die Verwendung eines .NET Array
kaum von der eines reinen X++ Array.<br />
.NET Arrays können in X++ sogar auf zwei verschiedene Arten deklariert werden.
</p>
        <p>
          <u>Variante 1:</u>
        </p>
        <p>
Die Deklaration eines .NET Arrays erfolgt analog zu der Deklaration eines "reinen"
X++ Arrays:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">System.Object[]
arrayOfObjects;<br />
System.Int32[] arrayOfIntegers;<br /><br /></span>
        </p>
        <p>
Die Syntax für die Instanzierung des .NET Array weicht allerdings leicht von der "normalen"
X++ Syntax ab:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">arrayOfObjects <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.Object[10]();<br />
arrayOfIntegers <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.Int32[3]();<br /><br /></span>
        </p>
        <p>
Wichtig ist hierbei, dass immer "()" verwendet wird.
</p>
        <p>
Um die Werte eines .NET Arrays zu setzen wird die Methode "SetValue()" verwendet:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">arrayOfObjects.SetValue(myObject,
0);<br />
arrayOfIntegers.SetValue(300, 1);<br /><br /></span>
        </p>
        <p>
Um Werte aus einem Array abzufragen kann die Methode "GetValue" verwendet werden:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">arrayOfObjects.GetValue(0);<br />
arrayOfIntegers.GetValue(1);<br /><br /></span>
        </p>
        <p>
Eine weitere sehr nützliche Methode ist die Methode "get_Length()". Diese liefert
die Anzahl der Array-Elemente zurück.
</p>
        <p>
          <u>Variante 2:</u>
        </p>
        <p>
Alternativ zur ersten Variante besteht noch die Möglichkeit, ein .NET Array über die
Klasse System.Array zu erzeugen.<br />
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.
</p>
        <p>
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.
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/cc557456.aspx">How to: Use X++ Syntax
for CLR Arrays</a>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=514153a0-b0ff-4af7-b6f3-73645f99f656" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX - X++ und .NET (CLR) Arrays </title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,514153a0-b0ff-4af7-b6f3-73645f99f656.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,514153a0-b0ff-4af7-b6f3-73645f99f656.aspx</link>
      <pubDate>Mon, 02 Mar 2009 18:40:39 GMT</pubDate>
      <description>&lt;p&gt;
Oft ist in Newsgroups und Foren die Frage zu lesen, wie .NET (CLR) Arrays in X++ verwendet,
bzw. wie diese deklariert werden können.&lt;br&gt;
Im Großen und Ganzen unterscheidet sich die Syntax für die Verwendung eines .NET Array
kaum von der eines reinen X++ Array.&lt;br&gt;
.NET Arrays können in X++ sogar auf zwei verschiedene Arten deklariert werden.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;Variante 1:&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Die Deklaration eines .NET Arrays erfolgt analog zu der Deklaration eines "reinen"
X++ Arrays:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;System.Object[]
arrayOfObjects;&lt;br&gt;
System.Int32[] arrayOfIntegers;&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Die Syntax für die Instanzierung des .NET Array weicht allerdings leicht von der "normalen"
X++ Syntax ab:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;arrayOfObjects &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.Object[10]();&lt;br&gt;
arrayOfIntegers &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.Int32[3]();&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Wichtig ist hierbei, dass immer "()" verwendet wird.
&lt;/p&gt;
&lt;p&gt;
Um die Werte eines .NET Arrays zu setzen wird die Methode "SetValue()" verwendet:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;arrayOfObjects.SetValue(myObject,
0);&lt;br&gt;
arrayOfIntegers.SetValue(300, 1);&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Um Werte aus einem Array abzufragen kann die Methode "GetValue" verwendet werden:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;arrayOfObjects.GetValue(0);&lt;br&gt;
arrayOfIntegers.GetValue(1);&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Eine weitere sehr nützliche Methode ist die Methode "get_Length()". Diese liefert
die Anzahl der Array-Elemente zurück.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;Variante 2:&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Alternativ zur ersten Variante besteht noch die Möglichkeit, ein .NET Array über die
Klasse System.Array zu erzeugen.&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/cc557456.aspx"&gt;How to: Use X++ Syntax
for CLR Arrays&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=514153a0-b0ff-4af7-b6f3-73645f99f656" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,514153a0-b0ff-4af7-b6f3-73645f99f656.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=d68de873-df06-4172-b927-a9bc15e1f81e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,d68de873-df06-4172-b927-a9bc15e1f81e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,d68de873-df06-4172-b927-a9bc15e1f81e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d68de873-df06-4172-b927-a9bc15e1f81e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wer schon mit dem AIF in der Version 4.0 von Microsoft Dynamics AX gearbeitet hat
wird sich daran erinnern, dass ein Debuggen des Quellcodes, welcher durch das
AIF ausgeführt wird, nur möglich ist, wenn hierfür eine kleine Codeanpassung
in den Klassen "AifInboundProcessingService" und "AifOutboundProcessingService" vorgenommen
wird.<br />
Das genaue Vorgehen für die Version 4.0 von Dynamics AX ist in diesem <a href="http://casperkamal.spaces.live.com/blog/cns!9138ED475277CD63!175.entry">Artikel</a> beschrieben.
</p>
        <p>
Für Dynamics AX 2009 kann diese Quellcodeänderung allerdings nicht so ohne weiteres
angewendet werden, da für Dynamics AX 2009 einige Features ergänzt wurden (z.B. paralelle
Verarbeitung von AIF Nachrichten) und somit der Quellcode der beiden Klassen einige
Abweichungen zu dem der Version 4.0 hat.
</p>
        <p>
          <font size="3">
            <u>Debuggen von ausgehenden Nachrichten</u>
          </font>
        </p>
        <p>
Um das Debuggen von ausgehenden Nachrichten zu ermöglichen, muss die Methode "runAsWrapper"
der Klasse "AifOutboundProcessingService" angepasst werden.<br />
Der Aufruf von "runAS" (Zeile 22) muss durch "AifOutboundProcessingService::processAsUser(messageIdContainer)"
ersetzt werden.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">...<br />
try</span>
            <br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
runAs currentUser and process all messages in the container.</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   new</span> RunAsPermission(runAsUserId).assert();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
AKU, Enable Debuging for outbound messages - START --&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Do not use in production system!!!</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
BP deviation documented</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //runas(runAsUserId,</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
classnum(AifOutboundProcessingService),</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
staticmethodstr(AifOutboundProcessingService, processAsUser),</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
messageIdContainer,</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
runAsCompany);</span><br />
   AifOutboundProcessingService::processAsUser(messageIdContainer);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
AKU, Enable Debuging for ourbound message - END --&gt;</span><br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Revert the permission</span><br />
   CodeAccessPermission::revertAssert();<br />
}<br /></span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">...</span>
        </p>
        <p>
          <font size="3">
            <u>Debuggen von eingehenden Nachrichten</u>
          </font>
        </p>
        <p>
Um das Debuggen von eingehenden Nachrichten zu ermöglichen, muss die Methode "runAsWrapper"
der Klasse "AifInboundProcessingService" angepasst werden.<br />
Der Aufruf von "runAS" (Teile 24) muss durch "AifInboundProcessingService::processAsUser(messageIdContainer)"
ersetzt werden.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">...<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span><br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Convert to Axapta UserId</span><br />
   axaptaUserId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> AifEndpointUser::getAxaptaUser(runAsUserId).Id;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   new</span> RunAsPermission(axaptaUserId).assert();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
AKU, Enable Debuging - START --&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Do not use in production system!!!</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
BP deviation documented</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //runas(axaptaUserId,</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
classnum(AifInboundProcessingService),</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
staticmethodstr(AifInboundProcessingService, processAsUser),</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
messageIdContainer);</span><br />
   AifInboundProcessingService::processAsUser(messageIdContainer);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
AKU, Enable Debuging - END --&gt;</span><br /><br />
   CodeAccessPermission::revertAssert();<br />
}<br />
...<br /></span>
        </p>
        <p>
Für beide Quellcodeänderung sollte noch erwähnt werden, dass diese in einem Produktivsystem
nicht durchgeführt werden sollten, da dies Auswirkungen auf die Verarbeitung der Stapelprozesse
des AIF's haben könnte.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=d68de873-df06-4172-b927-a9bc15e1f81e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>AIF debuggen mit Dynamics AX 2009</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,d68de873-df06-4172-b927-a9bc15e1f81e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,d68de873-df06-4172-b927-a9bc15e1f81e.aspx</link>
      <pubDate>Fri, 06 Feb 2009 22:29:08 GMT</pubDate>
      <description>&lt;p&gt;
Wer schon mit dem AIF in der Version 4.0 von Microsoft Dynamics AX gearbeitet hat
wird sich daran erinnern, dass ein Debuggen des Quellcodes, welcher durch&amp;nbsp;das
AIF ausgeführt wird,&amp;nbsp;nur möglich ist, wenn hierfür eine kleine Codeanpassung
in den Klassen "AifInboundProcessingService" und "AifOutboundProcessingService" vorgenommen
wird.&lt;br&gt;
Das genaue Vorgehen für die Version 4.0 von Dynamics AX ist in diesem &lt;a href="http://casperkamal.spaces.live.com/blog/cns!9138ED475277CD63!175.entry"&gt;Artikel&lt;/a&gt; beschrieben.
&lt;/p&gt;
&lt;p&gt;
Für Dynamics AX 2009 kann diese Quellcodeänderung allerdings nicht so ohne weiteres
angewendet werden, da für Dynamics AX 2009 einige Features ergänzt wurden (z.B. paralelle
Verarbeitung von AIF Nachrichten) und somit der Quellcode der beiden Klassen einige
Abweichungen zu dem der Version 4.0 hat.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=3&gt;&lt;u&gt;Debuggen von ausgehenden Nachrichten&lt;/u&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Um das Debuggen von ausgehenden Nachrichten zu ermöglichen, muss die Methode "runAsWrapper"
der Klasse "AifOutboundProcessingService" angepasst werden.&lt;br&gt;
Der Aufruf von "runAS" (Zeile 22) muss durch "AifOutboundProcessingService::processAsUser(messageIdContainer)"
ersetzt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;...&lt;br&gt;
try&lt;/span&gt;
&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
runAs currentUser and process all messages in the container.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&lt;/span&gt; RunAsPermission(runAsUserId).assert();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
AKU, Enable Debuging for outbound messages - START --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Do not use in production system!!!&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
BP deviation documented&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//runas(runAsUserId,&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
classnum(AifOutboundProcessingService),&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
staticmethodstr(AifOutboundProcessingService, processAsUser),&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
messageIdContainer,&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
runAsCompany);&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;AifOutboundProcessingService::processAsUser(messageIdContainer);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
AKU, Enable Debuging for ourbound message - END --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Revert the permission&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeAccessPermission::revertAssert();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;...&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=3&gt;&lt;u&gt;Debuggen von eingehenden Nachrichten&lt;/u&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Um das Debuggen von eingehenden Nachrichten zu ermöglichen, muss die Methode "runAsWrapper"
der Klasse "AifInboundProcessingService" angepasst werden.&lt;br&gt;
Der Aufruf von "runAS" (Teile 24) muss durch "AifInboundProcessingService::processAsUser(messageIdContainer)"
ersetzt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;...&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt;
&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Convert to Axapta UserId&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;axaptaUserId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; AifEndpointUser::getAxaptaUser(runAsUserId).Id;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&lt;/span&gt; RunAsPermission(axaptaUserId).assert();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
AKU, Enable Debuging - START --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Do not use in production system!!!&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
BP deviation documented&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//runas(axaptaUserId,&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
classnum(AifInboundProcessingService),&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
staticmethodstr(AifInboundProcessingService, processAsUser),&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
messageIdContainer);&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;AifInboundProcessingService::processAsUser(messageIdContainer);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
AKU, Enable Debuging - END --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeAccessPermission::revertAssert();&lt;br&gt;
}&lt;br&gt;
...&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Für beide Quellcodeänderung sollte noch erwähnt werden, dass diese in einem Produktivsystem
nicht durchgeführt werden sollten, da dies Auswirkungen auf die Verarbeitung der Stapelprozesse
des AIF's haben könnte.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=d68de873-df06-4172-b927-a9bc15e1f81e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,d68de873-df06-4172-b927-a9bc15e1f81e.aspx</comments>
      <category>Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=ef93e4ea-4344-445a-8afa-db59ed706dfa</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,ef93e4ea-4344-445a-8afa-db59ed706dfa.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,ef93e4ea-4344-445a-8afa-db59ed706dfa.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ef93e4ea-4344-445a-8afa-db59ed706dfa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Das Application Integration Framework von Dynamics AX basiert auf Dokumenten (Axd&lt;Document&gt;
Klassen).<br />
Eigene Dokumente lassen sich reicht einfach per Hand oder mit Hilfe des Dokumenten-Wizards
erstellen.<br />
In der Version 2009 von Dynamics AX erstellt dieser Wizard auch gleichzeitig den benötigenten
Service (WCF-Webservice) und andere benötigte Elemente wie (Serviceklassen und Macros).<br />
Welche Schritte hierfür benötigt werden ist zum Beispiel im <a href="http://msdn.microsoft.com/en-us/library/aa856656.aspx">Microsoft
Dynamics AX Developer Center</a> beschrieben.
</p>
        <p>
Ein kleines Problem entsteht, wenn das neue Dokument, genauer gesagt die Elemente
oder Objekte des Dokuments, in einem Layer (zum Beispiel CUS-Layer) entwickelt wird
und später, aus welchen Gründen auch immer, alle Objekte des Dokuments (Query, Ax&lt;Table&gt;
Class, Axd&lt;Document&gt; Class) in einen anderen Layer (zum Beispiel VAR-Layer)
verschoben werden.
</p>
        <p>
Nach der "Verschiebung" des neuen Dokuments in einen anderen Entwicklungslayer werden
durch die AIF-Konfigurationsmasken (siehe Maske Dienstleistungen) allerdings keine
Operationen (Insert, Update, Delete, FindKey, etc.) mehr angezeigt.<br />
Auch an anderen Stellen, wie zum Beispiel der Endpunktkonfiguration, sind die entsprechenden
Operationen nicht mehr auswählbar oder vorhanden.
</p>
        <p>
Der Grund hierfür liegt in der ClassId der Serviceklasse des neuen Dokuments. Dieser,
wie auch jedem anderen Objekt, wird beim Import in einen anderen Layer eine neue ID
zugewiesen, wenn nicht explizit angegeben wurde, dass der Export und Import mit ID's
erfolgen soll. So kann es sein, dass die Klasse mit der ID 40001 nach dem Import in
einen anderen Layer die ID 300001 zugeordnet ist.
</p>
        <p>
Da wärend der Konfiguration des AIF's der AOT nach Dokumenten/Services durchsucht
wird und für jedes Dokument bzw. jeden Service ein Datensatz in der Tabelle "AifService"
sowie ein bis mehrere Datensätze in der Tabelle "AifAction" erzeugt wird, welche alle
eine Referenz auf die ClassId der Serviceklasse enthalten, kommt es jetzt zu dem genannten
Problem.<br />
Der Id 40001 ist nun keine Klasse oder noch schlimmer eine andere Klasse zugewiesen.
Auch eine "Aktualisierung" dieser Datensätze über die Aktualisierungsfunktion, welche
auf der Maske Dienstleistungen bereit gestellt wird, führt nicht zum gewünschten Erfolg.
</p>
        <p>
Genau in dieser Funktion scheint sich ein kleiner Fehler eingeschlichen zu haben.
Dort wird zwar eine Aktulisierung der ClassId für die Datensätze der Tabelle "AifService",
aber nicht für die Datensätze der Tabelle "AifAction", durchgeführt.
</p>
        <p>
Um diese Verhalten zu reproduzieren, muss folgendes gemacht werden:
</p>
        <ol>
          <li>
Erstellen eines neuen AIF Dokuments bzw. AIF Services.</li>
          <li>
Über die Maske Dienstleistungen, zu finden unter "Grundeinstellungen -&gt; Einstellungen
-&gt; Application Integration Framework -&gt; Dienstleistungen", Funktion "Aktualisieren"
das neue Dokument / den neuen Service "aktivieren".</li>
          <li>
Über den Button "Servicearbeitsgänge" können nun alle Operationen welche durch das
Dokument / den Service bereit gestellt werden eingesehen werden.</li>
          <li>
Verschieben aller Elemente des Dokuments / des Services in einen anderen Layer.</li>
          <li>
Schritt 2 erneut druchführen.</li>
          <li>
Über den Button "Servicearbeitsgänge" werden keine Operation mehr angezeigt.</li>
        </ol>
        <p>
Um dieses Problem zu lösen, gibt 2 Möglichkeiten.
</p>
        <p>
Entweder manuelles Löschen alle zu diesem Dokument/Service gehörigen Datensätze
der Tabelle "AifAction" oder aber man ergänzt die Methode "registerOperations" der
Klasse "AifServiceGenerationManager" um ein wenig X++ Code (bei Zeile 43) welcher
nicht nur den Namen der Operation aktualisiert sondern auch die ClassId.<br />
Da dieser Code sehr einfach ist verzichte ich an dieser Stelle auf ein Beispiel.
</p>
        <p>
Leider tritt dieses Problem auch mit Dynamics AX 2009 Service Pack 1 auf.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=ef93e4ea-4344-445a-8afa-db59ed706dfa" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX AIF - Dokumente, Services aber keine Operationen?</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,ef93e4ea-4344-445a-8afa-db59ed706dfa.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,ef93e4ea-4344-445a-8afa-db59ed706dfa.aspx</link>
      <pubDate>Tue, 27 Jan 2009 18:46:19 GMT</pubDate>
      <description>&lt;p&gt;
Das Application Integration Framework von Dynamics AX basiert auf Dokumenten (Axd&amp;lt;Document&amp;gt;
Klassen).&lt;br&gt;
Eigene Dokumente lassen sich reicht einfach per Hand oder mit Hilfe des Dokumenten-Wizards
erstellen.&lt;br&gt;
In der Version 2009 von Dynamics AX erstellt dieser Wizard auch gleichzeitig den benötigenten
Service (WCF-Webservice) und andere benötigte Elemente wie (Serviceklassen und Macros).&lt;br&gt;
Welche Schritte hierfür benötigt werden ist zum Beispiel im &lt;a href="http://msdn.microsoft.com/en-us/library/aa856656.aspx"&gt;Microsoft
Dynamics AX Developer Center&lt;/a&gt; beschrieben.
&lt;/p&gt;
&lt;p&gt;
Ein kleines Problem entsteht, wenn das neue Dokument, genauer gesagt die Elemente
oder Objekte des Dokuments, in einem Layer (zum Beispiel CUS-Layer) entwickelt wird
und später, aus welchen Gründen auch immer, alle Objekte des Dokuments (Query, Ax&amp;lt;Table&amp;gt;
Class, Axd&amp;lt;Document&amp;gt; Class) in einen anderen Layer (zum Beispiel VAR-Layer)
verschoben werden.
&lt;/p&gt;
&lt;p&gt;
Nach der "Verschiebung" des neuen Dokuments in einen anderen Entwicklungslayer werden
durch die AIF-Konfigurationsmasken (siehe Maske Dienstleistungen) allerdings keine
Operationen (Insert, Update, Delete, FindKey, etc.)&amp;nbsp;mehr angezeigt.&lt;br&gt;
Auch an anderen Stellen, wie zum Beispiel der Endpunktkonfiguration, sind die entsprechenden
Operationen nicht mehr auswählbar oder vorhanden.
&lt;/p&gt;
&lt;p&gt;
Der Grund hierfür liegt in der ClassId der Serviceklasse des neuen Dokuments. Dieser,
wie auch jedem anderen Objekt, wird beim Import in einen anderen Layer eine neue ID
zugewiesen, wenn nicht explizit angegeben wurde, dass der Export und Import mit ID's
erfolgen soll. So kann es sein, dass die Klasse mit der ID 40001 nach dem Import in
einen anderen Layer die ID 300001 zugeordnet ist.
&lt;/p&gt;
&lt;p&gt;
Da wärend der Konfiguration des AIF's der AOT nach Dokumenten/Services durchsucht
wird und für jedes Dokument bzw. jeden Service ein Datensatz in der Tabelle "AifService"
sowie ein bis mehrere Datensätze in der Tabelle "AifAction" erzeugt wird, welche alle
eine Referenz auf die ClassId der Serviceklasse enthalten, kommt es jetzt zu dem genannten
Problem.&lt;br&gt;
Der Id 40001 ist nun keine Klasse oder noch schlimmer eine andere Klasse zugewiesen.
Auch eine "Aktualisierung" dieser Datensätze über die Aktualisierungsfunktion, welche
auf der Maske Dienstleistungen bereit gestellt wird, führt nicht zum gewünschten Erfolg.
&lt;/p&gt;
&lt;p&gt;
Genau in dieser Funktion scheint sich ein kleiner Fehler eingeschlichen zu haben.
Dort wird zwar eine Aktulisierung der ClassId für die Datensätze der Tabelle "AifService",
aber nicht für die Datensätze der Tabelle "AifAction", durchgeführt.
&lt;/p&gt;
&lt;p&gt;
Um diese Verhalten zu reproduzieren, muss folgendes gemacht werden:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Erstellen eines neuen AIF Dokuments bzw. AIF Services.&lt;/li&gt;
&lt;li&gt;
Über die Maske Dienstleistungen, zu finden unter&amp;nbsp;"Grundeinstellungen -&amp;gt; Einstellungen
-&amp;gt; Application Integration Framework -&amp;gt; Dienstleistungen", Funktion "Aktualisieren"
das neue Dokument / den neuen Service "aktivieren".&lt;/li&gt;
&lt;li&gt;
Über den Button "Servicearbeitsgänge" können nun alle Operationen welche durch das
Dokument / den Service bereit gestellt werden eingesehen werden.&lt;/li&gt;
&lt;li&gt;
Verschieben aller Elemente des Dokuments / des Services in einen anderen Layer.&lt;/li&gt;
&lt;li&gt;
Schritt 2 erneut druchführen.&lt;/li&gt;
&lt;li&gt;
Über den Button "Servicearbeitsgänge" werden keine Operation mehr angezeigt.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Um dieses Problem zu lösen, gibt 2 Möglichkeiten.
&lt;/p&gt;
&lt;p&gt;
Entweder&amp;nbsp;manuelles Löschen&amp;nbsp;alle zu diesem Dokument/Service gehörigen Datensätze
der Tabelle "AifAction" oder aber man ergänzt die Methode "registerOperations" der
Klasse "AifServiceGenerationManager" um ein wenig X++ Code (bei Zeile 43)&amp;nbsp;welcher
nicht nur den Namen der Operation aktualisiert sondern auch die ClassId.&lt;br&gt;
Da dieser Code sehr einfach ist verzichte ich an dieser Stelle auf ein Beispiel.
&lt;/p&gt;
&lt;p&gt;
Leider tritt dieses Problem auch mit Dynamics AX 2009 Service Pack 1 auf.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=ef93e4ea-4344-445a-8afa-db59ed706dfa" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,ef93e4ea-4344-445a-8afa-db59ed706dfa.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/Administration;Dynamics AX/AIF;Dynamics AX/Dynamics AX 2009;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=db4cdf8e-8cfa-4837-9371-a8362a319290</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,db4cdf8e-8cfa-4837-9371-a8362a319290.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,db4cdf8e-8cfa-4837-9371-a8362a319290.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=db4cdf8e-8cfa-4837-9371-a8362a319290</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In Microsoft Dynamics AX werden alle Informationsmeldungen, Warnungen und Fehlermeldungen
in einem Fenster, dem so genannten Infolog, ausgegeben.
</p>
        <p>
Wie Informationen, Warnungen oder Fehlermeldungen erzeugt werden können, ist an vielen
Stellen bereits beschrieben.<br />
Ein wie ich finde sehr guter Artikel über dieses Thema ist dieser: <a href="http://blogs.msdn.com/mfp/pages/the-user-friendly-infolog.aspx">The
user friendly Infolog</a>.
</p>
        <p>
An dieser Stelle soll aber kurz beschrieben werden, wie die Meldungen des
Infologs ausgewertet werden können, um zum Beispiel zu ermitteln, ob das Infolog eine
Fehlermeldung oder auch eine Warnung enthält.
</p>
        <p>
Zuerst stellt sich die Frage, warum benötigt man überhaupt diese Art von Information
da in Dynamics AX die Möglichkeit besteht, verschiedenste Operationen innerhalb
einer Transaktion zu Kapsel und diese bei Auftreten eines Fehlers oder Erzeugung einer
Fehlermeldung (Stichwort "throw error") automatisch rückgängig zu machen.
</p>
        <p>
Diese Frage soll anhand eines Beispiels beantwortet werden.
</p>
        <p>
Angenommen wir möchten eine Anpassung in Dynamics AX schreiben, welche es ermöglicht,
Änderungen an Stücklisten und Arbeitsplänen von Produktionsaufträgen zu automatisieren
und alle getätigten Änderungen in einer Transaktion zu kapseln. Anschließend soll
noch der Status der Produktions aktualisiert werden. Ebenfalls innerhalb der Transaktion.<br />
Zum Beispiel soll der Produktionsauftrag gestartet werden.
</p>
        <p>
Hierfür ist es notwendig verschiedene Standardfunktionen von Dynamics AX zu verwenden,
die bereits eine Fehlerbehandlung implementiert haben und somit keine Fehler mehr
"melden", welche den Abbruch einer Transaktion zu Folge haben könnten.<br />
Somit wird zwar gewährleistet, dass alle "Unterfunktionen" in sich richtig auf Fehler
richtig reagieren, aber dennoch könnte eine Dateninkonsistenz entstehen, da nicht
alle Operationen rückgängig gemacht werden. Es könnte Beispielhaft sein, dass
die Anlage von neuen Stücklistenpositionen und/oder Arbeitsgangpositionen funktioniert,
die spätere Statusaktualisierung des Produktionsauftrags aber nicht. Die erstellten
Stücklistenpositionen und/oder Arbeitsgangpositionen würden im System gespeichert
(bleiben).
</p>
        <p>
Abhilfe für dieses Problem kann duch die Auswertung des Infologs und manuellen Aufrufs
von "ttsabort" geschaffen werden.
</p>
        <p>
Mit dem "SysInfologEnumerator" können alle Meldungen, welche in das Infolog geschrieben
wurden, durchlaufen werden.<br />
Über die Methode "currentException" kann anschließend ausgewertet werden, um was für
eine Meldung (Information, Warnung, Fehler) es sich handelt.
</p>
        <p>
Hier ein kurzes Beispiel, wie dies aussehen könnte:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">boolean
hasError()<br />
{<br />
   SysInfologEnumerator <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>;<br />
   SysInfoAction action;<br />
   boolean hasError <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Analyse
the infolog to see if there are any warnings/errors</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   enum</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SysInfologEnumerator::newData(infolog.infologData());<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   while</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>.moveNext())<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      switch</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>.currentException())<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         case</span> Exception::Error:<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         case</span> Exception::Warning:<br />
            hasError <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            break</span>;<br />
      }<br /><br />
      infolog.add(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>.currentException(), <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>.currentMessage(), <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span>.currentHelpUrl());<br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   return</span> hasError;<br />
}</span>
        </p>
        <p>
Es muss allerdings beachtet werden, dass alle Meldungen des Infologs, durch den Aufruf
von "SysInfologEnumerator::newData(...)", gelöscht werden.<br />
Sollen diesese Meldungen nach der "Auswertung" dennoch dem Benutzer angezeigt werden,
müssen diese wieder manuell in das Infolog geschrieben werden (über "infolog.add(..)").
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=db4cdf8e-8cfa-4837-9371-a8362a319290" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Ermitteln ob Warnungen oder Fehlermeldung im Infolog enthalten sind</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,db4cdf8e-8cfa-4837-9371-a8362a319290.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,db4cdf8e-8cfa-4837-9371-a8362a319290.aspx</link>
      <pubDate>Thu, 08 Jan 2009 18:09:12 GMT</pubDate>
      <description>&lt;p&gt;
In Microsoft Dynamics AX werden alle Informationsmeldungen, Warnungen und Fehlermeldungen
in einem Fenster, dem so genannten Infolog, ausgegeben.
&lt;/p&gt;
&lt;p&gt;
Wie Informationen, Warnungen oder Fehlermeldungen erzeugt werden können, ist an vielen
Stellen bereits beschrieben.&lt;br&gt;
Ein wie ich finde sehr guter Artikel über dieses Thema ist dieser: &lt;a href="http://blogs.msdn.com/mfp/pages/the-user-friendly-infolog.aspx"&gt;The
user friendly Infolog&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
An dieser&amp;nbsp;Stelle soll&amp;nbsp;aber kurz beschrieben werden, wie die Meldungen des
Infologs ausgewertet werden können, um zum Beispiel zu ermitteln, ob das Infolog eine
Fehlermeldung oder auch eine Warnung enthält.
&lt;/p&gt;
&lt;p&gt;
Zuerst stellt sich die Frage, warum benötigt man überhaupt diese Art von Information
da&amp;nbsp;in Dynamics AX die Möglichkeit besteht, verschiedenste Operationen innerhalb
einer Transaktion zu Kapsel und diese bei Auftreten eines Fehlers oder Erzeugung einer
Fehlermeldung (Stichwort "throw error") automatisch rückgängig zu machen.
&lt;/p&gt;
&lt;p&gt;
Diese Frage soll anhand eines Beispiels beantwortet werden.
&lt;/p&gt;
&lt;p&gt;
Angenommen wir möchten eine Anpassung in Dynamics AX schreiben, welche es ermöglicht,
Änderungen an Stücklisten und Arbeitsplänen von Produktionsaufträgen zu automatisieren
und alle getätigten Änderungen in einer Transaktion zu kapseln. Anschließend soll
noch der Status der Produktions aktualisiert werden. Ebenfalls innerhalb der Transaktion.&lt;br&gt;
Zum Beispiel soll der Produktionsauftrag gestartet werden.
&lt;/p&gt;
&lt;p&gt;
Hierfür ist es notwendig verschiedene Standardfunktionen von Dynamics AX zu verwenden,
die bereits eine Fehlerbehandlung implementiert haben und somit keine Fehler mehr
"melden", welche den Abbruch einer Transaktion zu Folge haben könnten.&lt;br&gt;
Somit wird zwar gewährleistet, dass alle "Unterfunktionen" in sich richtig auf Fehler
richtig reagieren, aber dennoch könnte eine Dateninkonsistenz entstehen, da nicht
alle Operationen rückgängig gemacht werden.&amp;nbsp;Es könnte Beispielhaft sein, dass
die Anlage von neuen Stücklistenpositionen und/oder Arbeitsgangpositionen funktioniert,
die spätere Statusaktualisierung des Produktionsauftrags&amp;nbsp;aber nicht. Die erstellten
Stücklistenpositionen und/oder Arbeitsgangpositionen würden im System gespeichert
(bleiben).
&lt;/p&gt;
&lt;p&gt;
Abhilfe für dieses Problem kann duch die Auswertung des Infologs und manuellen Aufrufs
von "ttsabort" geschaffen werden.
&lt;/p&gt;
&lt;p&gt;
Mit dem "SysInfologEnumerator" können alle Meldungen, welche in das Infolog geschrieben
wurden, durchlaufen werden.&lt;br&gt;
Über die Methode "currentException" kann anschließend ausgewertet werden, um was für
eine Meldung (Information, Warnung, Fehler) es sich handelt.
&lt;/p&gt;
&lt;p&gt;
Hier ein kurzes Beispiel, wie dies aussehen könnte:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;boolean
hasError()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysInfologEnumerator &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysInfoAction action;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;boolean hasError &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Analyse
the infolog to see if there are any warnings/errors&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;enum&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SysInfologEnumerator::newData(infolog.infologData());&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;.moveNext())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;.currentException())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&lt;/span&gt; Exception::Error:&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&lt;/span&gt; Exception::Warning:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hasError &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;infolog.add(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;.currentException(), &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;.currentMessage(), &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt;.currentHelpUrl());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; hasError;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Es muss allerdings beachtet werden, dass alle Meldungen des Infologs, durch den Aufruf
von "SysInfologEnumerator::newData(...)", gelöscht werden.&lt;br&gt;
Sollen diesese Meldungen nach der "Auswertung" dennoch dem Benutzer angezeigt werden,
müssen diese wieder manuell in das Infolog geschrieben werden (über "infolog.add(..)").
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=db4cdf8e-8cfa-4837-9371-a8362a319290" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,db4cdf8e-8cfa-4837-9371-a8362a319290.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=0b55aa90-c644-4505-9fa7-5a99d7c4a2d0</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,0b55aa90-c644-4505-9fa7-5a99d7c4a2d0.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,0b55aa90-c644-4505-9fa7-5a99d7c4a2d0.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=0b55aa90-c644-4505-9fa7-5a99d7c4a2d0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft Dynamics AX 2009 bietet die Möglichkeit, den Verlauf eines Dokuments, welches
über das AIF exportiert oder importiert wurde zu betrachten.<br />
Dies war auch schon mit Microsoft Dynamics AX 4.0 möglich.
</p>
        <p>
Über die Maske "Dokumentverlauf" können alle Dokumente/Nachrichten eingesehen werden,
welche über das AIF verarbeitet wurden.<br />
Über den Button "Korrelation" ist es sogar möglich, die von der Verarbeitung (schreiben,
ändern, lesen, etc.) betroffenen Datensätze anzuzeigen.
</p>
        <p>
        </p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/AIFFehler_Maske2.jpg" border="0" />
        </p>
        <p>
So ist es zumindest in der Theorie.<br />
In der Praxis sieht es leider etwas anders aus. Nach einem Klick auf den Button "Korrelation"
öffnet sich leider nicht wie erwartet die Maske "Dokumentkorrelierung".<br />
Stattdessen wird der Debugger (wenn installiert) geöffnet und die Fehlermeldung
ausgegeben, dass ein Objekt nicht über die Methode "extendedTypeId" verfügt.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/AIFFehler2.jpg" border="0" />
        </p>
        <p>
So wie es scheint, hat sich in den Quellcode ein kleiner Fehler eingeschlichen, welcher
dazu führt, dass die Maske "Dokumentkorrelierung" niemals geöffnet werden kann.<br />
Nach einem Vergleich der Funktionalitäten zwischen Dynamics AX 4.0 und Dynamics AX
2009 kann dieses Verhalten (der Fehler) aber wie folgt beschrieben behoben werden.
</p>
        <ol>
          <li>
AOT öffnen und zu der Tabelle "AifCorrelation" navigieren. 
</li>
          <li>
Den Quelltext der Methode "displayEntityKey" anzeigen lassen bzw. diese für die Bearbeitung
öffnen. 
</li>
          <li>
Folgende Quelltextzeile suchen:<br /><font face="Courier New">dictField = new <strong>DictField</strong>(entityKey.parmTableId(),
enumerator.currentKey());</font></li>
          <li>
Dieses Zeile abändern in:<br /><font face="Courier New">dictField = new <strong>SySDictField</strong>(entityKey.parmTableId(),
enumerator.currentKey());</font></li>
        </ol>
        <p>
Nach dieser kleinen Quelltextänderung sollte alles wie erwartet funktionierten und
die Maske "Dokumentkorrelierung" mit den entsprechenden Datensätzen angezeigt werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=0b55aa90-c644-4505-9fa7-5a99d7c4a2d0" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics AX 2009 AIF - Aufruf der Dokumentkorrelierung im Dokumentverlauf</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,0b55aa90-c644-4505-9fa7-5a99d7c4a2d0.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,0b55aa90-c644-4505-9fa7-5a99d7c4a2d0.aspx</link>
      <pubDate>Wed, 05 Nov 2008 18:06:49 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft Dynamics AX 2009 bietet die Möglichkeit, den Verlauf eines Dokuments, welches
über das AIF exportiert oder importiert wurde zu betrachten.&lt;br&gt;
Dies war auch schon mit Microsoft Dynamics AX 4.0 möglich.
&lt;/p&gt;
&lt;p&gt;
Über die Maske "Dokumentverlauf" können alle Dokumente/Nachrichten eingesehen werden,
welche über das AIF verarbeitet wurden.&lt;br&gt;
Über den Button "Korrelation" ist es sogar möglich, die von der Verarbeitung (schreiben,
ändern, lesen, etc.) betroffenen Datensätze anzuzeigen.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/AIFFehler_Maske2.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
So ist es zumindest in der Theorie.&lt;br&gt;
In der Praxis sieht es leider etwas anders aus. Nach einem Klick auf den Button "Korrelation"
öffnet sich leider nicht wie erwartet die Maske "Dokumentkorrelierung".&lt;br&gt;
Stattdessen wird der Debugger (wenn installiert)&amp;nbsp;geöffnet und&amp;nbsp;die Fehlermeldung
ausgegeben, dass ein Objekt nicht über die Methode "extendedTypeId" verfügt.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/AIFFehler2.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
So wie es scheint, hat sich in den Quellcode ein kleiner Fehler eingeschlichen, welcher
dazu führt, dass die Maske "Dokumentkorrelierung" niemals geöffnet werden kann.&lt;br&gt;
Nach einem Vergleich der Funktionalitäten zwischen Dynamics AX 4.0 und Dynamics AX
2009 kann dieses Verhalten (der Fehler) aber wie folgt beschrieben behoben werden.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
AOT öffnen und zu der Tabelle "AifCorrelation" navigieren. 
&lt;li&gt;
Den Quelltext der Methode "displayEntityKey" anzeigen lassen bzw. diese für die Bearbeitung
öffnen. 
&lt;li&gt;
Folgende Quelltextzeile suchen:&lt;br&gt;
&lt;font face="Courier New"&gt;dictField = new &lt;strong&gt;DictField&lt;/strong&gt;(entityKey.parmTableId(),
enumerator.currentKey());&lt;/font&gt; 
&lt;li&gt;
Dieses Zeile abändern in:&lt;br&gt;
&lt;font face="Courier New"&gt;dictField = new &lt;strong&gt;SySDictField&lt;/strong&gt;(entityKey.parmTableId(),
enumerator.currentKey());&lt;/font&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Nach dieser kleinen Quelltextänderung sollte alles wie erwartet funktionierten und
die Maske "Dokumentkorrelierung" mit den entsprechenden Datensätzen angezeigt werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=0b55aa90-c644-4505-9fa7-5a99d7c4a2d0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,0b55aa90-c644-4505-9fa7-5a99d7c4a2d0.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics AX/AIF</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=52c21c8f-5aa5-4d84-aa88-d640b80e9701</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,52c21c8f-5aa5-4d84-aa88-d640b80e9701.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,52c21c8f-5aa5-4d84-aa88-d640b80e9701.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=52c21c8f-5aa5-4d84-aa88-d640b80e9701</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wie bereits in diesem Artikel <a href="http://blog.ak-home.net/PermaLink,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx">"Auswahl
von mehreren Datensätzen in einem Grid-Control (MultiSelect)"</a> beschrieben, kann
für ein Grid-Control die Eigenschaft MultiSelect gesetzt werden, womit es ermöglicht
wird, dass mehrere Datensätze für eine weitere Verarbeitung ausgewählt werden können.
</p>
        <p>
Dies Funktioniert solange, bis &lt;DataSource&gt;_ds.research() aufgerufen wird. Dieser
Aufruf hat zur Folge, dass die Daten der DataSource neu geladen werden und somit auch
die Selektierung verworfen wird.
</p>
        <p>
Ein Beispiel wie es nicht funktioniert:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> clicked() 
<br />
{ <br />
   CustTable custTable; <br />
   ; <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   for</span> (custTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.getFirst(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)
? CustTable_ds.getFirst(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)
: CustTable_ds.cursor(); <br />
        custTable; <br />
        custTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.getNext()) <br />
   { <br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      //do
something with custTable </span><br />
      info(custTable.accountNum);<br />
      </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">custTable_ds.research();   </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> <br />
   } 
<br />
}</span>
        </p>
        <p>
Es gilt also genau zu beachten zu welchem Zeitpunkt bzw. an welcher Stelle im Quelltext
die Methode &lt;DataSource&gt;_ds.research() aufgerufen wird.
</p>
        <p>
Weiterhin kann es zu Problemen beim MultiSelect kommen, wenn in den Methoden der DataSource
ein Aufruf von &lt;DataSource&gt;_ds.research() erfolgt.<br />
Normalerweise werden die DataSource-Methoden für jeden selektierten Datensatz ausgeführt.
Wenn aber innerhalb einer der Methoden, wie z.B. Delete(), wird diese Methode nur
für den ersten ausgewählten Datensatz ausgeführt und dann ein Research ausgeführt,
was wie schon beschrieben zu einem Verwerfen der Selektierung führt.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=52c21c8f-5aa5-4d84-aa88-d640b80e9701" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>MultiSelect und die DataSource-Methode research().</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,52c21c8f-5aa5-4d84-aa88-d640b80e9701.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,52c21c8f-5aa5-4d84-aa88-d640b80e9701.aspx</link>
      <pubDate>Thu, 14 Aug 2008 17:00:44 GMT</pubDate>
      <description>&lt;p&gt;
Wie bereits in diesem Artikel &lt;a href="http://blog.ak-home.net/PermaLink,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx"&gt;"Auswahl
von mehreren Datensätzen in einem Grid-Control (MultiSelect)"&lt;/a&gt; beschrieben, kann
für ein Grid-Control die Eigenschaft MultiSelect gesetzt werden, womit es ermöglicht
wird, dass mehrere Datensätze für eine weitere Verarbeitung ausgewählt werden können.
&lt;/p&gt;
&lt;p&gt;
Dies Funktioniert solange, bis &amp;lt;DataSource&amp;gt;_ds.research() aufgerufen wird. Dieser
Aufruf hat zur Folge, dass die Daten der DataSource neu geladen werden und somit auch
die Selektierung verworfen wird.
&lt;/p&gt;
&lt;p&gt;
Ein Beispiel wie es nicht funktioniert:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; clicked() 
&lt;br&gt;
{&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable custTable;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&lt;/span&gt; (custTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.getFirst(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)
?&amp;nbsp;CustTable_ds.getFirst(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)
: CustTable_ds.cursor();&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; custTable;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;custTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.getNext())&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//do
something with custTable&amp;nbsp;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info(custTable.accountNum);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;custTable_ds.research();&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Es gilt also genau zu beachten zu welchem Zeitpunkt bzw. an welcher Stelle im Quelltext
die Methode &amp;lt;DataSource&amp;gt;_ds.research() aufgerufen wird.
&lt;/p&gt;
&lt;p&gt;
Weiterhin kann es zu Problemen beim MultiSelect kommen, wenn in den Methoden der DataSource
ein Aufruf von &amp;lt;DataSource&amp;gt;_ds.research() erfolgt.&lt;br&gt;
Normalerweise werden die DataSource-Methoden für jeden selektierten Datensatz ausgeführt.
Wenn aber innerhalb einer der Methoden, wie z.B. Delete(), wird diese Methode nur
für den ersten ausgewählten Datensatz ausgeführt und dann ein Research ausgeführt,
was wie schon beschrieben zu einem Verwerfen der Selektierung führt.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=52c21c8f-5aa5-4d84-aa88-d640b80e9701" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,52c21c8f-5aa5-4d84-aa88-d640b80e9701.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=be8bfbd5-e4ac-4858-8c19-9d45aaa37220</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,be8bfbd5-e4ac-4858-8c19-9d45aaa37220.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,be8bfbd5-e4ac-4858-8c19-9d45aaa37220.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=be8bfbd5-e4ac-4858-8c19-9d45aaa37220</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft Dynamics AX verwendet für eindeutige Kennungswerte (Id’s) die eingebauten
Nummernkreise, für welche ein Feld vom Typ „String“ benötigt wird. Dies macht auch
Sinn, da Nummernkreise in Dynamics AX oft ein oder mehrere alphanumerische Zeichen
enthalten. Natürlich können auch rein nummerische Nummernkreise mit diesem „Framework“
erstellt werden.
</p>
        <p>
Allerdings sind die Nummernkreise im Dynamics AX Standard nicht ganz optimal bei der
Verwendung von einem rein nummerischen Nummernkreisen. Dies fängt z.B. schon beim
Datentyp an, der für das ID-Feld der Tabelle verwendet werden muss. Bedingt dadurch,
dass ein Feld vom Typ „String“ verwendet werden muss, belegt dieses Feld unnötig viel
Speicher in der Datenbank. Weiterhin gestalten sich Sortierungen, Rechenoperationen,
etc. erheblich schwieriger.
</p>
        <p>
Diese Probleme können umgangen werden, wenn für das ID-Feld der Datentyp „Integer“
oder „Int64“ verwendet wird. Leider kann nun nicht mehr das Nummernkreis-Framework
des Dynamics AX Standards verwendet werden, da dies den Datentyp „String“ für ein
ID-Feld vorschreibt.
</p>
        <p>
Es muss also ein eigenes, kleines Nummernkreis-Framework oder ein eigener Nummernkreis
geschrieben werden, der die Verwendung des Datentyps „Integer“ für ID-Felder ermöglicht.
Dies hört sich zuerst schwierig an, da Dinge wie fortlaufende Nummernvergabe oder
die Wiederverwendung von freien Nummern (Löchern im Nummernkreis) berücksichtigt werden
sollten.
</p>
        <p>
Es ist aber ganz und gar nicht schwierig, eine eigene Nummernkreisfunktionalität zu
erstellen. Das einzige was hierfür benötigt wird ist eine entsprechen aufgebaute Select-Abfrage.
</p>
        <p>
Die nächste Nummer eines Nummernkreises ist immer die zuletzt vergebenen Nummer (höchste)
+ 1.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   Aku_TestTable
t1;<br />
   ;<br />
   select maxof(ID) from t1;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   return</span> t1.ID <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> 1;</span>
        </p>
        <p>
Etwas schwieriger wird es, wenn auch die frei gewordenen Nummern des Nummernkreises
wieder vergeben/verwendet werden sollen. Dann muss immer die kleinste Id aus der Tabelle
gesucht werden, für die es keinen Datensatz in der Tabelle gibt. Gibt es kein "Nummernloch",
muss die nächst höchste Nummer vergeben werden.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   Aku_TestTable
t1;<br />
   Aku_TestTable t2;<br />
   ;<br />
   select minof(ID) from t1 notexists join t2 where t2.ID == (t1.ID <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> 1);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   return</span> t1.ID <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> 1;</span>
        </p>
        <p>
Um diese ein wenig zu verdeutlichen, kann eine beispielhafte Implementierung eines
eigenen Nummernkreises in diesem <a href="http://blog.ak-home.net/content/binary/SharedProject_AKU_OwnIntNumberSeq.rar">Demoprojekt
"SharedProject_AKU_OwnIntNumberSeq"</a> angesehen und runter geladen werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=be8bfbd5-e4ac-4858-8c19-9d45aaa37220" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Numerische Nummernkreise im Eigenbau</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,be8bfbd5-e4ac-4858-8c19-9d45aaa37220.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,be8bfbd5-e4ac-4858-8c19-9d45aaa37220.aspx</link>
      <pubDate>Fri, 08 Aug 2008 14:38:44 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft Dynamics AX verwendet für eindeutige Kennungswerte (Id’s) die eingebauten
Nummernkreise, für welche ein Feld vom Typ „String“ benötigt wird. Dies macht auch
Sinn, da Nummernkreise in Dynamics AX oft ein oder mehrere alphanumerische Zeichen
enthalten. Natürlich können auch rein nummerische Nummernkreise mit diesem „Framework“
erstellt werden.
&lt;/p&gt;
&lt;p&gt;
Allerdings sind die Nummernkreise im Dynamics AX Standard nicht ganz optimal bei der
Verwendung von einem rein nummerischen Nummernkreisen. Dies fängt z.B. schon beim
Datentyp an, der für das ID-Feld der Tabelle verwendet werden muss. Bedingt dadurch,
dass ein Feld vom Typ „String“ verwendet werden muss, belegt dieses Feld unnötig viel
Speicher in der Datenbank. Weiterhin gestalten sich Sortierungen, Rechenoperationen,
etc. erheblich schwieriger.
&lt;/p&gt;
&lt;p&gt;
Diese Probleme können umgangen werden, wenn für das ID-Feld der Datentyp „Integer“
oder „Int64“ verwendet wird. Leider kann nun nicht mehr das Nummernkreis-Framework
des Dynamics AX Standards verwendet werden, da dies den Datentyp „String“ für ein
ID-Feld vorschreibt.
&lt;/p&gt;
&lt;p&gt;
Es muss also ein eigenes, kleines Nummernkreis-Framework oder ein eigener Nummernkreis
geschrieben werden, der die Verwendung des Datentyps „Integer“ für ID-Felder ermöglicht.
Dies hört sich zuerst schwierig an, da Dinge wie fortlaufende Nummernvergabe oder
die Wiederverwendung von freien Nummern (Löchern im Nummernkreis) berücksichtigt werden
sollten.
&lt;/p&gt;
&lt;p&gt;
Es ist aber ganz und gar nicht schwierig, eine eigene Nummernkreisfunktionalität zu
erstellen. Das einzige was hierfür benötigt wird ist eine entsprechen aufgebaute Select-Abfrage.
&lt;/p&gt;
&lt;p&gt;
Die nächste Nummer eines Nummernkreises ist immer die zuletzt vergebenen Nummer (höchste)
+ 1.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Aku_TestTable
t1;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;select maxof(ID) from t1;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; t1.ID &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; 1;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Etwas schwieriger wird es, wenn auch die frei gewordenen Nummern des Nummernkreises
wieder vergeben/verwendet werden sollen. Dann muss immer die kleinste Id aus der Tabelle
gesucht werden, für die es keinen Datensatz in der Tabelle gibt. Gibt es kein "Nummernloch",
muss die nächst höchste Nummer vergeben werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Aku_TestTable
t1;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Aku_TestTable t2;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;select minof(ID) from t1 notexists join t2 where t2.ID == (t1.ID &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; 1);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; t1.ID &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; 1;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Um diese ein wenig zu verdeutlichen, kann eine beispielhafte Implementierung eines
eigenen Nummernkreises in diesem &lt;a href="http://blog.ak-home.net/content/binary/SharedProject_AKU_OwnIntNumberSeq.rar"&gt;Demoprojekt
"SharedProject_AKU_OwnIntNumberSeq"&lt;/a&gt; angesehen und runter geladen werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=be8bfbd5-e4ac-4858-8c19-9d45aaa37220" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,be8bfbd5-e4ac-4858-8c19-9d45aaa37220.aspx</comments>
      <category>Dynamics Ax/Programmierung;Dynamics Ax/Programmierung, Dynamics Ax/HowTo</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=1d00947d-ff17-471a-8e06-7ed13640c46d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,1d00947d-ff17-471a-8e06-7ed13640c46d.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,1d00947d-ff17-471a-8e06-7ed13640c46d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1d00947d-ff17-471a-8e06-7ed13640c46d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In der Screencast Sektion von Channel 9 hat Mey Meenakshisundaram 6 Screencasts über
die Entwicklung mit dem Enterprise Portal veröffentlicht.
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-List-Page-in-Enterprise-Portal/">Microsoft
Dynamics AX 2009 – Creating simple List Page in Enterprise Portal</a>
          <br />
This how-to video demonstrates how to create a simple List Page in Enterprise Portal
using AxGridView control.
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-Task-Page-in-Enterprise-Portal/">Microsoft
Dynamics AX 2009 – Creating simple Task Page in Enterprise Portal</a>
          <br />
This how-to video demonstrates how to create a simple Task Page in Enterprise Portal
using AxForm control.
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-TunnelWizard-Page-in-Enterprise-Portal/">Microsoft
Dynamics AX 2009 – Creating simple Tunnel(Wizard) Page in Enterprise Portal</a>
          <br />
This how-to video demonstrates how to create a simple Tunnel(Wizard) Page in Enterprise
Portal using ASP.net Wizard control and EP AxForm control.
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Calling-X-classes-in-Enterprise-Portal-User-Controls-in-C/">Microsoft
Dynamics AX 2009 – Calling X++ classes in Enterprise Portal User Controls in C#</a>
          <br />
This how-to video demonstrates how to create a simple X++ Class in AOT and create
a C# proxy for this class and call it in Enterprise Portal user control written in
C#.
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Using-Record-Context-in-Enterprise-Portal/">Microsoft
Dynamics AX 2009 – Using Record Context in Enterprise Portal</a>
          <br />
Microsoft Dynamics AX developers will learn how to use record context in Enterprise
Portal. Record context is used to pass currently selected record information on a
page or Web part to another page or connected Web part. This how-to-video demonstrates
three ways of passing record context...
</p>
        <p>
          <a id="ctl00_MainPlaceHolder_Starter_TitleLink" title="Permalink" href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Advanced-Grid-in-Enterprise-Portal-List-Page/">Microsoft
Dynamics AX 2009 – Advanced Grid in Enterprise Portal List Page</a>
          <br />
This how-to video demonstrates how to add ranges in dataset to restrict the data displayed
and the different options supported (open,hidden,locked). This also demonstrates how
to use display and edit methods defined in the table in the Grid.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=1d00947d-ff17-471a-8e06-7ed13640c46d" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX 2009 Enterprise Portal Entwicklung Samples</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,1d00947d-ff17-471a-8e06-7ed13640c46d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,1d00947d-ff17-471a-8e06-7ed13640c46d.aspx</link>
      <pubDate>Thu, 26 Jun 2008 17:46:58 GMT</pubDate>
      <description>&lt;p&gt;
In der Screencast Sektion von Channel 9 hat Mey Meenakshisundaram 6 Screencasts über
die Entwicklung mit dem Enterprise Portal veröffentlicht.
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-List-Page-in-Enterprise-Portal/"&gt;Microsoft
Dynamics AX 2009 – Creating simple List Page in Enterprise Portal&lt;/a&gt;
&lt;br&gt;
This how-to video demonstrates how to create a simple List Page in Enterprise Portal
using AxGridView control.
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-Task-Page-in-Enterprise-Portal/"&gt;Microsoft
Dynamics AX 2009 – Creating simple Task Page in Enterprise Portal&lt;/a&gt;
&lt;br&gt;
This how-to video demonstrates how to create a simple Task Page in Enterprise Portal
using AxForm control.
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Creating-simple-TunnelWizard-Page-in-Enterprise-Portal/"&gt;Microsoft
Dynamics AX 2009 – Creating simple Tunnel(Wizard) Page in Enterprise Portal&lt;/a&gt;
&lt;br&gt;
This how-to video demonstrates how to create a simple Tunnel(Wizard) Page in Enterprise
Portal using ASP.net Wizard control and EP AxForm control.
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Calling-X-classes-in-Enterprise-Portal-User-Controls-in-C/"&gt;Microsoft
Dynamics AX 2009 – Calling X++ classes in Enterprise Portal User Controls in C#&lt;/a&gt;
&lt;br&gt;
This how-to video demonstrates how to create a simple X++ Class in AOT and create
a C# proxy for this class and call it in Enterprise Portal user control written in
C#.
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Using-Record-Context-in-Enterprise-Portal/"&gt;Microsoft
Dynamics AX 2009 – Using Record Context in Enterprise Portal&lt;/a&gt;
&lt;br&gt;
Microsoft Dynamics AX developers will learn how to use record context in Enterprise
Portal. Record context is used to pass currently selected record information on a
page or Web part to another page or connected Web part. This how-to-video demonstrates
three ways of passing record context...
&lt;/p&gt;
&lt;p&gt;
&lt;a id=ctl00_MainPlaceHolder_Starter_TitleLink title=Permalink href="http://channel9.msdn.com/posts/meysun/Microsoft-Dynamics-AX-2009--Advanced-Grid-in-Enterprise-Portal-List-Page/"&gt;Microsoft
Dynamics AX 2009 – Advanced Grid in Enterprise Portal List Page&lt;/a&gt;
&lt;br&gt;
This how-to video demonstrates how to add ranges in dataset to restrict the data displayed
and the different options supported (open,hidden,locked). This also demonstrates how
to use display and edit methods defined in the table in the Grid.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=1d00947d-ff17-471a-8e06-7ed13640c46d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,1d00947d-ff17-471a-8e06-7ed13640c46d.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/Programmierung;Dynamics AX / Programmierung / Enterprise Portal</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=40c372cb-a0e8-4963-9627-dbcb08d37d7b</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,40c372cb-a0e8-4963-9627-dbcb08d37d7b.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,40c372cb-a0e8-4963-9627-dbcb08d37d7b.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=40c372cb-a0e8-4963-9627-dbcb08d37d7b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wenn bei der Entwicklung mit Microsoft Dynamics AX 4.0 die Quellcodeverwaltung mittels
Visual SourceSafe 2005 eingeschaltet wurde, besteht die Möglichkeit einzelne Versionen
eines Objekts miteinander zu vergleichen.
</p>
        <p>
Hierbei kann es aber bei einer "ungünstigen" Konfiguration des lokal Repository-Verzeichnisses
sein, dass bei einem Vergleich von zwei Objektversionen die Fehlermeldung "<font color="#ff0000">Fehler:
Fortsetzen nicht möglich</font>" ausgegeben wird.
</p>
        <p>
Diese Fehlermeldung wird immer erzeugt, wenn sich das lokale Repository-Verzeichnis
und das Verzeichnis, in dem die temporären Internetdateien (Temporary Internet Files)
gespeichert werden, nicht auf der gleichen Partition (Datenträger) befinden.
</p>
        <p>
Beispiel:
</p>
        <p>
Ordner der Temporary Internet Files = C:\Dokumente und Einstellungen\UserXY\Lokale
Einstellungen\Temporary Internet Files<br />
Ordner des lokalen Repositories = D:\VSSRepository\Test
</p>
        <p>
-&gt; Die Fehlermeldung wird ausgegeben.
</p>
        <p>
Ordner der Temporary Internet Files = C:\Dokumente und Einstellungen\UserXY\Lokale
Einstellungen\Temporary Internet Files<br />
Ordner des lokalen Repositories = C:\VSSRepository\Test
</p>
        <p>
-&gt; Die Fehlermeldung wird nicht ausgegeben und der Versionvergleich funktioniert
problemlos.
</p>
        <p>
Dieses Problem wird durch ein <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=8a1a68d8-db11-417c-91ad-02aab484776b&amp;displaylang=en">Update
für Visual SourceSafe 2005</a> behoben. Es empfiehlt sich, bei Verwendung der Quellcodeverwaltung
mit Visual SourceSafe 2005 als VC-System, dieses Update einzuspielen.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=40c372cb-a0e8-4963-9627-dbcb08d37d7b" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Versionsverwaltung mit Visual SourceSafe - Vergleichen von Objektversionen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,40c372cb-a0e8-4963-9627-dbcb08d37d7b.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,40c372cb-a0e8-4963-9627-dbcb08d37d7b.aspx</link>
      <pubDate>Thu, 12 Jun 2008 09:57:09 GMT</pubDate>
      <description>&lt;p&gt;
Wenn bei der Entwicklung mit Microsoft Dynamics AX 4.0 die Quellcodeverwaltung mittels
Visual SourceSafe 2005 eingeschaltet wurde, besteht die Möglichkeit einzelne Versionen
eines Objekts miteinander zu vergleichen.
&lt;/p&gt;
&lt;p&gt;
Hierbei kann es aber bei einer "ungünstigen" Konfiguration des lokal Repository-Verzeichnisses
sein, dass bei einem Vergleich von zwei Objektversionen die Fehlermeldung "&lt;font color=#ff0000&gt;Fehler:
Fortsetzen nicht möglich&lt;/font&gt;" ausgegeben wird.
&lt;/p&gt;
&lt;p&gt;
Diese Fehlermeldung wird immer erzeugt, wenn sich das lokale Repository-Verzeichnis
und das Verzeichnis, in dem die temporären Internetdateien (Temporary Internet Files)
gespeichert werden,&amp;nbsp;nicht auf der gleichen Partition (Datenträger) befinden.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
Ordner&amp;nbsp;der Temporary Internet Files =&amp;nbsp;C:\Dokumente und Einstellungen\UserXY\Lokale
Einstellungen\Temporary Internet Files&lt;br&gt;
Ordner des lokalen Repositories = D:\VSSRepository\Test
&lt;/p&gt;
&lt;p&gt;
-&amp;gt; Die Fehlermeldung wird ausgegeben.
&lt;/p&gt;
&lt;p&gt;
Ordner&amp;nbsp;der Temporary Internet Files =&amp;nbsp;C:\Dokumente und Einstellungen\UserXY\Lokale
Einstellungen\Temporary Internet Files&lt;br&gt;
Ordner des lokalen Repositories = C:\VSSRepository\Test
&lt;/p&gt;
&lt;p&gt;
-&amp;gt; Die Fehlermeldung wird nicht ausgegeben und der Versionvergleich funktioniert
problemlos.
&lt;/p&gt;
&lt;p&gt;
Dieses Problem wird durch ein &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=8a1a68d8-db11-417c-91ad-02aab484776b&amp;amp;displaylang=en"&gt;Update
für Visual SourceSafe 2005&lt;/a&gt; behoben. Es empfiehlt sich, bei Verwendung der Quellcodeverwaltung
mit Visual SourceSafe 2005 als VC-System, dieses Update einzuspielen.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=40c372cb-a0e8-4963-9627-dbcb08d37d7b" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,40c372cb-a0e8-4963-9627-dbcb08d37d7b.aspx</comments>
      <category>Allgemein;Dynamics Ax/Administration;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung, Dynamics Ax/HowTo</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=38d95169-c598-4123-ae48-77d75e0c9a9e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,38d95169-c598-4123-ae48-77d75e0c9a9e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,38d95169-c598-4123-ae48-77d75e0c9a9e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=38d95169-c598-4123-ae48-77d75e0c9a9e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So nach und nach erscheinen immer mehr Informationen über die Version 2009 von
Dynamics AX im Internet.<br />
Hier eine Liste der bereits verfügbaren Quellen:
</p>
        <p>
          <a href="http://www.microsoft.com/dynamics/ax/using/ax_installationinfo.mspx">Install
Microsoft Dynamics AX 2009</a> (Informationen zur Installtion von Dynamics AX
2009)
</p>
        <p>
          <a href="http://www.microsoft.com/dynamics/ax/using/default.mspx">Using Microsoft
Dynamics AX 2009</a> (Allgemeine Informationen zu Dynamics AX 2009)<a></a></p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/aa496071.aspx">Microsoft Dynamics
AX 2009 SDK</a>
        </p>
        <p>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7B80DC17-BCF0-4AF5-A4D0-81ABA51F8002&amp;displaylang=en">What's
new for Microsoft Dynamics AX 2009</a> (Änderungen/Neuerungen als download)
</p>
        <p>
          <a href="http://blogs.msdn.com/epblog/">The Microsoft Dynamics AX Enterprise Portal
Blog</a> (Informationen über das EP, direkt vom MS EP Team)
</p>
        <p>
 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=38d95169-c598-4123-ae48-77d75e0c9a9e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Technische Informationen über Microsoft Dynamics AX 2009 im Internet</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,38d95169-c598-4123-ae48-77d75e0c9a9e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,38d95169-c598-4123-ae48-77d75e0c9a9e.aspx</link>
      <pubDate>Fri, 06 Jun 2008 13:30:27 GMT</pubDate>
      <description>&lt;p&gt;
So nach und nach erscheinen immer mehr Informationen über die Version&amp;nbsp;2009 von
Dynamics AX im Internet.&lt;br&gt;
Hier eine Liste der bereits verfügbaren Quellen:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/dynamics/ax/using/ax_installationinfo.mspx"&gt;Install
Microsoft Dynamics AX 2009&lt;/a&gt;&amp;nbsp;(Informationen zur Installtion von Dynamics AX
2009)
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/dynamics/ax/using/default.mspx"&gt;Using Microsoft
Dynamics AX 2009&lt;/a&gt;&amp;nbsp;(Allgemeine Informationen zu Dynamics AX 2009)&lt;a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/aa496071.aspx"&gt;Microsoft Dynamics
AX 2009 SDK&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7B80DC17-BCF0-4AF5-A4D0-81ABA51F8002&amp;amp;displaylang=en"&gt;What's
new for Microsoft Dynamics AX 2009&lt;/a&gt; (Änderungen/Neuerungen als download)
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/epblog/"&gt;The Microsoft Dynamics AX Enterprise Portal
Blog&lt;/a&gt;&amp;nbsp;(Informationen über das EP, direkt vom MS EP Team)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=38d95169-c598-4123-ae48-77d75e0c9a9e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,38d95169-c598-4123-ae48-77d75e0c9a9e.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/Administration;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=92d3dd05-07a6-446f-b2f4-20e5fd09ff1e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,92d3dd05-07a6-446f-b2f4-20e5fd09ff1e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,92d3dd05-07a6-446f-b2f4-20e5fd09ff1e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=92d3dd05-07a6-446f-b2f4-20e5fd09ff1e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Für jede Tabelle können Systemfelder wie Erstellt von, Geändert von, Erstellungsdatum,
Erstellungszeit oder Änderungsdatum von Dynamics AX aktiviert werden.<br />
Diese Felder werden durch Dynamics AX automatisch gefüllt. Wird zum Beispiel ein neuer
Datensatz erzeugt, füllt Dynamics AX die Systemfelder mit den entsprechenden
Daten.
</p>
        <p>
Es gibt aber Situationen wo man selber Einfuß auf die Werte dieser Felder nehmen
muss. Ein Beispiel hierfür könnte eine Datenübernahme sein, bei der die Informationen
über den Ersteller oder das Erstellungsdatum des Datensatzes nicht verloren gehen
dürfen.
</p>
        <p>
Wie dies gehen kann zeigt dieses kleine Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">YourTable
table;<br />
;<br />
ttsbegin;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//can
only be called on server tier. -&gt; method must be executed on server tier.</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SkipAOSValidationPermission().assert();<br />
table.skipAosValidation(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br /><br />
table.YourField <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Value"</span>;<br /><br />
table.overwriteSystemfields(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//set
your own values for the system fields.</span><br />
table.(fieldnum(Table1, ModifiedDate)) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> today() <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> 2;<br />
table.(fieldnum(Table1, CreatedDate)) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> today() <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> 5;<br />
table.(fieldnum(Table1, CreatedBy)) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"TEST"</span>;<br /><br />
table.insert();<br />
ttscommit;<br /><br />
table.skipAosValidation(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);</span>
        </p>
        <p>
Allerdings können die Systemfelder nur beim Erstellen eines neuen Datensatzes "von
Hand" festgelegt werden.
</p>
        <p>
Wie das Ändern von Werten der Systemfelder bei bereits bestehenden Datensätzen geht
demonstriert die Klasse "BatchRun", Methode "runJob" und "finishJob".<br />
Kurz gesagt wird genau genommen der Datensatz nicht geändert, sondern es werden nur
die Daten des bestehenden Datensatzes in den neuen Datensatz kopiert (mit newBuffer
= oldBuffer.data()) und dann wie bereits beschrieben die Systemfelder mit eigenen
Werten befüllt. Dann wird der bestehnde Datensatz gelöscht und der neue Datensatz
in die Datenbank geschrieben.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=92d3dd05-07a6-446f-b2f4-20e5fd09ff1e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Werte der Systemfelder eines Datensatzes setzen </title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,92d3dd05-07a6-446f-b2f4-20e5fd09ff1e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,92d3dd05-07a6-446f-b2f4-20e5fd09ff1e.aspx</link>
      <pubDate>Thu, 29 May 2008 19:36:51 GMT</pubDate>
      <description>&lt;p&gt;
Für jede Tabelle können Systemfelder wie Erstellt von, Geändert von, Erstellungsdatum,
Erstellungszeit oder Änderungsdatum&amp;nbsp;von Dynamics AX aktiviert werden.&lt;br&gt;
Diese Felder werden durch Dynamics AX automatisch gefüllt. Wird zum Beispiel ein neuer
Datensatz erzeugt,&amp;nbsp;füllt Dynamics AX die Systemfelder mit&amp;nbsp;den entsprechenden
Daten.
&lt;/p&gt;
&lt;p&gt;
Es gibt aber Situationen wo man selber Einfuß&amp;nbsp;auf die Werte dieser Felder nehmen
muss. Ein Beispiel hierfür könnte eine Datenübernahme sein, bei der die Informationen
über den Ersteller oder das Erstellungsdatum des Datensatzes nicht verloren gehen
dürfen.
&lt;/p&gt;
&lt;p&gt;
Wie dies gehen kann zeigt dieses kleine Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;YourTable
table;&lt;br&gt;
;&lt;br&gt;
ttsbegin;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//can
only be called on server tier. -&amp;gt; method must be executed on server tier.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SkipAOSValidationPermission().assert();&lt;br&gt;
table.skipAosValidation(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
table.YourField &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Value"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
table.overwriteSystemfields(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//set
your own values for the system fields.&lt;/span&gt;
&lt;br&gt;
table.(fieldnum(Table1, ModifiedDate)) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; today() &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; 2;&lt;br&gt;
table.(fieldnum(Table1, CreatedDate)) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; today() &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; 5;&lt;br&gt;
table.(fieldnum(Table1, CreatedBy)) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"TEST"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
table.insert();&lt;br&gt;
ttscommit;&lt;br&gt;
&lt;br&gt;
table.skipAosValidation(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Allerdings können die Systemfelder nur beim Erstellen eines neuen Datensatzes "von
Hand" festgelegt werden.
&lt;/p&gt;
&lt;p&gt;
Wie das Ändern von Werten der Systemfelder bei bereits bestehenden Datensätzen geht
demonstriert die Klasse "BatchRun", Methode "runJob" und "finishJob".&lt;br&gt;
Kurz gesagt wird genau genommen der Datensatz nicht geändert, sondern es werden nur
die Daten des bestehenden Datensatzes in den neuen Datensatz kopiert (mit&amp;nbsp;newBuffer
= oldBuffer.data()) und dann wie bereits beschrieben die Systemfelder mit eigenen
Werten befüllt. Dann wird der bestehnde Datensatz gelöscht und der neue Datensatz
in die Datenbank geschrieben.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=92d3dd05-07a6-446f-b2f4-20e5fd09ff1e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,92d3dd05-07a6-446f-b2f4-20e5fd09ff1e.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=f4d824f5-434d-4b51-8bdb-671182f66cd5</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,f4d824f5-434d-4b51-8bdb-671182f66cd5.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,f4d824f5-434d-4b51-8bdb-671182f66cd5.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=f4d824f5-434d-4b51-8bdb-671182f66cd5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Häufig werden Optionen (Ja/Nein-Fragen) in Microsoft Dynamics AX durch ein CheckBox
Control und einem entsprechendem Feld einer Tabelle abgebildet. 
</p>
        <p>
Ein gutes Beispiel hierfür ist die Maske „Lagerparameter“, Reiter „Lagerungsdimensionen“.
Hier kann eingestellt werden, welche Lagerungsdimension wo im System angezeigt werden
soll. Zur Speicherung der gewählten Einstellungen wird die Tabelle „InventDimSetupGrid“
verwendet. Diese Tabelle enthält für jede Option jeweils ein Feld (abgeleitet vom
Enum „NoYes“).<br />
Diese Art der Speicherung von Optionswerten ist sicherlich sehr leicht zu verstehen
und auch sehr einfach zu erstellen. Da aber für jede Option ein Feld in der Tabelle
angelegt werden muss, kann dies relativ zeitaufwendig sein.
</p>
        <p>
Es besteht aber die Möglichkeit, Optionswerte in nur einem Feld zu speichern. Diese
Art der Speicherung kann unter Umständen sogar als die elegantere angesehen werden,
da z.B. für einen Datensatz weniger Speicher in der Datenbank benötigt wird.
</p>
        <p>
Um dies zu realisieren, wird als erstes ein Feld vom Typ „int“ in der Tabelle benötigt.
Dieses Feld dient als Datenspeicher für alle benötigten Optionswerte (Ja oder Nein).
Jedes Bit dieses „int“ Feldes stellt genau einen Optionswert und somit eine Option
dar. Um nun die gewählten Werte der Optionen speichern zu können, müssen diese mit
Bit-Operationen (right / left shift, binary and, etc.) in das „int“ Feld geschrieben
werden.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/TableBrowser.jpg" border="0" />
          <br />
Das Feld "bitMask" wird in dieser Darstellung als Datenspeicher der Optionswerte verwendet.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/Maske.jpg" border="0" />
          <br />
Auf einer Maske werden alle Optionen als einzelne CheckBoxen bereit gestellt.
</p>
        <p>
Da diese Art der Speicherung in Dynamics AX nicht besonders oft verwendet wird und
Quellcode oft mehr sagt als (nur) ein langer Artikel, habe ich ein kleines „Tutorial“
erstellt, um die benötigten Schritte zu beschreiben.
</p>
        <a href="http://blog.ak-home.net/content/binary/SharedProject_AKU_EnumControl_Frm.rar">SharedProject_AKU_EnumControl_Frm.rar
(2,03 KB)</a>
        <p>
Eine Erklärung aller Bit-Operatoren ist im <a href="http://msdn2.microsoft.com/en-us/library/aa870833.aspx">Microsoft
Dynamics AX Developer Center</a> zu finden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f4d824f5-434d-4b51-8bdb-671182f66cd5" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Speichern von Optionswerten</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,f4d824f5-434d-4b51-8bdb-671182f66cd5.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,f4d824f5-434d-4b51-8bdb-671182f66cd5.aspx</link>
      <pubDate>Mon, 05 May 2008 19:53:48 GMT</pubDate>
      <description>&lt;p&gt;
Häufig werden Optionen (Ja/Nein-Fragen) in Microsoft Dynamics AX durch ein CheckBox
Control und einem entsprechendem Feld einer Tabelle abgebildet. 
&lt;/p&gt;
&lt;p&gt;
Ein gutes Beispiel hierfür ist die Maske „Lagerparameter“, Reiter „Lagerungsdimensionen“.
Hier kann eingestellt werden, welche Lagerungsdimension wo im System angezeigt werden
soll. Zur Speicherung der gewählten Einstellungen wird die Tabelle „InventDimSetupGrid“
verwendet. Diese Tabelle enthält für jede Option jeweils ein Feld (abgeleitet vom
Enum „NoYes“).&lt;br&gt;
Diese Art der Speicherung von Optionswerten ist sicherlich sehr leicht zu verstehen
und auch sehr einfach zu erstellen. Da aber für jede Option ein Feld in der Tabelle
angelegt werden muss, kann dies relativ zeitaufwendig sein.
&lt;/p&gt;
&lt;p&gt;
Es besteht aber die Möglichkeit, Optionswerte in nur einem Feld zu speichern. Diese
Art der Speicherung kann unter Umständen sogar als die elegantere angesehen werden,
da z.B. für einen Datensatz weniger Speicher in der Datenbank benötigt wird.
&lt;/p&gt;
&lt;p&gt;
Um dies zu realisieren, wird als erstes ein Feld vom Typ „int“ in der Tabelle benötigt.
Dieses Feld dient als Datenspeicher für alle benötigten Optionswerte (Ja oder Nein).
Jedes Bit dieses „int“ Feldes stellt genau einen Optionswert und somit eine Option
dar. Um nun die gewählten Werte der Optionen speichern zu können, müssen diese mit
Bit-Operationen (right / left shift, binary and, etc.) in das „int“ Feld geschrieben
werden.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/TableBrowser.jpg" border=0&gt;
&lt;br&gt;
Das Feld "bitMask" wird in dieser Darstellung als Datenspeicher der Optionswerte verwendet.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/Maske.jpg" border=0&gt;
&lt;br&gt;
Auf einer Maske werden alle Optionen als einzelne CheckBoxen bereit gestellt.
&lt;/p&gt;
&lt;p&gt;
Da diese Art der Speicherung in Dynamics AX nicht besonders oft verwendet wird und
Quellcode oft mehr sagt als (nur) ein langer Artikel, habe ich ein kleines „Tutorial“
erstellt, um die benötigten Schritte zu beschreiben.
&lt;/p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/SharedProject_AKU_EnumControl_Frm.rar"&gt;SharedProject_AKU_EnumControl_Frm.rar
(2,03 KB)&lt;/a&gt; 
&lt;p&gt;
Eine Erklärung aller Bit-Operatoren ist im &lt;a href="http://msdn2.microsoft.com/en-us/library/aa870833.aspx"&gt;Microsoft
Dynamics AX Developer Center&lt;/a&gt; zu finden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f4d824f5-434d-4b51-8bdb-671182f66cd5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,f4d824f5-434d-4b51-8bdb-671182f66cd5.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung, Dynamics Ax/HowTo</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=f99cee2d-936e-4d86-93df-dca440272c57</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,f99cee2d-936e-4d86-93df-dca440272c57.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,f99cee2d-936e-4d86-93df-dca440272c57.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=f99cee2d-936e-4d86-93df-dca440272c57</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Im <a href="http://msdn.microsoft.com/en-us/dynamics/ax/cc507280.aspx">Microsoft Dynamics
AX Developer Center</a> wurde für Dynamics AX Entwickler eine neue Webcast Serie gestartet.
</p>
        <p>
Auszug:
</p>
        <p>
"On this page you will find videos designed for all Microsoft Dynamics AX developers,
from the novice to the professional. New videos are added regularly, so check back
often."
</p>
        <p>
Derzeit ist nur ein Webcast über "Dynamics Links between parent and child Forms"
erhältlich.<br />
Gilt zu hoffen, dass in der nächsten Zeit noch weitere nützliche Webcast folgen.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f99cee2d-936e-4d86-93df-dca440272c57" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>"How Do I" - Videos (Webcasts) im Microsoft Dynamics AX Developer Center</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,f99cee2d-936e-4d86-93df-dca440272c57.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,f99cee2d-936e-4d86-93df-dca440272c57.aspx</link>
      <pubDate>Fri, 02 May 2008 13:06:10 GMT</pubDate>
      <description>&lt;p&gt;
Im &lt;a href="http://msdn.microsoft.com/en-us/dynamics/ax/cc507280.aspx"&gt;Microsoft Dynamics
AX Developer Center&lt;/a&gt; wurde für Dynamics AX Entwickler eine neue Webcast Serie gestartet.
&lt;/p&gt;
&lt;p&gt;
Auszug:
&lt;/p&gt;
&lt;p&gt;
"On this page you will find videos designed for all Microsoft Dynamics AX developers,
from the novice to the professional. New videos are added regularly, so check back
often."
&lt;/p&gt;
&lt;p&gt;
Derzeit ist nur ein Webcast&amp;nbsp;über "Dynamics Links between parent and child Forms"
erhältlich.&lt;br&gt;
Gilt zu hoffen, dass in der nächsten Zeit noch weitere nützliche Webcast folgen.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=f99cee2d-936e-4d86-93df-dca440272c57" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,f99cee2d-936e-4d86-93df-dca440272c57.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=8245e6cb-2aa3-4ade-bc29-a7408bd6c157</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,8245e6cb-2aa3-4ade-bc29-a7408bd6c157.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,8245e6cb-2aa3-4ade-bc29-a7408bd6c157.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8245e6cb-2aa3-4ade-bc29-a7408bd6c157</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Das Erstellen von Produktionsaufträgen sollte an sich kein Problem darstellen. Leider
ist dem nicht ganz so.
</p>
        <p>
Anders als in anderen Modulen (z.B. Aufträge) von Dynamics AX, existiert hierfür keine
Klassenstruktur, welche die entsprechenden Funktionen bereit stellt.<br />
Der Dynamics AX Standard erstellt Produktionsaufträge immer über die Maske „ProdTableCreate“.
Es gibt aber Situationen, wo für die Erstellung eines Produktionsauftrages keine Maske
verwendet werden kann. Ein Beispiel hierfür könnte eine Schnittstelle sein, welche
über eine Textdatei die zu produzierenden Waren einließt und entsprechende Produktionsaufträge
im System generiert.
</p>
        <p>
Die Frage ist nun, wie erstellt man Produktionsaufträge per Quellcode, damit diese
auch „richtig“ im System erzeugt werden (inkl. Stückliste, Arbeitsplan und Lagerbuchung).
</p>
        <ul>
          <li>
Zuerst muss der Produktionsauftrag mit den Daten des zu produzierenden Artikels initialisiert
werden. 
</li>
          <li>
Weiterhin müssen Produktionsmenge und Lieferdatum festgelegt werden. 
</li>
          <li>
Ebenfalls sind die zu verwendende Stückliste und der Arbeitsplan zu definieren. 
</li>
          <li>
Und als letzter Schritt muss der Produktionsauftrag noch erzeugt werden.</li>
        </ul>
        <p>
Hierbei gilt es aber zu beachten, dass die Erstellung (Speichern in der Datenbank) nicht
mit der Methode „insert“ der Tabelle „ProdTable“ geschieht, sondern dass hierfür die
Klasse „ProdTableType“ und deren Methode „insert“ verwendet wird. Nur so wird die
entsprechende Lagerbewegung / Lagerbuchung im System erzeugt und wenn notwendig Referenzen
zu einem Verkaufsauftrag oder einer anderen Produktion hinterlegt.
</p>
        <p>
Um dies zu veranschaulichen ein kurzes Beispiel, in welchem ein neuer Produktionsauftrag
erstellt wird.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> CreateProductionOrder(Args
_args)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Die zu produzierende Menge</span><br />
    ProdQtySched productionQty <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Der zu produzierende Artikel</span><br />
    ItemId productionItem <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Artikelnummer"</span>;<br /><br />
    ProdTable prodTable;<br />
    InventTable inventTable;<br />
    ;<br />
    inventTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> InventTable::find(productionItem);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Initialisierung des Produktionsauftrags</span><br />
    prodTable.initValue();<br />
    prodTable.ItemId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> inventTable.ItemId;<br />
    prodTable.initFromInventTable(inventTable);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Lieferdatum festlegen</span><br />
    prodTable.DlvDate <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> today();<br /><br />
    prodTable.QtySched <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> productionQty;<br />
    prodTable.RemainInventPhysical <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> prodTable.QtySched;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Die zu verwendende Stückliste und Arbeitsplan bestimmen</span><br />
    prodTable.initRouteVersion();<br />
    prodTable.initBOMVersion();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//Produktionsauftrag erstellen</span><br />
    prodTable.type().insert();<br />
}</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" color="#003300" size="2">Selbstverständlich
sind auch weitere Angaben bei der Erstellung des Produktionsauftrags möglich.<br />
Z.B. kann ein Produktionsauftrag auch aus einer Verkaufsauftragsposition erzeugt werden
(bei Verwendung der Methode "initFromSalesLine").</font>
          </span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=8245e6cb-2aa3-4ade-bc29-a7408bd6c157" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Produktionsaufträge per Quellcode erstellen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,8245e6cb-2aa3-4ade-bc29-a7408bd6c157.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,8245e6cb-2aa3-4ade-bc29-a7408bd6c157.aspx</link>
      <pubDate>Sat, 12 Apr 2008 13:30:59 GMT</pubDate>
      <description>&lt;p&gt;
Das Erstellen von Produktionsaufträgen sollte an sich kein Problem darstellen. Leider
ist dem nicht ganz so.
&lt;/p&gt;
&lt;p&gt;
Anders als in anderen Modulen (z.B. Aufträge) von Dynamics AX, existiert hierfür keine
Klassenstruktur, welche die entsprechenden Funktionen bereit stellt.&lt;br&gt;
Der Dynamics AX Standard erstellt Produktionsaufträge immer über die Maske „ProdTableCreate“.
Es gibt aber Situationen, wo für die Erstellung eines Produktionsauftrages keine Maske
verwendet werden kann. Ein Beispiel hierfür könnte eine Schnittstelle sein, welche
über eine Textdatei die zu produzierenden Waren einließt und entsprechende Produktionsaufträge
im System generiert.
&lt;/p&gt;
&lt;p&gt;
Die Frage ist nun, wie erstellt man Produktionsaufträge per Quellcode, damit diese
auch „richtig“ im System erzeugt werden (inkl. Stückliste, Arbeitsplan und Lagerbuchung).
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Zuerst muss der Produktionsauftrag mit den Daten des zu produzierenden Artikels initialisiert
werden. 
&lt;li&gt;
Weiterhin müssen Produktionsmenge und Lieferdatum festgelegt werden. 
&lt;li&gt;
Ebenfalls sind die zu verwendende Stückliste und der Arbeitsplan zu definieren. 
&lt;li&gt;
Und als letzter Schritt muss der Produktionsauftrag noch erzeugt werden.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Hierbei gilt es aber zu beachten, dass&amp;nbsp;die Erstellung (Speichern in der Datenbank)&amp;nbsp;nicht
mit der Methode „insert“ der Tabelle „ProdTable“ geschieht, sondern dass hierfür die
Klasse „ProdTableType“ und deren Methode „insert“ verwendet wird. Nur so wird die
entsprechende Lagerbewegung / Lagerbuchung im System erzeugt und wenn notwendig Referenzen
zu einem Verkaufsauftrag oder einer anderen Produktion hinterlegt.
&lt;/p&gt;
&lt;p&gt;
Um dies zu veranschaulichen ein kurzes Beispiel, in welchem ein neuer Produktionsauftrag
erstellt wird.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; CreateProductionOrder(Args
_args)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Die zu produzierende Menge&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ProdQtySched productionQty &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Der zu produzierende Artikel&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ItemId productionItem &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Artikelnummer"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ProdTable prodTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; InventTable inventTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; inventTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; InventTable::find(productionItem);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Initialisierung des Produktionsauftrags&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.initValue();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.ItemId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; inventTable.ItemId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.initFromInventTable(inventTable);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Lieferdatum festlegen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.DlvDate &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; today();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.QtySched &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; productionQty;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.RemainInventPhysical &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; prodTable.QtySched;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Die zu verwendende Stückliste und Arbeitsplan bestimmen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.initRouteVersion();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.initBOMVersion();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//Produktionsauftrag erstellen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; prodTable.type().insert();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;Selbstverständlich
sind auch weitere Angaben&amp;nbsp;bei der&amp;nbsp;Erstellung des Produktionsauftrags möglich.&lt;br&gt;
Z.B. kann ein Produktionsauftrag auch aus einer Verkaufsauftragsposition erzeugt werden
(bei Verwendung der Methode "initFromSalesLine").&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=8245e6cb-2aa3-4ade-bc29-a7408bd6c157" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,8245e6cb-2aa3-4ade-bc29-a7408bd6c157.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=249a12dc-34c1-4dea-9abf-6e42217f4e0d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,249a12dc-34c1-4dea-9abf-6e42217f4e0d.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,249a12dc-34c1-4dea-9abf-6e42217f4e0d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=249a12dc-34c1-4dea-9abf-6e42217f4e0d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Das Buchen von Bestellungen in Microsoft Dynamics AX geschieht über die Klasse „PurchFormLetter“
bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung
oder Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse
„PurchFormLetter“ abgeleitet ist (siehe Abbildung).
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/PurchFormLetter.gif" border="0" />
        </p>
        <p>
Abbildung 1 - Klassenhierarchie der Klasse „PurchFormLetter“
</p>
        <p>
Vergleicht man die Klassenhierarchie der „PurchFormLetter“ Klassen mit der Klassenhierarchie
der „SalesFormLetter“ Klassen, so ist zu erkennen, dass auch das Buchen von Bestellungen
vom Prinzip her genau so funktioniert wie das Buchen von Aufträgen (Vergleiche hierzu: <a href="http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx">Microsoft
Dynamics AX API – Teil 3 „Buchen von Aufträgen“</a>).
</p>
        <p>
Deswegen sind auch für das Buchen von Bestellungen im Wesentlichen nur zwei Schritte
notwendig.
</p>
        <ol>
          <li>
Über die Methode „construct“ der Klasse „PurchFormLetter“ ein dem Buchungstyp einsprechendes
Objekt erzeugen. 
</li>
          <li>
Über den Aufruf der Methode „update“ die Bestellung buchen.</li>
        </ol>
        <p>
Hierzu ein Beispiel (Buchen des Lieferscheins für eine Bestellung):
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> PurchPostPackingSlip(Args
_args)<br />
{<br />
   PurchFormLetter purchFormLetter;<br />
   PurchTable purchTable;<br />
   PurchId purchId;<br />
   Num packingSlipId;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Angabe
der Bestellung, für welche der Lieferschein gebucht werden soll.</span><br />
   purchId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"00244_049"</span>;<br />
   purchTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> PurchTable::find(purchId);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestimmen
des Buchungstyps durch Angabe des DocumentStatus (Lieferschein).</span><br />
   purchFormLetter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> PurchFormLetter::construct(DocumentStatus::PackingSlip);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Festlegen
der externen Lieferscheinnummer.</span><br />
   packingSlipId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"EXT-100155L"</span>;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Buchen
des Lieferscheins.</span><br />
   purchFormLetter.update(purchTable,<br />
                          packingSlipId,<br />
                          SystemDateGet(),<br />
                          PurchUpdate::All,<br />
                          AccountOrder::Auto,<br />
                          NoYes::No,<br />
                          NoYes::No,<br />
                          NoYes::No,<br />
                          NoYes::No);<br />
}</span>
        </p>
        <p>
Einziger Unterschied zu den Auftragsbuchen ist, dass bei der Buchung einer Bestellung
die „externe“ Nummer des Belegs (Lieferscheinnummer, Rechnungsnummer, etc.) angegeben
werden muss.
</p>
        <p>
Analog zu den Auftragsbuchen, sind auch beim Buchen von Bestellungen umfangreichere
oder etwas speziellere Buchungsszenarien möglich (Vergleiche hierzu: <a href="http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx">Microsoft
Dynamics AX API – Teil 3 „Buchen von Aufträgen“</a>).
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=249a12dc-34c1-4dea-9abf-6e42217f4e0d" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX API – Teil 4 „Buchen von Bestellungen“</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,249a12dc-34c1-4dea-9abf-6e42217f4e0d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,249a12dc-34c1-4dea-9abf-6e42217f4e0d.aspx</link>
      <pubDate>Sat, 26 Jan 2008 14:12:18 GMT</pubDate>
      <description>&lt;p&gt;
Das Buchen von Bestellungen in Microsoft Dynamics AX geschieht über die Klasse „PurchFormLetter“
bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung
oder Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse
„PurchFormLetter“ abgeleitet ist (siehe Abbildung).
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/PurchFormLetter.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Abbildung 1 - Klassenhierarchie der Klasse „PurchFormLetter“
&lt;/p&gt;
&lt;p&gt;
Vergleicht man die Klassenhierarchie der „PurchFormLetter“ Klassen mit der Klassenhierarchie
der „SalesFormLetter“ Klassen, so ist zu erkennen, dass auch das Buchen von Bestellungen
vom Prinzip her genau so funktioniert wie das Buchen von Aufträgen (Vergleiche hierzu: &lt;a href="http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx"&gt;Microsoft
Dynamics AX API – Teil 3 „Buchen von Aufträgen“&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Deswegen sind auch für das Buchen von Bestellungen im Wesentlichen nur zwei Schritte
notwendig.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Über die Methode „construct“ der Klasse „PurchFormLetter“ ein dem Buchungstyp einsprechendes
Objekt erzeugen. 
&lt;li&gt;
Über den Aufruf der Methode „update“ die Bestellung buchen.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Hierzu ein Beispiel (Buchen des Lieferscheins für eine Bestellung):
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; PurchPostPackingSlip(Args
_args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchFormLetter purchFormLetter;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchTable purchTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchId purchId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Num packingSlipId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Angabe
der Bestellung, für welche der Lieferschein gebucht werden soll.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"00244_049"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; PurchTable::find(purchId);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestimmen
des Buchungstyps durch Angabe des DocumentStatus (Lieferschein).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchFormLetter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; PurchFormLetter::construct(DocumentStatus::PackingSlip);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Festlegen
der externen Lieferscheinnummer.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;packingSlipId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"EXT-100155L"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Buchen
des Lieferscheins.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchFormLetter.update(purchTable,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packingSlipId,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SystemDateGet(),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchUpdate::All,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AccountOrder::Auto,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Einziger Unterschied zu den Auftragsbuchen ist, dass bei der Buchung einer Bestellung
die „externe“ Nummer des Belegs (Lieferscheinnummer, Rechnungsnummer, etc.) angegeben
werden muss.
&lt;/p&gt;
&lt;p&gt;
Analog zu den Auftragsbuchen, sind auch beim Buchen von Bestellungen umfangreichere
oder etwas speziellere Buchungsszenarien möglich (Vergleiche hierzu: &lt;a href="http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx"&gt;Microsoft
Dynamics AX API – Teil 3 „Buchen von Aufträgen“&lt;/a&gt;).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=249a12dc-34c1-4dea-9abf-6e42217f4e0d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,249a12dc-34c1-4dea-9abf-6e42217f4e0d.aspx</comments>
      <category>Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=c1798182-de60-4146-85ed-06035d74c6c6</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c1798182-de60-4146-85ed-06035d74c6c6</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Für ein Grid-Control kann über die Einstellung "MultiSelect" gesteuert werden, od
dieses Control die Auswahl von mehr als einem Datensatz erlaubt.
</p>
        <p>
Gültige Einstellungen sind:<br />
Yes - Es können mehrere Datensätze ausgewählt werden.<br />
No - Es kann immer nur ein Datensatz ausgewählt werden.
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedOneRecord_2.jpg">
            <img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="82" alt="GridSelectedOneRecord" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedOneRecord_thumb.jpg" width="244" border="0" />
          </a>
          <br />
Auswahl eines Datensatzes
</p>
        <p>
          <a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedMultipleRecords_2.jpg">
            <img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="115" alt="GridSelectedMultipleRecords" src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedMultipleRecords_thumb.jpg" width="244" border="0" />
          </a>
          <br />
Auswahl mehrerer Datensätze
</p>
        <p>
Zugriff auf die aktuelle Selektion (einer oder mehrere) erhält man wie folgt beschrieben:
</p>
        <p>
Ist nur ein Datensatz markiert, bzw. soll mit einfacher Auswahl gearbeitet werden
(MultiSelect = No), kann der ausgewählte Datensatz über den aktuellen DataSource-Cursor
der Grid-Control DataSource ermittelt werden.<br />
Der DataSource-Cursor steht immer auf dem zu letzt ausgewählten Datensatz eines Grid-Control's.
</p>
        <p>
Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> clicked()<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //CustTable
ist die DataSource des Grid-Controls </span><br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Datenoperationen
für den Datensatz ausführen.</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Do
something....</span><br />
   info(CustTable.AccountNum);   <br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Angezeigte
Datensätze im Grid Control aktualisieren</span><br />
   element.lockWindowUpdate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
   CustTable_ds.research();<br />
   element.lockWindowUpdate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
}<br /></span>
        </p>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Soll eine Mehrfachauswahl möglich sein, reicht der Zugriff auf den aktuellen DataSource-Cursor
nicht mehr aus. Um alle ausgewählten Datensätze der DataSource zu erhalten, muss diese
mit einer Schleife unter Verwendung der Methoden "getFirst" und "getNext" durchlaufen
werden. Hilfreich hierbei ist die Methode "anyMarked", mit welcher ermittelt werden
kann ob mehrere Datensätze ausgewählt sind oder nicht.
</p>
        <p>
Auch hierfür ein Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> clicked()<br />
{<br />
   CustTable selectedCustTable;<br />
   Common currentRecord;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   if</span> (CustTable_ds.anyMarked()) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Es
sind meherer Datensätze selektiert.</span><br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      //Ersten
selektierten Datensatz ermitteln.</span><br />
      selectedCustTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.getFirst(1);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      while</span>(selectedCustTable)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         //Datenoperationen
für den Datensatz ausführn.</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         //Do
something....</span><br />
         info(selectedCustTable.AccountNum);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         //Nächsten
selektieren Datensatz ermitteln.</span><br />
         selectedCustTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.getNext();<br />
      }<br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   else</span><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Nur
ein Datensatz ist selektiert.</span><br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      //Selektierten
Datensatz ermitteln.</span><br />
      currentRecord <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.cursor().data();<br />
      selectedCustTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CustTable_ds.cursor();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      //Datenoperationen
für den Datensatz ausführen.</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      //Do
something....</span><br />
      info(selectedCustTable.AccountNum);<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Angezeigte
Datensätze im Grid Control aktualisieren   </span><br />
   element.lockWindowUpdate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
   CustTable_ds.research();<br />
   CustTable_ds.findRecord(currentRecord);<br />
   CustTable_ds.refresh();<br />
   element.lockWindowUpdate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
}<br /></span>
        </p>
        <div class="wlWriterSmartContent" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:88a38c7a-9239-4f4e-bead-9888f3b5b81a" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px">
          <p>
Der Quellcode des Beispiels:<br /></p>
        </div>
        <a href="http://blog.ak-home.net/content/binary/Form_GridSelectedRecords.xpo">Form_GridSelectedRecords.xpo
(6.2 KB)</a>
        <p>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=c1798182-de60-4146-85ed-06035d74c6c6" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Auswahl von mehreren Datens&amp;auml;tzen in einem Grid-Control (MultiSelect)</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx</link>
      <pubDate>Wed, 02 Jan 2008 20:39:57 GMT</pubDate>
      <description>&lt;p&gt;
Für ein Grid-Control kann über die Einstellung "MultiSelect" gesteuert werden, od
dieses Control die Auswahl von mehr als einem Datensatz erlaubt.
&lt;/p&gt;
&lt;p&gt;
Gültige Einstellungen sind:&lt;br&gt;
Yes - Es können mehrere Datensätze ausgewählt werden.&lt;br&gt;
No - Es kann immer nur ein Datensatz ausgewählt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedOneRecord_2.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=82 alt=GridSelectedOneRecord src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedOneRecord_thumb.jpg" width=244 border=0&gt;&lt;/a&gt; 
&lt;br&gt;
Auswahl eines Datensatzes
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedMultipleRecords_2.jpg"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=115 alt=GridSelectedMultipleRecords src="http://blog.ak-home.net/content/binary/WindowsLiveWriter/67f84a96e997_1389C/GridSelectedMultipleRecords_thumb.jpg" width=244 border=0&gt;&lt;/a&gt; 
&lt;br&gt;
Auswahl mehrerer Datensätze
&lt;/p&gt;
&lt;p&gt;
Zugriff auf die aktuelle Selektion (einer oder mehrere) erhält man wie folgt beschrieben:
&lt;/p&gt;
&lt;p&gt;
Ist nur ein Datensatz markiert, bzw. soll mit einfacher Auswahl gearbeitet werden
(MultiSelect = No), kann der ausgewählte Datensatz über den aktuellen DataSource-Cursor
der Grid-Control DataSource ermittelt werden.&lt;br&gt;
Der DataSource-Cursor steht immer auf dem zu letzt ausgewählten Datensatz eines Grid-Control's.
&lt;/p&gt;
&lt;p&gt;
Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; clicked()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//CustTable
ist die DataSource des Grid-Controls&amp;nbsp;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Datenoperationen
für den Datensatz ausführen.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Do
something....&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;info(CustTable.AccountNum);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Angezeigte
Datensätze im Grid Control aktualisieren&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;element.lockWindowUpdate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable_ds.research();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;element.lockWindowUpdate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;style type=text/css&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Soll eine Mehrfachauswahl möglich sein, reicht der Zugriff auf den aktuellen DataSource-Cursor
nicht mehr aus. Um alle ausgewählten Datensätze der DataSource zu erhalten, muss diese
mit einer Schleife unter Verwendung der Methoden "getFirst" und "getNext" durchlaufen
werden. Hilfreich hierbei ist die Methode "anyMarked", mit welcher ermittelt werden
kann ob mehrere Datensätze ausgewählt sind oder nicht.
&lt;/p&gt;
&lt;p&gt;
Auch hierfür ein Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; clicked()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable selectedCustTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Common currentRecord;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (CustTable_ds.anyMarked()) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Es
sind meherer Datensätze selektiert.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Ersten
selektierten Datensatz ermitteln.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedCustTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.getFirst(1);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/span&gt;(selectedCustTable)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Datenoperationen
für den Datensatz ausführn.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Do
something....&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info(selectedCustTable.AccountNum);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Nächsten
selektieren Datensatz ermitteln.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedCustTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.getNext();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Nur
ein Datensatz ist selektiert.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Selektierten
Datensatz ermitteln.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentRecord &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.cursor().data();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedCustTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CustTable_ds.cursor();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Datenoperationen
für den Datensatz ausführen.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Do
something....&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info(selectedCustTable.AccountNum);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Angezeigte
Datensätze im Grid Control aktualisieren&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;element.lockWindowUpdate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable_ds.research();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable_ds.findRecord(currentRecord);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable_ds.refresh();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;element.lockWindowUpdate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;div class=wlWriterSmartContent id=scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:88a38c7a-9239-4f4e-bead-9888f3b5b81a style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;p&gt;
Der Quellcode des Beispiels:&lt;br&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;a href="http://blog.ak-home.net/content/binary/Form_GridSelectedRecords.xpo"&gt;Form_GridSelectedRecords.xpo
(6.2 KB)&lt;/a&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=c1798182-de60-4146-85ed-06035d74c6c6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,c1798182-de60-4146-85ed-06035d74c6c6.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=35e4fcc9-ee88-4407-bd10-6fb758baac84</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,35e4fcc9-ee88-4407-bd10-6fb758baac84.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,35e4fcc9-ee88-4407-bd10-6fb758baac84.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=35e4fcc9-ee88-4407-bd10-6fb758baac84</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Von Zeit zu Zeit ist es hilfreich sich den Abfragebefehl, der durch eine Query erzeugt
wird, zur Laufzeit anzusehen.
</p>
        <p>
Leider unterstützt der Debugger von Microsoft Dynamics AX das Debuggen von Querys
nicht. Ein Datenbanktrace durchzuführen ist auch nicht immer sinnvoll, da man
durch das Traceprotokoll keine direkte "Verbindung" von Abfragebefehl und Query einsehen
kann.
</p>
        <p>
Einen Workaround hierfür gibt es aber.
</p>
        <p>
Die Methode "toString" einer Query DataSource gibt den Abfragbefehl, der durch die
Query an die Datenbank geschickt wird, zurück. Dieser kann dann, durch die statischen
Methoden des "Debug" Objekts, im Debuggers ausgegeben bzw. angezeigt werden.
</p>
        <p>
Ein Beispiel:
</p>
        <p>
debug::printDebug(query.dataSourceTable(tablenum(CustTable)).toString())
</p>
        <p>
Weiterhin ist unter <a href="http://www.axaptapedia.com/DEV_QueryBrowser">http://www.axaptapedia.com/DEV_QueryBrowser</a> ein
Tool für die Analyse von Querys erhältlich. Dieses Tool funktioniert ähnlich wie der
Tablebrowser von Dynamics AX. Mit dem Tool können nicht nur der Abfragebefehl, der
durch eine Query erstellt wird, sondern auch die von der Query ermittelten Daten
betrachtet und ausgewertet werden.
</p>
        <p>
Eine ausreichende Beschreibung zur Verwendung des Tool's ist ebenfalls auf Axaptapedia
(siehe Link weiter oben) zu finden.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35e4fcc9-ee88-4407-bd10-6fb758baac84" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Debuggen von Queries</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,35e4fcc9-ee88-4407-bd10-6fb758baac84.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,35e4fcc9-ee88-4407-bd10-6fb758baac84.aspx</link>
      <pubDate>Thu, 27 Dec 2007 14:40:11 GMT</pubDate>
      <description>&lt;p&gt;
Von Zeit zu Zeit ist es hilfreich sich den Abfragebefehl, der durch eine Query erzeugt
wird, zur Laufzeit anzusehen.
&lt;/p&gt;
&lt;p&gt;
Leider unterstützt der Debugger von Microsoft Dynamics AX&amp;nbsp;das Debuggen von Querys
nicht.&amp;nbsp;Ein Datenbanktrace durchzuführen ist auch nicht immer sinnvoll, da man
durch das Traceprotokoll keine direkte "Verbindung" von Abfragebefehl und Query einsehen
kann.
&lt;/p&gt;
&lt;p&gt;
Einen Workaround hierfür gibt es aber.
&lt;/p&gt;
&lt;p&gt;
Die Methode "toString" einer Query DataSource gibt den Abfragbefehl, der durch die
Query an die Datenbank geschickt wird, zurück. Dieser kann dann, durch die statischen
Methoden des "Debug" Objekts, im Debuggers ausgegeben bzw. angezeigt&amp;nbsp;werden.
&lt;/p&gt;
&lt;p&gt;
Ein Beispiel:
&lt;/p&gt;
&lt;p&gt;
debug::printDebug(query.dataSourceTable(tablenum(CustTable)).toString())
&lt;/p&gt;
&lt;p&gt;
Weiterhin ist unter &lt;a href="http://www.axaptapedia.com/DEV_QueryBrowser"&gt;http://www.axaptapedia.com/DEV_QueryBrowser&lt;/a&gt;&amp;nbsp;ein
Tool für die Analyse von Querys erhältlich. Dieses Tool funktioniert ähnlich wie der
Tablebrowser von Dynamics AX. Mit dem Tool können nicht nur der Abfragebefehl, der
durch eine&amp;nbsp;Query erstellt wird, sondern auch die von der Query ermittelten Daten
betrachtet und ausgewertet werden.
&lt;/p&gt;
&lt;p&gt;
Eine ausreichende Beschreibung zur Verwendung des Tool's ist ebenfalls auf Axaptapedia
(siehe Link weiter oben) zu finden.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35e4fcc9-ee88-4407-bd10-6fb758baac84" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,35e4fcc9-ee88-4407-bd10-6fb758baac84.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Tools</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=80c59760-ceac-47f2-a69a-77bfec91aa5c</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,80c59760-ceac-47f2-a69a-77bfec91aa5c.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,80c59760-ceac-47f2-a69a-77bfec91aa5c.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=80c59760-ceac-47f2-a69a-77bfec91aa5c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Einen ersten Ausblick auf die "neuen" Quellcodeverwaltungsfeatures in Microsoft Dynamics
AX 5.0 zeigt der Screencast "Version control in MorphX" auf Channel9.
</p>
        <p>
          <a href="http://channel9.msdn.com/Showpost.aspx?postid=367024">http://channel9.msdn.com/Showpost.aspx?postid=367024</a>
        </p>
        <p>
Ich zitiere:<br />
"﻿This screencast is a preview of the version control system integration options in
the next release of MorphX - the IDE of Dynamics AX.<br />
It shows a side-by-side comparison of the integration options with Team
Foundation Server, Visual Source Safe, and MorphX VCS. <br />
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."
</p>
        <p>
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.
</p>
        <p>
Vielen Dank an dieser Stelle an Michael Fruergaard Pontoppidan (<a href="http://blogs.msdn.com/mfp/default.aspx">http://blogs.msdn.com/mfp/default.aspx</a>)
für diesen und die bisherigen Screencasts über Microsoft Dynamics AX. 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=80c59760-ceac-47f2-a69a-77bfec91aa5c" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Quellcodeverwaltung mit Dynamics AX 5.0</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,80c59760-ceac-47f2-a69a-77bfec91aa5c.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,80c59760-ceac-47f2-a69a-77bfec91aa5c.aspx</link>
      <pubDate>Wed, 19 Dec 2007 19:24:13 GMT</pubDate>
      <description>&lt;p&gt;
Einen ersten Ausblick auf die "neuen" Quellcodeverwaltungsfeatures in Microsoft Dynamics
AX 5.0 zeigt der Screencast "Version control in MorphX" auf Channel9.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=367024"&gt;http://channel9.msdn.com/Showpost.aspx?postid=367024&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Ich zitiere:&lt;br&gt;
"﻿This screencast is a preview of the version control system integration options in
the next release of MorphX - the&amp;nbsp;IDE of Dynamics AX.&lt;br&gt;
It shows a side-by-side comparison&amp;nbsp;of the integration options&amp;nbsp;with Team
Foundation Server, Visual Source Safe, and MorphX VCS.&amp;nbsp;&lt;br&gt;
The latter is&amp;nbsp;a simple, yet powerful alternative without any additional infrastructure
requirements. The last half of the screencast gives a demonstration of MorphX VCS."
&lt;/p&gt;
&lt;p&gt;
Durch die neuen Features die MorphX VCS mit sich bringt, sowie die Möglichkeit Visual
Studio Team System, oder genauer der Team Foundation Server,&amp;nbsp;(nicht nur) als
Quellcodeverwaltung zu verwenden, sollte nun für jeden ein "passendes" Quellcodeverwaltungsystem
bereit stehen.
&lt;/p&gt;
&lt;p&gt;
Vielen Dank an dieser Stelle an Michael Fruergaard Pontoppidan (&lt;a href="http://blogs.msdn.com/mfp/default.aspx"&gt;http://blogs.msdn.com/mfp/default.aspx&lt;/a&gt;)
für diesen und die bisherigen Screencasts über Microsoft Dynamics AX.&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=80c59760-ceac-47f2-a69a-77bfec91aa5c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,80c59760-ceac-47f2-a69a-77bfec91aa5c.aspx</comments>
      <category>Allgemein;Dynamics Ax;Dynamics Ax/Administration;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=fd2880c2-3f25-4219-ac8d-0c7f71e1690e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,fd2880c2-3f25-4219-ac8d-0c7f71e1690e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,fd2880c2-3f25-4219-ac8d-0c7f71e1690e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=fd2880c2-3f25-4219-ac8d-0c7f71e1690e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Die Version 4.0 von Microsoft Dynamics AX enthält eine neue Funktion ("Nach Raster
filtern" oder "Filter by Grid") mit der die Datenfilterung direkt in einem Grid ermöglicht
wird.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/nachrasterfiltern.jpg" border="0" />
        </p>
        <p>
Die Funktion "Nach Raster Filtern" kann entweder über die Tastenkombination "STRG
+ G", über die Symbolleiste oder den Menüpunkt "Bearbeiten - Filtern - Nach Raster
filtern" aktiviert werden.
</p>
        <p>
Das "Nach Raster filtern" ist per Standard deaktiviert und muss somit immer manuell
durch den Benutzer aktiviert werden. Leider wird in den benutzerspezifischen
Einstellungen für eine Maske nicht gespeichert ob das "Nach Raster filtern" aktiviert
oder deaktiviert ist. Somit muss die Funktion, wenn diese verwendet werden soll, für
jede Maske und nach jedem Schließen einer Maske erneut aktiviert werden.
</p>
        <p>
Soll nun für eine Maske die Funktion "Nach Raster filtern" dauerhaft aktiviert sein,
ist eine kleine Anpassung im Quelltext der Maske notwendig.
</p>
        <p>
Als erstes muss die Eigenschaft "AutoDeclaration" für das Grid Control, bei welchem
die Funktion "Nach Raster filtern" aktiviert werden soll, auf "Yes" gesetzt werden.
Weiterhin muss die Methode "run" der Maske, nach dem Aufruf von "super", um diese
Quellcodezeilen ergänzt werden:
</p>
        <p>
Grid.enter();<br />
this.task(2855);
</p>
        <p>
"Grid" ist hierbei der Name des Grid Controls, für welches die Funktion "Nach Raster
filtern" aktiviert werden soll.
</p>
        <p>
Soll gleichzeitig noch ein Filter für die Datensätze aktiviert werden, erfolgt
dies über die Ranges der Datasource-Querys. Hierbei kann wie gewohnt eine Range
für die entsprechende Query definiert werden. Wird die Range für ein Feld gesetzt,
welches in dem Grid Control angezeigt wird, wird der Wert der Range entsprechend in
der "Filterzeile" angezeigt.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=fd2880c2-3f25-4219-ac8d-0c7f71e1690e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Nach Raster filtern per Quelltext aktivieren</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,fd2880c2-3f25-4219-ac8d-0c7f71e1690e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,fd2880c2-3f25-4219-ac8d-0c7f71e1690e.aspx</link>
      <pubDate>Fri, 14 Dec 2007 17:38:30 GMT</pubDate>
      <description>&lt;p&gt;
Die&amp;nbsp;Version 4.0 von Microsoft Dynamics AX enthält eine neue Funktion ("Nach Raster
filtern" oder "Filter by Grid") mit der die Datenfilterung direkt in einem Grid ermöglicht
wird.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/nachrasterfiltern.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Die Funktion "Nach Raster Filtern" kann entweder über die Tastenkombination "STRG
+ G", über die Symbolleiste oder den Menüpunkt "Bearbeiten - Filtern - Nach Raster
filtern" aktiviert werden.
&lt;/p&gt;
&lt;p&gt;
Das "Nach Raster filtern" ist per Standard deaktiviert und muss somit immer manuell
durch den Benutzer aktiviert werden.&amp;nbsp;Leider wird in den benutzerspezifischen
Einstellungen&amp;nbsp;für eine Maske nicht gespeichert ob das "Nach Raster filtern" aktiviert
oder deaktiviert ist. Somit&amp;nbsp;muss die Funktion, wenn diese verwendet werden soll,&amp;nbsp;für
jede Maske und nach jedem Schließen einer Maske erneut aktiviert werden.
&lt;/p&gt;
&lt;p&gt;
Soll nun für eine Maske die Funktion "Nach Raster filtern" dauerhaft aktiviert sein,
ist eine kleine Anpassung im Quelltext der Maske notwendig.
&lt;/p&gt;
&lt;p&gt;
Als erstes muss die Eigenschaft "AutoDeclaration" für das Grid Control, bei welchem
die Funktion "Nach Raster filtern" aktiviert werden soll, auf "Yes" gesetzt werden.
Weiterhin muss die Methode "run" der Maske, nach dem Aufruf von "super", um diese
Quellcodezeilen ergänzt werden:
&lt;/p&gt;
&lt;p&gt;
Grid.enter();&lt;br&gt;
this.task(2855);
&lt;/p&gt;
&lt;p&gt;
"Grid" ist hierbei der Name des Grid Controls, für welches die Funktion "Nach Raster
filtern" aktiviert werden soll.
&lt;/p&gt;
&lt;p&gt;
Soll&amp;nbsp;gleichzeitig noch ein Filter für die Datensätze aktiviert werden, erfolgt
dies über die Ranges der Datasource-Querys. Hierbei kann wie gewohnt eine&amp;nbsp;Range
für die entsprechende Query definiert werden.&amp;nbsp;Wird die Range für ein Feld gesetzt,
welches in dem Grid Control angezeigt wird, wird der Wert der Range entsprechend in
der "Filterzeile" angezeigt.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=fd2880c2-3f25-4219-ac8d-0c7f71e1690e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,fd2880c2-3f25-4219-ac8d-0c7f71e1690e.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=a2a673b5-22eb-430f-8d46-ef38a5f28169</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,a2a673b5-22eb-430f-8d46-ef38a5f28169.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,a2a673b5-22eb-430f-8d46-ef38a5f28169.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=a2a673b5-22eb-430f-8d46-ef38a5f28169</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
Jeder der sich mit dem Thema schon einmal auseinander setzen musste, wird mit hoher
Wahrscheinlichkeit auf eines dieser „Probleme“ gestoßen sein:
</p>
        <ul>
          <li>
Wie kann ein Datum zwischen Dynamics AX und .NET ausgetauscht werden? 
</li>
          <li>
Wie kann die aktuelle Zeit an ein .NET Objekt übermittelt werden? 
</li>
          <li>
Wie rufe ich eigentlich Werte eines .NET Enums ab?</li>
        </ul>
        <p>
Diese Liste könnte man noch beliebig erweitern.
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/Referenc_hinzufuegen.jpg" border="0" />
        </p>
        <p>
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.
</p>
        <p>
Bei diesem Beispiel wurde eine Referenz zur Assembly „Microsoft.Office.Interop.Outlook“
erstellt.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/Add_reference_to_Assembly.jpg" border="0" />
        </p>
        <p>
Ab jetzt können alle .NET Objekte, die in dieser Assembly enthalten sind, in Dynamics
AX verwendet werden.
</p>
        <p>
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.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> CreateOutlookAppointment(Args
_args)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //.NET
(CLR) Datentypen</span><br />
   InteropPermission permission;<br />
   Microsoft.Office.Interop.Outlook._Application outlookApplication;<br />
   Microsoft.Office.Interop.Outlook._AppointmentItem outlookAppointment;<br />
   Microsoft.Office.Interop.Outlook.OlItemType outlookItemType;<br />
   System.DateTime appointmentStartTime;<br />
   System.DateTime appointmentEndTime;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Dynamics
AX Datentypen</span><br />
   Date1980 startDate, endDate;<br />
   TimeExpected startTime, endTime;<br />
   ;<br />
   permission <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> InteropPermission(InteropKind::ClrInterop);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   if</span> (permission
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      return</span>;<br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //”Unsichere”
Aufrufe starten</span><br />
   permission.assert();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Das
Outlook Application Objekt instanzieren</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //(Beispiel
für Erstellung eines .NET Klassenobjekts)</span><br />
   outlookApplication <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Microsoft.Office.Interop.Outlook.ApplicationClass();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Gewünschten
Outlook-Elementtyp auswählen</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //(Beispiel
für Zuweisung eines .NET Enum Wertes)</span><br />
   outlookItemType <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">= </span>ClrInterop::parseClrEnum('Microsoft.Office.Interop.Outlook.OlItemType',
'olAppointmentItem');<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Gewünschten
Outlook-Elemnttyp erstellen (Termin)</span><br />
   outlookAppointment <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> outlookApplication.CreateItem(outlookItemType);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Den
Betreff zuweisen</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //(Beispiel
für Zuweisung eines "einfachen" Wertes)</span><br />
   outlookAppointment.set_Subject(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Ein
Test aus Dynamics AX"</span>);<br /><br />
   startDate <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> str2Date(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"25.10.2007"</span>,
123);<br />
   startTime <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> str2Time(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"10:30:00"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //"Beginnt
um" zuweisen</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //(Beispiel
für Konvertierung Dynamics AX Datum/Zeit -&gt; .NET DateTime)</span><br />
   appointmentStartTime <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">= </span>System.Convert::ToDateTime(strfmt(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"%1
%2"</span>, startDate, time2str(startTime, 0, 0)));<br />
   outlookAppointment.set_Start(appointmentStartTime);<br /><br />
   endDate <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> str2Date(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"26.10.2007"</span>,
123);<br />
   endTime <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> str2Time(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"11:00:00"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //"Endet
um" zuweisen</span><br />
   appointmentEndTime <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">= </span>System.Convert::ToDateTime(strfmt(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"%1
%2"</span>, endDate, time2str(endTime, 0, 0)));<br />
   outlookAppointment.set_End(appointmentEndTime);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Den
Termin speichern (ab jetzt ist der Termin in Outlook zu sehen)</span><br />
   outlookAppointment.Save();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //”Unsichere”
Aufrufe beenden</span><br />
   CodeAccessPermission::revertAssert();<br />
}</span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=a2a673b5-22eb-430f-8d46-ef38a5f28169" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX und .NET - Erstellen eines Termins in Outlook</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,a2a673b5-22eb-430f-8d46-ef38a5f28169.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,a2a673b5-22eb-430f-8d46-ef38a5f28169.aspx</link>
      <pubDate>Fri, 02 Nov 2007 17:06:11 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Jeder der sich mit dem Thema schon einmal auseinander setzen musste, wird mit hoher
Wahrscheinlichkeit auf eines dieser „Probleme“ gestoßen sein:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Wie kann ein Datum zwischen Dynamics AX und .NET ausgetauscht werden? 
&lt;li&gt;
Wie kann die aktuelle Zeit an ein .NET Objekt übermittelt werden? 
&lt;li&gt;
Wie rufe ich eigentlich Werte eines .NET Enums ab?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Diese Liste könnte man noch beliebig erweitern.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/Referenc_hinzufuegen.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Bei diesem Beispiel wurde eine Referenz zur Assembly „Microsoft.Office.Interop.Outlook“
erstellt.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/Add_reference_to_Assembly.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Ab jetzt können alle .NET Objekte, die in dieser Assembly enthalten sind, in Dynamics
AX verwendet werden.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; CreateOutlookAppointment(Args
_args)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//.NET
(CLR) Datentypen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;InteropPermission permission;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft.Office.Interop.Outlook._Application outlookApplication;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft.Office.Interop.Outlook._AppointmentItem outlookAppointment;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Microsoft.Office.Interop.Outlook.OlItemType outlookItemType;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;System.DateTime appointmentStartTime;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;System.DateTime appointmentEndTime;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Dynamics
AX Datentypen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Date1980 startDate, endDate;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;TimeExpected startTime, endTime;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;permission &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; InteropPermission(InteropKind::ClrInterop);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (permission
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//”Unsichere”
Aufrufe starten&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;permission.assert();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Das
Outlook Application Objekt instanzieren&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//(Beispiel
für Erstellung eines .NET Klassenobjekts)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookApplication &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Microsoft.Office.Interop.Outlook.ApplicationClass();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Gewünschten
Outlook-Elementtyp auswählen&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//(Beispiel
für Zuweisung eines .NET Enum Wertes)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookItemType &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;= &lt;/span&gt;ClrInterop::parseClrEnum('Microsoft.Office.Interop.Outlook.OlItemType',
'olAppointmentItem');&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Gewünschten
Outlook-Elemnttyp erstellen (Termin)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookAppointment &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; outlookApplication.CreateItem(outlookItemType);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Den
Betreff zuweisen&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//(Beispiel
für Zuweisung eines "einfachen" Wertes)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookAppointment.set_Subject(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Ein
Test aus Dynamics AX"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;startDate &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; str2Date(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"25.10.2007"&lt;/span&gt;,
123);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;startTime &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; str2Time(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"10:30:00"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//"Beginnt
um" zuweisen&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//(Beispiel
für Konvertierung Dynamics AX Datum/Zeit -&amp;gt; .NET DateTime)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;appointmentStartTime &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;= &lt;/span&gt;System.Convert::ToDateTime(strfmt(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"%1
%2"&lt;/span&gt;, startDate, time2str(startTime, 0, 0)));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookAppointment.set_Start(appointmentStartTime);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;endDate &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; str2Date(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"26.10.2007"&lt;/span&gt;,
123);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;endTime &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; str2Time(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"11:00:00"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//"Endet
um" zuweisen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;appointmentEndTime &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;= &lt;/span&gt;System.Convert::ToDateTime(strfmt(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"%1
%2"&lt;/span&gt;, endDate, time2str(endTime, 0, 0)));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookAppointment.set_End(appointmentEndTime);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Den
Termin speichern (ab jetzt ist der Termin in Outlook zu sehen)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;outlookAppointment.Save();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//”Unsichere”
Aufrufe beenden&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeAccessPermission::revertAssert();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=a2a673b5-22eb-430f-8d46-ef38a5f28169" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,a2a673b5-22eb-430f-8d46-ef38a5f28169.aspx</comments>
      <category>.NET;Dynamics Ax/HowTo;Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=5cb22557-acb4-41ec-9546-c65d681e3a3d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5cb22557-acb4-41ec-9546-c65d681e3a3d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Das Buchen von Aufträgen in Microsoft Dynamics AX geschieht über die Klasse „SalesFormLetter“
bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung,
Lieferschein, Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse
„SalesFormLetter“ abgeleitet ist (siehe Abbildung).
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/SalesFormLetter.gif" border="0" />
        </p>
        <p>
Um einen Auftrag per Programmcode zu buchen, muss ein Objekt der Klasse „SalesFormLetter“
erstellt werden.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">salesFormLetter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SalesFormLetter::construct(DocumentStatus::Confirmation);</span>
        </p>
        <p>
Dies geschieht, wie Allgemein in Microsoft Dynamics AX üblich, über die “construct”
Methode der Klasse. Als Parameter muss dieser Methode die gewünschte Art der Buchung
(z.B. Bestätigung, Lieferschein, Rechnung) angegeben werden. Die „construct“ Methode
erzeugt ein,der Buchungsart entsprechendes, Objekt und gibt dieses zurück (In diesem
Fall wird ein „SalesFormLetter_Confirm“ Objekt erzeugt).<br />
Die eigentliche Buchung wird über die Methode „update“ aufgerufen. Da dieser Methode
alle für die Buchung notwendigen Daten als Parameter übergeben werden können, ist
eine einzelne Zuweisung von z.B. dem Auftrag, welcher gebucht werden soll, nicht notwendig.
</p>
        <p>
Hierzu ein Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
--- Buchen ohne Ausdruck ---</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> PostingConfimation(Args
_args)<br />
{<br />
   SalesFormLetter salesFormLetter;<br />
   SalesTable salesTable;<br />
   SalesId salesId;<br />
   PrintJobSettings printJobSettings;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Angabe
des Auftrags, welcher gebucht werden soll.</span><br />
   salesId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"00423_036"</span>;<br />
   salesTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SalesTable::find(salesId);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Bestimmen des Buchungstyps durch Angabe des DocumentStatus</span><br />
   salesFormLetter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SalesFormLetter::construct(DocumentStatus::Confirmation);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Buchen
des Auftrags (aber nicht Drucken).</span><br />
   salesFormLetter.update(salesTable,<br />
                          SystemDateGet(),<br />
                         
SalesUpdate::All,<br />
                          AccountOrder::None,<br />
                         
NoYes::No,<br />
                          NoYes::No);<br />
}</span>
        </p>
        <p>
Bei diesem Beispiel ist gut zu sehen, dass für die Buchung eines Auftrags im Wesentlichen
nur zwei Schritte notwendig sind.
</p>
        <ol>
          <li>
            <p>
Über die Methode „construct“ ein dem Buchungstyp einsprechendes Objekt erzeugen.
</p>
          </li>
          <li>
            <p>
Über den Aufruf der Methode „update“ den Auftrag buchen.
</p>
          </li>
        </ol>
        <p>
Natürlich können auch noch umfangreichere oder etwas speziellere Buchungsszenarien
mit der Klasse „salesFormLetter“ abgebildet werden. So ist es z.B. möglich, gleich
bei der Buchung entsprechende Dokumente auszudrucken (einmal, mehrfach und in verschiedene
Formate), die Maske für die Buchung zu öffnen (damit der Benutzer Einfluss auf die
Buchung nehmen kann) oder die Buchung nicht direkt auszuführen, sondern diese für
die Stapelverarbeitung bereit zu stellen.
</p>
        <p>
Damit es nicht zu komplex wird, kurz noch ein Beispiel zum Buchung und gleichzeitigen
ausdrucken entsprechender Dokumente.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
--- Buchen mit Ausdruck ---</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> PostingConfimation(Args
_args)<br />
{<br />
   SalesFormLetter salesFormLetter;<br />
   SalesTable salesTable;<br />
   SalesId salesId;<br />
   PrintJobSettings printJobSettings;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Angabe
des Auftrags, welcher gebucht werden soll.</span><br />
   salesId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"00423_036"</span>;<br />
   salesTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SalesTable::find(salesId);<br />
   salesFormLetter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SalesFormLetter::construct(DocumentStatus::Confirmation);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Buchen
des Auftrags und drucken (Druckmedium aus Std. Einstellung).</span><br />
   salesFormLetter.update(salesTable,<br />
                          SystemDateGet(),<br />
                          SalesUpdate::All,<br />
                          AccountOrder::None,<br />
                          NoYes::No,<br />
                          NoYes::Yes);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //2ter
Ausdruck.</span><br />
   printJobSettings <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> PrintJobSettings(salesFormLetter.printerSettingsFormletter(<br />
                                                          
PrintSetupOriginalCopy::Original));<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Wohin
möchten wir drucken (hier Datei).</span><br />
   printJobSettings.setTarget(PrintMedium::File);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //In
welches Format soll gedruckt werden (hier PDF).</span><br />
   printJobSettings.format(PrintFormat::PDF);<br />
   printJobSettings.fileName(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"C:\Test_Order.pdf"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Übergabe
der Druckoptionen an das SalesFormLetter Objekt.</span><br />
   salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings());<br /><br />
   salesFormLetter.printJournal();<br />
}</span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=5cb22557-acb4-41ec-9546-c65d681e3a3d" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX API – Teil 3 „Buchen von Aufträgen“</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx</link>
      <pubDate>Thu, 25 Oct 2007 17:45:14 GMT</pubDate>
      <description>&lt;p&gt;
Das Buchen von Aufträgen in Microsoft Dynamics AX geschieht über die Klasse „SalesFormLetter“
bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung,
Lieferschein, Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse
„SalesFormLetter“ abgeleitet ist (siehe Abbildung).
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/SalesFormLetter.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Um einen Auftrag per Programmcode zu buchen, muss ein Objekt der Klasse „SalesFormLetter“
erstellt werden.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;salesFormLetter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesFormLetter::construct(DocumentStatus::Confirmation);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Dies geschieht, wie Allgemein in Microsoft Dynamics AX üblich, über die “construct”
Methode der Klasse. Als Parameter muss dieser Methode die gewünschte Art der Buchung
(z.B. Bestätigung, Lieferschein, Rechnung) angegeben werden. Die „construct“ Methode
erzeugt ein,der Buchungsart entsprechendes, Objekt und gibt dieses zurück (In diesem
Fall wird ein „SalesFormLetter_Confirm“ Objekt erzeugt).&lt;br&gt;
Die eigentliche Buchung wird über die Methode „update“ aufgerufen. Da dieser Methode
alle für die Buchung notwendigen Daten als Parameter übergeben werden können, ist
eine einzelne Zuweisung von z.B. dem Auftrag, welcher gebucht werden soll, nicht notwendig.
&lt;/p&gt;
&lt;p&gt;
Hierzu ein Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
--- Buchen ohne Ausdruck ---&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; PostingConfimation(Args
_args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesFormLetter salesFormLetter;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesTable salesTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesId salesId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PrintJobSettings printJobSettings;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Angabe
des Auftrags, welcher gebucht werden soll.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"00423_036"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesTable::find(salesId);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Bestimmen des Buchungstyps durch Angabe des DocumentStatus&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesFormLetter::construct(DocumentStatus::Confirmation);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Buchen
des Auftrags (aber nicht Drucken).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter.update(salesTable,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SystemDateGet(),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
SalesUpdate::All,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AccountOrder::None,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
NoYes::No,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Bei diesem Beispiel ist gut zu sehen, dass für die Buchung eines Auftrags im Wesentlichen
nur zwei Schritte notwendig sind.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
Über die Methode „construct“ ein dem Buchungstyp einsprechendes Objekt erzeugen.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Über den Aufruf der Methode „update“ den Auftrag buchen.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Natürlich können auch noch umfangreichere oder etwas speziellere Buchungsszenarien
mit der Klasse „salesFormLetter“ abgebildet werden. So ist es z.B. möglich, gleich
bei der Buchung entsprechende Dokumente auszudrucken (einmal, mehrfach und in verschiedene
Formate), die Maske für die Buchung zu öffnen (damit der Benutzer Einfluss auf die
Buchung nehmen kann) oder die Buchung nicht direkt auszuführen, sondern diese für
die Stapelverarbeitung bereit zu stellen.
&lt;/p&gt;
&lt;p&gt;
Damit es nicht zu komplex wird, kurz noch ein Beispiel zum Buchung und gleichzeitigen
ausdrucken entsprechender Dokumente.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
--- Buchen mit Ausdruck ---&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; PostingConfimation(Args
_args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesFormLetter salesFormLetter;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesTable salesTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesId salesId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PrintJobSettings printJobSettings;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Angabe
des Auftrags, welcher gebucht werden soll.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"00423_036"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesTable::find(salesId);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesFormLetter::construct(DocumentStatus::Confirmation);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Buchen
des Auftrags und drucken (Druckmedium aus Std. Einstellung).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter.update(salesTable,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SystemDateGet(),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesUpdate::All,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AccountOrder::None,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::No,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::Yes);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//2ter
Ausdruck.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;printJobSettings &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; PrintJobSettings(salesFormLetter.printerSettingsFormletter(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
PrintSetupOriginalCopy::Original));&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Wohin
möchten wir drucken (hier Datei).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;printJobSettings.setTarget(PrintMedium::File);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//In
welches Format soll gedruckt werden (hier PDF).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;printJobSettings.format(PrintFormat::PDF);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;printJobSettings.fileName(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@"C:\Test_Order.pdf"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Übergabe
der Druckoptionen an das SalesFormLetter Objekt.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings());&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesFormLetter.printJournal();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=5cb22557-acb4-41ec-9546-c65d681e3a3d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,5cb22557-acb4-41ec-9546-c65d681e3a3d.aspx</comments>
      <category>Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=12b53c7f-292b-4ccf-a471-b0e80bd7646e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,12b53c7f-292b-4ccf-a471-b0e80bd7646e.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,12b53c7f-292b-4ccf-a471-b0e80bd7646e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=12b53c7f-292b-4ccf-a471-b0e80bd7646e</wfw:commentRss>
      <title>Drag &amp; Drop in Masken</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,12b53c7f-292b-4ccf-a471-b0e80bd7646e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,12b53c7f-292b-4ccf-a471-b0e80bd7646e.aspx</link>
      <pubDate>Tue, 16 Oct 2007 21:27:37 GMT</pubDate>
      <description>&lt;p class=MsoNormal&gt;
Nicht nur in der Microsoft Dynamics AX Entwicklungsumgebung hat man die Möglichkeit
mittels Drag &amp;amp; Drop Veränderungen vorzunehmen. Es ist recht einfach diese Funktion
auch in der Applikation verfügbar zu machen. Hier gibt es im Standard nur sehr wenige
Beispiele und die es gibt verwenden alle einen Tree oder eine List als Ziel.&amp;nbsp;
Ich&amp;nbsp;zeige diese Drag &amp;amp; Drop Funktion mit zwei Grids als Quelle und als Ziel
anhand eines einfachen Beispiels.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Um diese Drag &amp;amp; Drop Funktion in einer Maske zu implementieren braucht es zuerst
einmal zwei Datenquellen, eine als Quelle und eine als Ziel. Um die Daten auf der
Maske anzuzeigen hab ich jeweils ein Grid gewählt. Als Beispiel hab ich einfach eine
neue Maske erstellt, die als Datenquelle SalesLine (Zieldatenquelle) und Inventtable
(Quelldatenquelle) beinhaltet. Die Anzeige der Daten spielt hier nur eine untergeordnete
Rolle.
&lt;/p&gt;
&lt;img src="http://starside.eu/content/binary/DragDropFormDesigner.jpg" border=0&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p class=MsoNormal&gt;
Nun muss nur noch auf den Grid (SalesLineGrid und InventTableGrid) die Eigenschaft
DragDrop auf „Manual“ gestellt werden um Drag &amp;amp; Drop zu aktivieren (Es gibt nur
die Möglichkeit auf None oder Manual).&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;img src="http://starside.eu/content/binary/DragDropFormProperties.jpg" border=0&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p class=MsoNormal&gt;&lt;?xml:namespace prefix = o /&gt;
Nun kann man auf der Maske schon die Daten mittels Drag &amp;amp; Drop verschieben. Die
Funktion zum Einfügen des Datensatzes aus der Quelle ins Ziel ist natürlich noch nicht
vorhanden, man kann aber das optische Verhalten (Datensatz in ein anderes Grid ziehen)
schon betrachten.&amp;nbsp;&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Nun müssen noch einige Ereignisse überschrieben werden um die Funktion zu implementieren.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;o:p&gt;&lt;/o:p&gt;
dragOver = hier wird festgelegt welche Aktion durchgeführt wird (Move, Copy, None).
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span lang=EN-GB&gt;Move = Mouse+SHIFT Taste (Default)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt; 
&lt;li&gt;
&lt;span lang=EN-GB&gt;Copy&lt;span&gt;&amp;nbsp;&lt;/span&gt;= Mouse+STRG Taste&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=MsoNormal&gt;
So kann z.B. festgelegt werden, das auf dem Grid “InventTableGrid” kein Drag&amp;amp;Drop
möglich sein soll. Hierzu wird diese Methode wie folgt überschrieben.&lt;o:p&gt;
&lt;br&gt;

&lt;/p&gt;
&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; FormDrag
dragOver(FormControl _dragSource, FormDrag _dragMode, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _x, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _y)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; FormDrag ret;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// ret = super(_dragSource, _dragMode, _x, _y);&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// Kein Drag&amp;amp;Drop zulassen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; FormDrag::None;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
return&lt;/span&gt; ret;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/span&gt;Es können hier natürlich alle möglichen Überprüfungen stattfinden um festzulegen,
wann welche Option erlaubt/ nicht erlaubt ist.&lt;o:p&gt;&lt;/o:p&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&gt;
&lt;p class=MsoNormal&gt;
Um die Funktion nun abzuschließen fehlt nur noch das erzeugen des Datensatzes auf
der Tabelle SalesLine. Hierzu wird die Method „Drop“ auf dem Grid „SalesLineGrid“
überschrieben.&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Um Auftragspositionen aus den Artikelstamm anzulegen könnte die Methode so ausehen&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; drop(FormControl
_dragSource, FormDrag _dragMode, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _x, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _y)&lt;br&gt;
{&lt;br&gt;
SalesLine sLine;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Ist
Quelle identisch mit aktuellem Grid (SalesLineGrid)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (_dragSource.equal(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;))&lt;br&gt;
{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//TODO:
Hier kann bspw. das Verschieben der Auftragsposition implementiert werden (LineNum)&lt;/span&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Ist
Quelle InventTableGrid&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (_dragSource.name()
== InventTableGrid.name())&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Nur Aktion ausführen wenn Copy oder Move&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt;(_dragMode
== FormDrag::Copy || _dragMode == FormDrag::Move)&lt;br&gt;
{&lt;br&gt;
sLine.initValue();&lt;br&gt;
sLine.SalesId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SalesID.valueStr();&lt;br&gt;
sLine.initFromSalesTable(SalesTable::find(salesLIne.SalesId));&lt;br&gt;
sLine.ItemId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; inventTable.ItemId;&lt;br&gt;
sLine.initFromInventTable(InventTable);&lt;br&gt;
sLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes);&lt;br&gt;
salesLine_ds.executeQuery();&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
super(_dragSource, _dragMode, _x, _y);&lt;br&gt;
}&lt;/span&gt;
&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;p class=MsoNormal&gt;
In der Maske kann nun aus dem Artikelstamm eine neue Auftragsposition mittels Drag
&amp;amp; Drop erstellt werden. Hierfür habe ich noch eine Vorbelegung/ Einschränkung
auf die Aufragsnummer vorgenommen um die Auftragsposition erzeugen zu können.&lt;br&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;img src="http://starside.eu/content/binary/FormDragDrop.jpg" border=0&gt;
&lt;/p&gt;
Die Drag &amp;amp; Drop Funktion kann nur von der Artikeltabelle zu den Auftragsposition
durchgeführt werden. Umgekehrt funktioniert das nicht, was man auch optisch sehen
kann. (Screenshots haben aus irgendwelchen Gründen nicht funktioniert)&lt;br&gt;
&lt;br&gt;
Ein weiterer Vorteil bei der Drag &amp;amp; Drop Funktion ist, das Sie auch Maskenübergreifend
funktioniert. Hierfür sind gar keine weiteren Änderungen notwendig. Es muss in der
Drop Methode, wenn dort Überprüfungen stattfinden, nur der Ursprung auch erlaubt,
bzw. mit berücksichtigt wurden sein. 
&lt;p class=MsoNormal&gt;
&lt;o:p&gt;&lt;/o:p&gt;
Die gerade erstellte Maske lässt sich schon jetzt zweimal öffnen um dort von der einen
zu der anderen Maske Daten mittels Drag &amp;amp; Drop zu übertragen (Inventtable -&amp;gt;
SalesLine)&lt;o:p&gt;
&lt;br&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Durch kleine Änderungen kann diese Funktion auch aus der Artikelmaske ausgeführt werden.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Hierzu muss in der Artikelmaske einfach auf dem Grid DragDrop auf Manual gesetzt werden
und die Drop Funktion in der neu erstellten Maske leicht angepasst werden. 
&lt;br&gt;
&lt;/p&gt;
Beispielprojekte für das einfache Drag&amp;amp;Drop innerhalb einer Maske und die kleine
Erweiterung für das Drag&amp;amp;Drop aus der Artikelmaske herraus gibts auch wieder.&lt;br&gt;
&lt;p class=MsoNormal&gt;
In der Maske "BOMDesigner" kann die Drag&amp;amp;Drop Funktion noch anhand einer Baumstruktur
(FormTreeControl) als Quelle bewundert werden. 
&lt;br&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Beispiel SimpleDragAndDrop&lt;br&gt;
&lt;a href="http://starside.eu/content/binary/Form_SimpleDragDrop.rar"&gt;Form_SimpleDragDrop.rar
(1,99 KB)&lt;/a&gt;
&lt;/p&gt;
Beispiel Projekt für Drag&amp;amp;Drop aus Artikelmaske in die Maske SimpleDragAndDrop&lt;br&gt;
&lt;a href="http://starside.eu/content/binary/SharedProject_DragAndDropInventTable.rar"&gt;SharedProject_DragAndDropInventTable.rar
(11,71 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://starside.eu/cptrk.ashx?id=0e7f190d-8b09-457f-8471-bdf9bf235ad8"&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=12b53c7f-292b-4ccf-a471-b0e80bd7646e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,12b53c7f-292b-4ccf-a471-b0e80bd7646e.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=ceccbb06-b590-4a87-842e-62f282421bd5</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,ceccbb06-b590-4a87-842e-62f282421bd5.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,ceccbb06-b590-4a87-842e-62f282421bd5.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ceccbb06-b590-4a87-842e-62f282421bd5</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Erhält man bei seiner täglich Arbeit die Fehlermeldung „Ein Befehl der Datendefinitionssprache
kann nicht für () ausgeführt werden. Die SQL Datenbank hat einen Fehler gemeldet.“
oder auf englisch „cannot excecute a data definition language command on (). The SQL
database has issued an error.” stellt sich einem meist eine große Hürde in den Weg,
weil aus dieser Fehlermeldung nicht eindeutig zu erkennen ist, wo ein Fehler entstanden
ist bzw. wieso der Fehler auftritt.
</p>
        <p>
Durch Zufall bin ich drauf gestoßen, wie man genau diese Fehlermeldung produzieren
kann und somit Rückschlüsse auf die Ursache des Fehlers schließen kann.
</p>
        <p>
Das Folgende Vorgehen...
</p>
        <ol>
          <li>
Erstellen eines EDT’s vom Typ „string“ mit dem Namen „MY_BaseId“.</li>
          <li>
Verwenden des EDT’s in einer Tabelle (Name:  MY_BaseTable).</li>
          <li>
Erzeugen von mehreren Datensätzen in der Tabelle.</li>
          <li>
Löschen des EDT’s „MY_BaseId“.</li>
          <li>
Erstellen eines EDT’s vom Typ „real“ mit dem Namen „MY_BaseId“ (gleicher Name wie
der gelöschte EDT vom Typ „string“ hatte).</li>
          <li>
Kompilieren oder synchronisieren der Tabelle „MY_BaseTable“.</li>
        </ol>
        <p>
...ergibt die genannte Fehlermeldung.
</p>
        <p>
Daraus ist zu schließen, dass der Fehler immer Auftritt, wenn der Typ eines vorhandenen
EDT’s den bereits eine oder mehrere Tabellen verwenden, geändert wird.<br />
Ich konnte die Fehlermeldung bzw. den Fehler aber nur reproduzieren, wenn die jeweilige
Tabelle ein oder mehrere Datensätze enthielt. War in der Tabelle kein Datensatz vorhanden
kam es nicht zu der Fehlermeldung.
</p>
        <p>
Um besagten Fehler oder besagte Fehlermeldung zu beheben müssen entweder alle Datensätze
in der Tabelle oder die Tabelle selbst gelöscht werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=ceccbb06-b590-4a87-842e-62f282421bd5" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Ein Befehl der Datendefinitionssprache kann nicht für () ausgeführt werden.</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,ceccbb06-b590-4a87-842e-62f282421bd5.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,ceccbb06-b590-4a87-842e-62f282421bd5.aspx</link>
      <pubDate>Wed, 12 Sep 2007 18:14:27 GMT</pubDate>
      <description>&lt;p&gt;
Erhält man bei seiner täglich Arbeit die Fehlermeldung „Ein Befehl der Datendefinitionssprache
kann nicht für () ausgeführt werden. Die SQL Datenbank hat einen Fehler gemeldet.“
oder auf englisch „cannot excecute a data definition language command on (). The SQL
database has issued an error.” stellt sich einem meist eine große Hürde in den Weg,
weil aus dieser Fehlermeldung nicht eindeutig zu erkennen ist, wo ein Fehler entstanden
ist bzw. wieso der Fehler auftritt.
&lt;/p&gt;
&lt;p&gt;
Durch Zufall bin ich drauf gestoßen, wie man genau diese Fehlermeldung produzieren
kann und somit Rückschlüsse auf die Ursache des Fehlers schließen kann.
&lt;/p&gt;
&lt;p&gt;
Das Folgende Vorgehen...
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Erstellen eines EDT’s vom Typ „string“ mit dem Namen „MY_BaseId“.&lt;/li&gt;
&lt;li&gt;
Verwenden des EDT’s in einer Tabelle (Name:&amp;nbsp; MY_BaseTable).&lt;/li&gt;
&lt;li&gt;
Erzeugen von mehreren Datensätzen in der Tabelle.&lt;/li&gt;
&lt;li&gt;
Löschen des EDT’s „MY_BaseId“.&lt;/li&gt;
&lt;li&gt;
Erstellen eines EDT’s vom Typ „real“ mit dem Namen „MY_BaseId“ (gleicher Name wie
der gelöschte EDT vom Typ „string“ hatte).&lt;/li&gt;
&lt;li&gt;
Kompilieren oder synchronisieren der Tabelle „MY_BaseTable“.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
...ergibt die genannte Fehlermeldung.
&lt;/p&gt;
&lt;p&gt;
Daraus ist zu schließen, dass der Fehler immer Auftritt, wenn der Typ eines vorhandenen
EDT’s den bereits eine oder mehrere Tabellen verwenden, geändert wird.&lt;br&gt;
Ich konnte die Fehlermeldung bzw. den Fehler aber nur reproduzieren, wenn die jeweilige
Tabelle ein oder mehrere Datensätze enthielt. War in der Tabelle kein Datensatz vorhanden
kam es nicht zu der Fehlermeldung.
&lt;/p&gt;
&lt;p&gt;
Um besagten Fehler oder besagte Fehlermeldung zu beheben müssen entweder alle Datensätze
in der Tabelle oder die Tabelle selbst gelöscht werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=ceccbb06-b590-4a87-842e-62f282421bd5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,ceccbb06-b590-4a87-842e-62f282421bd5.aspx</comments>
      <category>Dynamics Ax/Administration;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=922ce5c2-b520-42da-b282-e6bf79a0d995</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,922ce5c2-b520-42da-b282-e6bf79a0d995.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,922ce5c2-b520-42da-b282-e6bf79a0d995.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=922ce5c2-b520-42da-b282-e6bf79a0d995</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Eine Bestellung umfasst in Microsoft Dynamics AX immer einen Datensatz der Tabelle
„PurchTable“ und wenn die Bestellung einen Artikel enthält, auch einen Datensatz in
der Tabelle „PurchLine“. Zusätzlich werden in Abhängigkeit von den Daten der Bestellung
(Einmallieferant: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche Datensätze in
anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle „VendTable“
genannt. In dieser wird ein neuer Lieferant erstellt, wenn beim Erstellen der Bestellung
angegeben wurde, dass es sich um einen Einmallieferanten handelt. Ein weiteres Beispiel
wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen für sonstige
Zuschläge ebenfalls weitere Datensätze erzeugt werden.
</p>
        <p>
Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert
wird in Microsoft Dynamics AX durch die Klassen „PurchTableType“ (Abbildung 1) und
„PurchLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen abgebildet. Diese
Klassen steuern das Verhalten bei Anlage, Änderung und Löschung einer Bestellung.
Dies beinhaltet auch, welche Werte ein Feld bei welchem Bestellungstyp annehmen darf,
was geschieht wenn ein Feld geändert wird, was wird wie gebucht und so weiter.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/PurchTableType.gif" border="0" />
        </p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/PurchLineType.gif" border="0" />
        </p>
        <p>
Diese Klassen werden von überschriebenen Methoden der Tabellen „PurchTable“ und „PurchLine“
aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „PurchTable“, die
Methode „Insert“ der Klasse „PurchTableType“ auf. Abhängig vom Bestellungstyp wird
über die Methode „construct“ bei der Initialisierung eines „PurchTableType“ Objekts
gesteuert, welches konkrete Objekt erzeugt wird („PurchTableType_Purch“, „PurchTableType_ReturnItem“,
etc.). Dies erfolgt in der Methode „type“ der Tabelle „PurchTable“ oder „PurchLine“.
Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“
und „Delete“ auf die gleiche Weise überschrieben.<br />
Ein Blick in die Methoden der Tabelle „PurchTable“ sollte dies verdeutlichen.
</p>
        <p>
Somit ist die Logik, die für die Steuerung von Bestellungen in Microsoft Dynamics
AX verantwortlich ist, vom Prinzip her vergleichbar mit der Logik welche die Aufträge
„steuert“ (vergleiche hierzu: <a href="http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx">Microsoft
Dynamics AX API – Teil 1 „Erstellen von Aufträgen“</a>).
</p>
        <p>
Deswegen ist das Erstellen einer Bestellung genau so einfach wie das Erstellen eines
Auftrags. Um eine neue Bestellung zu erstellen muss im Wesentlichen nur:
</p>
        <ol>
          <li>
Eine neue Nummer des entsprechenden Nummernkreises gezogen werden. 
</li>
          <li>
Die Methode „InitValue“ der Tabelle „PurchTable“ aufgerufen werden. 
</li>
          <li>
Die Methode „InitFromVendTable“ der Tabelle „PurchTable“ mit Angabe des Lieferanten
Datensatzes aufgerufen werden. 
</li>
          <li>
Die Methode „Insert“ der Tabelle  „PurchTable“ aufgerufen werden.</li>
        </ol>
        <p>
Soll für diese gerade erzeugte Bestellung nun noch eine Artikelposition erzeugt werden,
muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „PurchLine“, mit vorheriger
Definition von Bestellungsnummer („PurchLine.PurchId“) und Artikelnummer („PurchLine.ItemId“),
aufgerufen werden.
</p>
        <p>
Hierzu ein Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> createPurchTableAndLine()<br />
{<br />
   VendAccount vendAccount <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;yourVendAccount&gt;"</span>;<br />
   ItemId itemId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;yourItemId&gt;"</span>;<br /><br />
   PurchTable purchTable;<br />
   PurchLine purchLine;<br />
   NumberSeq numberSeq;<br />
   InventTable inventTable;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestellungskopf
(PurchTable)</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Neue
Bestellungsnummer aus Nummernkreis erzeugen</span><br />
   NumberSeq <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> NumberSeq::newGetNumFromCode(<br />
   PurchParameters::numRefPurchId().numberSequence);<br />
   purchTable.PurchId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> NumberSeq.num();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestellungskopf
initialisieren</span><br />
   purchTable.initValue();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Initialisierung
der lieferantenspezifischen Bestellungsdaten</span><br />
   purchTable.initFromVendTable(VendTable::find(vendAccount));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestellungskopf
erstellen</span><br />
   purchTable.insert();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestellungsposition
(PurchLine)</span><br />
   purchLine.clear();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Zuweisen
von Bestellungsnummer und Artikelnummer</span><br />
   purchLine.purchId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> purchTable.PurchId;<br />
   purchLine.ItemId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> itemId;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Bestellungsposition
erstellen (ruft PurchLine.insert auf)</span><br />
   purchLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes,<br />
                        NoYes::Yes,
NoYes::Yes, NoYes::Yes);<br />
}</span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=922ce5c2-b520-42da-b282-e6bf79a0d995" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX API – Teil 2 „Erstellen von Bestellungen“</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,922ce5c2-b520-42da-b282-e6bf79a0d995.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,922ce5c2-b520-42da-b282-e6bf79a0d995.aspx</link>
      <pubDate>Mon, 03 Sep 2007 19:02:32 GMT</pubDate>
      <description>&lt;p&gt;
Eine Bestellung umfasst in Microsoft Dynamics AX immer einen Datensatz der Tabelle
„PurchTable“ und wenn die Bestellung einen Artikel enthält, auch einen Datensatz in
der Tabelle „PurchLine“. Zusätzlich werden in Abhängigkeit von den Daten der Bestellung
(Einmallieferant: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche Datensätze in
anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle „VendTable“
genannt. In dieser wird ein neuer Lieferant erstellt, wenn beim Erstellen der Bestellung
angegeben wurde, dass es sich um einen Einmallieferanten handelt. Ein weiteres Beispiel
wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen für sonstige
Zuschläge ebenfalls weitere Datensätze erzeugt werden.
&lt;/p&gt;
&lt;p&gt;
Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert
wird in Microsoft Dynamics AX durch die Klassen „PurchTableType“ (Abbildung 1) und
„PurchLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen abgebildet. Diese
Klassen steuern das Verhalten bei Anlage, Änderung und Löschung einer Bestellung.
Dies beinhaltet auch, welche Werte ein Feld bei welchem Bestellungstyp annehmen darf,
was geschieht wenn ein Feld geändert wird, was wird wie gebucht und so weiter.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/PurchTableType.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/PurchLineType.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Diese Klassen werden von überschriebenen Methoden der Tabellen „PurchTable“ und „PurchLine“
aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „PurchTable“, die
Methode „Insert“ der Klasse „PurchTableType“ auf. Abhängig vom Bestellungstyp wird
über die Methode „construct“ bei der Initialisierung eines „PurchTableType“ Objekts
gesteuert, welches konkrete Objekt erzeugt wird („PurchTableType_Purch“, „PurchTableType_ReturnItem“,
etc.). Dies erfolgt in der Methode „type“ der Tabelle „PurchTable“ oder „PurchLine“.
Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“
und „Delete“ auf die gleiche Weise überschrieben.&lt;br&gt;
Ein Blick in die Methoden der Tabelle „PurchTable“ sollte dies verdeutlichen.
&lt;/p&gt;
&lt;p&gt;
Somit ist die Logik, die für die Steuerung von Bestellungen in Microsoft Dynamics
AX verantwortlich ist, vom Prinzip her vergleichbar mit der Logik welche die Aufträge
„steuert“ (vergleiche hierzu: &lt;a href="http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx"&gt;Microsoft
Dynamics AX API – Teil 1 „Erstellen von Aufträgen“&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Deswegen ist das Erstellen einer Bestellung genau so einfach wie das Erstellen eines
Auftrags. Um eine neue Bestellung zu erstellen muss im Wesentlichen nur:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Eine neue Nummer des entsprechenden Nummernkreises gezogen werden. 
&lt;li&gt;
Die Methode „InitValue“ der Tabelle „PurchTable“ aufgerufen werden. 
&lt;li&gt;
Die Methode „InitFromVendTable“ der Tabelle „PurchTable“ mit Angabe des Lieferanten
Datensatzes aufgerufen werden. 
&lt;li&gt;
Die Methode „Insert“ der Tabelle&amp;nbsp; „PurchTable“ aufgerufen werden.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Soll für diese gerade erzeugte Bestellung nun noch eine Artikelposition erzeugt werden,
muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „PurchLine“, mit vorheriger
Definition von Bestellungsnummer („PurchLine.PurchId“) und Artikelnummer („PurchLine.ItemId“),
aufgerufen werden.
&lt;/p&gt;
&lt;p&gt;
Hierzu ein Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; createPurchTableAndLine()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;VendAccount vendAccount &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;yourVendAccount&amp;gt;"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemId itemId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;yourItemId&amp;gt;"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchTable purchTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchLine purchLine;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;NumberSeq numberSeq;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;InventTable inventTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestellungskopf
(PurchTable)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Neue
Bestellungsnummer aus Nummernkreis erzeugen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;NumberSeq &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; NumberSeq::newGetNumFromCode(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;PurchParameters::numRefPurchId().numberSequence);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchTable.PurchId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; NumberSeq.num();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestellungskopf
initialisieren&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchTable.initValue();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Initialisierung
der lieferantenspezifischen Bestellungsdaten&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchTable.initFromVendTable(VendTable::find(vendAccount));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestellungskopf
erstellen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchTable.insert();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestellungsposition
(PurchLine)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchLine.clear();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Zuweisen
von Bestellungsnummer und Artikelnummer&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchLine.purchId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; purchTable.PurchId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchLine.ItemId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; itemId;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Bestellungsposition
erstellen (ruft PurchLine.insert auf)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;purchLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::Yes,
NoYes::Yes, NoYes::Yes);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=922ce5c2-b520-42da-b282-e6bf79a0d995" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,922ce5c2-b520-42da-b282-e6bf79a0d995.aspx</comments>
      <category>Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=5f347b6a-f6b2-4343-af0c-27d517219f18</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5f347b6a-f6b2-4343-af0c-27d517219f18</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ein Auftrag umfasst in Microsoft Dynamics AX immer einen Datensatz in der Tabelle
„SalesTable“ (Auftragskopf) und wenn der Auftrag einen Artikel enthält (Auftragsposition),
auch einen Datensatz in der Tabelle „SalesLine“. Zusätzlich werden in Abhängigkeit
von den Daten des Auftrags (Einmalkunde: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche
Datensätze in anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle
„CustTable“ genannt. In dieser wird ein neuer Kunde erstellt, wenn beim Erstellen
des Auftrags angegeben wurde, dass es sich um einen Einmalkunden handelt. Ein weiteres
Beispiel wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen
für Sonstige Zuschläge ebenfalls weitere Datensätze erzeugt werden.
</p>
        <p>
Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert
(die so genannte Geschäftslogik) wird in Microsoft Dynamics AX durch die Klassen „SalesTableType“
(Abbildung 1) und „SalesLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen
abgebildet. Diese Klassen steuern das Verhalten bei Anlage, Änderung und Löschung
eines Auftrags. Dies beinhaltet auch, welche Werte ein Feld bei welchem Auftragstyp
annehmen darf, was geschieht wenn ein Feld geändert wird, was wird wie gebucht und
so weiter.
</p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/SalesTableType.gif" border="0" />
        </p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/SalesLineType.gif" border="0" />
        </p>
        <p>
Diese Klassen werden von überschriebenen Methoden der Tabellen „SalesTable“ und „SalesLine“
aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „SalesTable“, die
Methode „Insert“ der Klasse „SalesTableType“ auf. Abhängig vom Auftragstyp wird über
die Methode „construct“ bei der Initialisierung eines „SalesTableType“ Objekts gesteuert,
welches konkrete Objekt erzeugt wird („SalesTableType_Sales“, „SalesTableType_ItemReq“,
etc.).<br />
Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“
und „Delete“ auf die gleiche Weise überschrieben. Ein Blick in die Methoden der Tabelle
„SalesTable“ oder „SalesLine“ sollte dies verdeutlichen.
</p>
        <p>
Somit gestaltet sich das Erstellen eines neuen Auftrags sehr einfach, da die gesamte
Geschäftslogik die hinter einem Auftrag steht, automatisch aufgerufen wird.
</p>
        <p>
Um einen neuen Auftrag zu erstellen muss im Wesentlichen nur
</p>
        <ol>
          <li>
Eine neue Nummer des entsprechenden Nummernkreises gezogen werden. 
</li>
          <li>
Die Methode „InitValue“ der Tabelle „SalesTable“ aufgerufen werden. 
</li>
          <li>
Die Kundennummer zugewiesen werden. 
</li>
          <li>
Die Methode „InitFromCustAccount“ der Tabelle „SalesTable“ aufgerufen werden. 
</li>
          <li>
Die Methode „Insert“ der Tabelle  „SalesTable“ aufgerufen werden.</li>
        </ol>
        <p>
Soll für diesem gerade erzeugten Auftrag nun noch eine Artikelposition erzeugt werden,
muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „SalesLine“, mit vorheriger
Definition von Auftragsnummer („SalesLine.SalesId“) und Artikelnummer („SalesLine.ItemId“),
aufgerufen werden.
</p>
        <p>
Hierzu ein Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> createSalesTableAndLine()<br />
{<br />
   AccountNum custAccount = &lt;yourCustAccount&gt;;<br />
   ItemId itemId = &lt;yourItemId&gt;;<br /></span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   SalesTable
salesTable;<br />
   SalesLine salesLine;<br />
   NumberSeq NumberSeq;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Auftragskopf
(SalesTable)</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Neue
Auftragsnummer aus Nummernkreis erzeugen</span><br />
   NumberSeq <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> NumberSeq::newGetNumFromCode(<br />
   SalesParameters::numRefSalesId().numberSequence);<br />
   salesTable.SalesId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> NumberSeq.num();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Auftragskopf
initialisieren</span><br />
   salesTable.initValue();<br />
   salesTable.CustAccount <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> custAccount;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Initialisierung
der kundenspezifischen Auftragsdaten</span><br />
   salesTable.initFromCustTable();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Auftragskopf
erstellen</span><br />
   salesTable.insert();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Auftragsposition
(SalesLine)</span><br />
   salesLine.clear();<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Zuweisen
von Auftragsnummer und Artikelnummer</span><br />
   salesLine.SalesId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> salesTable.SalesId;<br />
   salesLine.ItemId <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> itemId;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Auftragsposition
erstellen (ruft SalesLine.insert auf)</span><br />
   salesLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes,<br />
                        NoYes::Yes,
NoYes::Yes);<br />
}</span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=5f347b6a-f6b2-4343-af0c-27d517219f18" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Microsoft Dynamics AX API – Teil 1 „Erstellen von Aufträgen“</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx</link>
      <pubDate>Fri, 17 Aug 2007 14:47:28 GMT</pubDate>
      <description>&lt;p&gt;
Ein Auftrag umfasst in Microsoft Dynamics AX immer einen Datensatz in der Tabelle
„SalesTable“ (Auftragskopf)&amp;nbsp;und wenn der Auftrag einen Artikel enthält (Auftragsposition),
auch einen Datensatz in der Tabelle „SalesLine“. Zusätzlich werden in Abhängigkeit
von den Daten des Auftrags (Einmalkunde: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche
Datensätze in anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle
„CustTable“ genannt. In dieser wird ein neuer Kunde erstellt, wenn beim Erstellen
des Auftrags angegeben wurde, dass es sich um einen Einmalkunden handelt. Ein weiteres
Beispiel wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen
für Sonstige Zuschläge ebenfalls weitere Datensätze erzeugt werden.
&lt;/p&gt;
&lt;p&gt;
Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert
(die so genannte Geschäftslogik) wird in Microsoft Dynamics AX durch die Klassen „SalesTableType“
(Abbildung 1) und „SalesLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen
abgebildet. Diese Klassen steuern das Verhalten bei Anlage, Änderung und Löschung
eines Auftrags. Dies beinhaltet auch, welche Werte ein Feld bei welchem Auftragstyp
annehmen darf, was geschieht wenn ein Feld geändert wird, was wird wie gebucht und
so weiter.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/SalesTableType.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/SalesLineType.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Diese Klassen werden von überschriebenen Methoden der Tabellen „SalesTable“ und „SalesLine“
aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „SalesTable“, die
Methode „Insert“ der Klasse „SalesTableType“ auf. Abhängig vom Auftragstyp wird über
die Methode „construct“ bei der Initialisierung eines „SalesTableType“ Objekts gesteuert,
welches konkrete Objekt erzeugt wird („SalesTableType_Sales“, „SalesTableType_ItemReq“,
etc.).&lt;br&gt;
Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“
und „Delete“ auf die gleiche Weise überschrieben. Ein Blick in die Methoden der Tabelle
„SalesTable“ oder „SalesLine“ sollte dies verdeutlichen.
&lt;/p&gt;
&lt;p&gt;
Somit gestaltet sich das Erstellen eines neuen Auftrags sehr einfach, da die gesamte
Geschäftslogik die hinter einem Auftrag steht, automatisch aufgerufen wird.
&lt;/p&gt;
&lt;p&gt;
Um einen neuen Auftrag zu erstellen muss im Wesentlichen nur
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Eine neue Nummer des entsprechenden Nummernkreises gezogen werden. 
&lt;li&gt;
Die Methode „InitValue“ der Tabelle „SalesTable“ aufgerufen werden. 
&lt;li&gt;
Die Kundennummer zugewiesen werden. 
&lt;li&gt;
Die Methode „InitFromCustAccount“ der Tabelle „SalesTable“ aufgerufen werden. 
&lt;li&gt;
Die Methode „Insert“ der Tabelle&amp;nbsp; „SalesTable“ aufgerufen werden.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Soll für diesem gerade erzeugten Auftrag nun noch eine Artikelposition erzeugt werden,
muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „SalesLine“, mit vorheriger
Definition von Auftragsnummer („SalesLine.SalesId“) und Artikelnummer („SalesLine.ItemId“),
aufgerufen werden.
&lt;/p&gt;
&lt;p&gt;
Hierzu ein Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; createSalesTableAndLine()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;AccountNum custAccount = &amp;lt;yourCustAccount&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemId itemId = &amp;lt;yourItemId&amp;gt;;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesTable
salesTable;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesLine salesLine;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;NumberSeq NumberSeq;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Auftragskopf
(SalesTable)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Neue
Auftragsnummer aus Nummernkreis erzeugen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;NumberSeq &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; NumberSeq::newGetNumFromCode(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SalesParameters::numRefSalesId().numberSequence);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable.SalesId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; NumberSeq.num();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Auftragskopf
initialisieren&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable.initValue();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable.CustAccount &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; custAccount;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Initialisierung
der kundenspezifischen Auftragsdaten&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable.initFromCustTable();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Auftragskopf
erstellen&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesTable.insert();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Auftragsposition
(SalesLine)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesLine.clear();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Zuweisen
von Auftragsnummer und Artikelnummer&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesLine.SalesId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; salesTable.SalesId;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesLine.ItemId &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; itemId;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Auftragsposition
erstellen (ruft SalesLine.insert auf)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;salesLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NoYes::Yes,
NoYes::Yes);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=5f347b6a-f6b2-4343-af0c-27d517219f18" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx</comments>
      <category>Dynamics Ax/Programmierung;Dynamics Ax/Programmierung/API</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=c566a09c-0fc9-41a3-b609-0680104f58d7</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,c566a09c-0fc9-41a3-b609-0680104f58d7.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,c566a09c-0fc9-41a3-b609-0680104f58d7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c566a09c-0fc9-41a3-b609-0680104f58d7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Manchmal ist es hilfreich beim Debuggen eines Codeblocks zusätzliche Informationen
im Debugger auszugeben. <br />
Dies kann zum Beispiel der aktuelle Wert eines Tabellenfelds sein.
</p>
        <p>
Ebenfalls ist es machmal hilfreich, zusätliche Überprüfungen von Werten einzelner
Variablen oder Tabellenfeldern durchzuführen, wenn der jeweilige Codeblock im Debugger
ausgeführt wird.
</p>
        <p>
Hierzu ein Beispiel: 
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">CustTable
custTable;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">while</span> select
custTable<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Den
Kundennamen im Debuggerfenster ausgeben.</span><br />
   debug::printDebug(custTable.Name);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Information
in einem beliebigen Debugger-Info-Tab ausgeben.</span><br />
   debug::printTab(DebugPrintTab::Method, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Aufruf
einer Methode"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Eine
Überprüfung eines Wertes durchführen (nur im Debug-Mode).</span><br />
   debug::assert(CustTable.Name !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> nullValue(CustTable.Name));<br /><br />
   info(custTable.Name);<br />
}</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">Alle
"Debug::" Anweisungen werden nur beachtet/ausgeführt, wenn der Code im Debugger ausgeführt
wird (gesetzter Breakpoint). </font>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">Wird
der Code "normal" ausgeführt, wird in dem Beispiel nur die "info()" Anweisung ausgeführt.</font>
          </span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=c566a09c-0fc9-41a3-b609-0680104f58d7" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Zusätzliche Informationen im Debugger ausgeben</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,c566a09c-0fc9-41a3-b609-0680104f58d7.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,c566a09c-0fc9-41a3-b609-0680104f58d7.aspx</link>
      <pubDate>Sat, 04 Aug 2007 12:55:55 GMT</pubDate>
      <description>&lt;p&gt;
Manchmal ist es hilfreich beim Debuggen eines Codeblocks zusätzliche Informationen
im Debugger auszugeben.&amp;nbsp;&lt;br&gt;
Dies kann zum Beispiel der aktuelle Wert&amp;nbsp;eines Tabellenfelds sein.
&lt;/p&gt;
&lt;p&gt;
Ebenfalls ist es machmal hilfreich, zusätliche Überprüfungen von Werten einzelner
Variablen oder Tabellenfeldern durchzuführen, wenn der jeweilige Codeblock im Debugger
ausgeführt wird.
&lt;/p&gt;
&lt;p&gt;
Hierzu ein Beispiel:&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;CustTable
custTable;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;while&lt;/span&gt; select
custTable&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Den
Kundennamen im Debuggerfenster ausgeben.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;debug::printDebug(custTable.Name);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Information
in einem beliebigen Debugger-Info-Tab ausgeben.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;debug::printTab(DebugPrintTab::Method, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Aufruf
einer Methode"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Eine
Überprüfung eines Wertes durchführen (nur im Debug-Mode).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;debug::assert(CustTable.Name !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; nullValue(CustTable.Name));&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;info(custTable.Name);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;Alle
"Debug::" Anweisungen werden nur beachtet/ausgeführt, wenn der Code im Debugger ausgeführt
wird (gesetzter Breakpoint). &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;Wird
der Code "normal" ausgeführt, wird in dem Beispiel nur die "info()" Anweisung ausgeführt.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=c566a09c-0fc9-41a3-b609-0680104f58d7" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,c566a09c-0fc9-41a3-b609-0680104f58d7.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=e6eb7122-8d56-4ed8-91c6-5431e07dd80e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,e6eb7122-8d56-4ed8-91c6-5431e07dd80e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,e6eb7122-8d56-4ed8-91c6-5431e07dd80e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=e6eb7122-8d56-4ed8-91c6-5431e07dd80e</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Möchte man alle Datensätze einer Tabelle löschen, kann hierfür der Befehl "<strong>Delete_From</strong>"
verwendet werden.
</p>
        <p>
Dies funktioniert soweit und es ist auch nichts gegen diese "Art" des Löschen einzuwenden.<br />
Wenn allerdings in der Tabelle mehrere millionen Datensätze gespeichert sind, dauert
dies schon recht lange (mehrere Stunden).
</p>
        <p>
Um das Löschen aller Datensätze einer Tabelle zu beschleunigen, kann der SQL Server
Befehl (Transact SQL) "<strong>TRUNCATE TABLE</strong>" verwendet werden.
</p>
        <p>
Dieser Befehl erfernt alle Zeilen aus einer Tabelle, ohne die einzelnen Löschungen
zu protokollieren. Der "TRUNCATE TABLE" Befehl ist wesentlich schneller
und verwendet weniger Systemressourcen als der "Delete" Befehl.
</p>
        <p>
Microsoft Dynamics AX unterstütz diesen Befehl leider nicht direkt.<br />
Somit muss der Aufruf von "TRUNCATE TABLE" über eine ADO-Connection oder in einem
der SQL Server Verwaltungs-Tools erfolgen.
</p>
        <p>
          <strong>
            <em>Update:<br /></em>
          </strong>Der "Truncate Table" Befehl ist doch in Dynamics AX implementiert. Und
zwar wird er durch die Methode "tableTruncate" der Klasse "SqlDataDictionary" implementiert. 
<br /><br />
Beispiel zur Verwendung: 
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SqlDataDictionary
sqlDict; 
<br />
; 
<br />
sqlDict <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlDataDictionary(); 
<br />
sqlDict.tableTruncate(tablenum(SysDataBaseLog)); </span>
        </p>
        <p>
Weitere Informationen zum "TRUNCATE TABLE" Befehl können über das MSDN bezogen werden.<br /><a href="http://msdn2.microsoft.com/de-de/library/ms177570.aspx">http://msdn2.microsoft.com/de-de/library/ms177570.aspx</a></p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=e6eb7122-8d56-4ed8-91c6-5431e07dd80e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Alle Datensätze einer sehr großen Tabelle löschen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,e6eb7122-8d56-4ed8-91c6-5431e07dd80e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,e6eb7122-8d56-4ed8-91c6-5431e07dd80e.aspx</link>
      <pubDate>Fri, 22 Jun 2007 07:59:24 GMT</pubDate>
      <description>&lt;p&gt;
Möchte man alle Datensätze einer Tabelle&amp;nbsp;löschen, kann hierfür der Befehl "&lt;strong&gt;Delete_From&lt;/strong&gt;"
verwendet werden.
&lt;/p&gt;
&lt;p&gt;
Dies funktioniert soweit und es ist auch nichts gegen diese "Art" des Löschen einzuwenden.&lt;br&gt;
Wenn allerdings in der Tabelle mehrere millionen Datensätze gespeichert sind, dauert
dies schon recht lange (mehrere Stunden).
&lt;/p&gt;
&lt;p&gt;
Um das Löschen aller Datensätze einer Tabelle zu beschleunigen, kann der SQL Server
Befehl (Transact SQL) "&lt;strong&gt;TRUNCATE TABLE&lt;/strong&gt;" verwendet werden.
&lt;/p&gt;
&lt;p&gt;
Dieser Befehl erfernt&amp;nbsp;alle Zeilen aus einer Tabelle, ohne die einzelnen Löschungen
zu protokollieren. Der&amp;nbsp;"TRUNCATE TABLE" Befehl&amp;nbsp;ist&amp;nbsp;wesentlich&amp;nbsp;schneller
und verwendet weniger Systemressourcen als der "Delete" Befehl.
&lt;/p&gt;
&lt;p&gt;
Microsoft Dynamics AX unterstütz diesen Befehl leider nicht direkt.&lt;br&gt;
Somit muss der Aufruf von "TRUNCATE TABLE" über eine ADO-Connection oder in einem
der SQL Server Verwaltungs-Tools erfolgen.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Update:&lt;br&gt;
&lt;/em&gt;&lt;/strong&gt;Der "Truncate Table" Befehl ist doch in Dynamics AX implementiert. Und
zwar wird er durch die Methode "tableTruncate" der Klasse "SqlDataDictionary" implementiert. 
&lt;br&gt;
&lt;br&gt;
Beispiel zur Verwendung: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SqlDataDictionary
sqlDict; 
&lt;br&gt;
; 
&lt;br&gt;
sqlDict &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlDataDictionary(); 
&lt;br&gt;
sqlDict.tableTruncate(tablenum(SysDataBaseLog)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Weitere Informationen zum "TRUNCATE TABLE" Befehl können über das MSDN bezogen werden.&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/de-de/library/ms177570.aspx"&gt;http://msdn2.microsoft.com/de-de/library/ms177570.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=e6eb7122-8d56-4ed8-91c6-5431e07dd80e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,e6eb7122-8d56-4ed8-91c6-5431e07dd80e.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung;SQL Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=485aebd7-0fc6-4dbb-8e23-42a567be4ed9</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,485aebd7-0fc6-4dbb-8e23-42a567be4ed9.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,485aebd7-0fc6-4dbb-8e23-42a567be4ed9.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=485aebd7-0fc6-4dbb-8e23-42a567be4ed9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Heute wurde in den Newsgroups die Frage gestellt, ob es nicht möglich sein, nach
einem XPO-Import einen "automatischen" CompileForward für alle mit dem XPO-File importierten
Klassen zu starten.
</p>
        <p>
Ganz automatisch ist dies leider nicht möglich. Es kann aber eine Art "Installationsjob"
geschrieben werden, der zusammen mit den entsprechenden Klassen durch das XPO-File
weitergegeben und importiert werden kann.
</p>
        <p>
Nach dem Import des XPO-File muss dieser Job nur noch gestartet werden und es werden
die frisch importierten Klassen sowie alle von diesen Klassen abgeleiteten Klasse
neu kompilert (CompileForward).
</p>
        <p>
Ein solcher "Installtionsjob" könnte wie folgt aussehen:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> runAfterImport(Args
_args)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
//CompileForward all imported (base) classes</span><br />
    ;<br />
    SysCompilerOutput::compileForward(className2Id(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"SalesFormLetter"</span>));<br />
    SysCompilerOutput::compileForward(className2Id(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Your
next base class"</span>));<br />
    SysCompilerOutput::compileForward(className2Id(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Your
next base class"</span>));<br />
}</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">Ein
manuelles Auswählen des CompileForward Menüpunktes einzelner importierter Klassen
kann dadurch entfallen.</font>
            <br />
          </span>
        </p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=485aebd7-0fc6-4dbb-8e23-42a567be4ed9" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>CompileForward beim importieren einer Klasse starten</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,485aebd7-0fc6-4dbb-8e23-42a567be4ed9.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,485aebd7-0fc6-4dbb-8e23-42a567be4ed9.aspx</link>
      <pubDate>Thu, 24 May 2007 19:38:38 GMT</pubDate>
      <description>&lt;p&gt;
Heute&amp;nbsp;wurde in den Newsgroups die Frage gestellt, ob es nicht möglich sein, nach
einem XPO-Import einen "automatischen" CompileForward für alle mit dem XPO-File importierten
Klassen zu starten.
&lt;/p&gt;
&lt;p&gt;
Ganz automatisch ist dies leider nicht möglich. Es kann aber eine Art "Installationsjob"
geschrieben werden, der zusammen mit den entsprechenden Klassen durch das XPO-File
weitergegeben und importiert werden kann.
&lt;/p&gt;
&lt;p&gt;
Nach dem Import des XPO-File muss dieser Job nur noch gestartet werden und es werden
die frisch importierten Klassen sowie alle von diesen Klassen abgeleiteten Klasse
neu kompilert (CompileForward).
&lt;/p&gt;
&lt;p&gt;
Ein solcher "Installtionsjob" könnte wie folgt aussehen:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; runAfterImport(Args
_args)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//CompileForward all imported (base) classes&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysCompilerOutput::compileForward(className2Id(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"SalesFormLetter"&lt;/span&gt;));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysCompilerOutput::compileForward(className2Id(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Your
next base class"&lt;/span&gt;));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysCompilerOutput::compileForward(className2Id(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Your
next base class"&lt;/span&gt;));&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;Ein
manuelles Auswählen des CompileForward Menüpunktes einzelner importierter Klassen
kann dadurch entfallen.&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=485aebd7-0fc6-4dbb-8e23-42a567be4ed9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,485aebd7-0fc6-4dbb-8e23-42a567be4ed9.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=9418cdba-0514-4ccf-af1d-231f6ca1b9e0</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,9418cdba-0514-4ccf-af1d-231f6ca1b9e0.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,9418cdba-0514-4ccf-af1d-231f6ca1b9e0.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9418cdba-0514-4ccf-af1d-231f6ca1b9e0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Wie z.B. aus Visual Studio bekannt kann in vielen IDE's der Ausführungsmodus des Quellcodes
bestimmt und gewechselt werden.<br />
Beispiele hierfür sind Debugmode oder Releasemode.
</p>
        <p>
Wenn nun im Quelltext auf den Ausführungsmodus abgefragt wird, so kann zum Beispiel
im Debugmode erweiterter Quellcode mit in ein Programm kompiliert werden, welcher beispielsweise
verschiedene Loggingarten implementiert um eine bessere Problemanalyse durchführen
zu können. <br />
Dies läßt sich auch mit Microsoft Dynamics AX machen. 
<br /><br />
Als erstes muss ein neues Macro erstellt werden (in diesem Beispiel mit dem Namen <em><strong>RunningMode</strong></em>),
welches als globaler Schalter zwischen den einzenen Ausführungsarten eingesetzt wird:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/*
Macro for setting the running Mode. */</span>
            <br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/*
Activate for debug mode. */</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#define</span>.Debug('<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>')<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/*
Activate for production mode. */</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//#define.Debug('') </span><br /></span>
        </p>
        <p>
Jetzt kann an beliebiger Stelle im Quellcode <em><strong>#Debug</strong></em> verwendet
werden um auf den Ausführungsmodus zu prüfen:  
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> TestTheRunningMode(Args
_args)<br />
{<br />
    #RunningMode<br />
    ;<br />
    print <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Code
der immer ausgeführt werden soll"</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
if</span>(#Debug)<br />
    {<br />
        print <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Code
der nur im Debug-Mode ausgeführt wird"</span><br />
    }<br />
    pause;<br />
} </span> 
</p>
        <p>
Abhängig davon, wie im Macro RunningMode #Debug definiert wurde, kann nun beliebiger
Quellcode aktiviert (ausgeführt) oder deaktiviert (nicht ausgeführt) werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=9418cdba-0514-4ccf-af1d-231f6ca1b9e0" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Quellcode abh&amp;auml;ngig vom Betriebsmodus des Systems ausf&amp;uuml;hren</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,9418cdba-0514-4ccf-af1d-231f6ca1b9e0.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,9418cdba-0514-4ccf-af1d-231f6ca1b9e0.aspx</link>
      <pubDate>Fri, 27 Apr 2007 17:04:10 GMT</pubDate>
      <description>&lt;p&gt;
Wie z.B. aus Visual Studio bekannt kann in vielen IDE's der Ausführungsmodus des Quellcodes
bestimmt und gewechselt werden.&lt;br&gt;
Beispiele hierfür sind&amp;nbsp;Debugmode oder Releasemode.
&lt;/p&gt;
&lt;p&gt;
Wenn nun im Quelltext auf den Ausführungsmodus abgefragt wird, so kann&amp;nbsp;zum Beispiel
im Debugmode erweiterter Quellcode mit in ein Programm kompiliert werden, welcher&amp;nbsp;beispielsweise
verschiedene Loggingarten implementiert um eine bessere Problemanalyse durchführen
zu können.&amp;nbsp;&lt;br&gt;
Dies läßt sich auch mit Microsoft Dynamics AX machen. 
&lt;br&gt;
&lt;br&gt;
Als erstes muss ein neues Macro erstellt werden (in diesem Beispiel mit dem Namen &lt;em&gt;&lt;strong&gt;RunningMode&lt;/strong&gt;&lt;/em&gt;),
welches als globaler Schalter zwischen den einzenen Ausführungsarten eingesetzt wird:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/*
Macro for setting the running Mode. */&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/*
Activate for debug mode. */&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#define&lt;/span&gt;.Debug('&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;')&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/*
Activate for production mode. */&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//#define.Debug('') &lt;/span&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Jetzt kann an beliebiger Stelle im Quellcode &lt;em&gt;&lt;strong&gt;#Debug&lt;/strong&gt;&lt;/em&gt; verwendet
werden um auf den Ausführungsmodus zu prüfen:&amp;nbsp; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; TestTheRunningMode(Args
_args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; #RunningMode&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; print &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Code
der immer ausgeführt werden soll"&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt;(#Debug)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Code
der nur im Debug-Mode ausgeführt wird"&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; pause;&lt;br&gt;
}&amp;nbsp;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Abhängig davon,&amp;nbsp;wie im Macro RunningMode #Debug definiert wurde, kann nun beliebiger
Quellcode aktiviert (ausgeführt) oder deaktiviert (nicht ausgeführt) werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=9418cdba-0514-4ccf-af1d-231f6ca1b9e0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,9418cdba-0514-4ccf-af1d-231f6ca1b9e0.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=008a147e-fdd7-4998-b6ff-b8f0673f7973</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,008a147e-fdd7-4998-b6ff-b8f0673f7973.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,008a147e-fdd7-4998-b6ff-b8f0673f7973.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=008a147e-fdd7-4998-b6ff-b8f0673f7973</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Möchte man eine Methode der Klasse <strong><em>Info</em></strong> anpassen oder erweitern,
können dabei unerklärliche Fehler auftreten.
</p>
        <p>
Soll zum Beispiel die Methode <em><strong>open(FormRun formRun)</strong></em> erweitert
werden und man verwendet hierbei eine Variable die in der <em><strong>classDeclaration</strong></em> deklariert
ist, erhält man spätestens zur Laufzeit eine Fehlermeldung (dies sogar bei fehlerfreiem
Code, keine Fehlermeldung im Debugger).
</p>
        <p>
Grund hierfür ist, dass in Dynamics AX 4.0 die Klasse Info immer nur beim Öffnen
des Clients erzeugt wird und man somit, egal ob die Klasse neu kompiliert wurde oder
nicht, immer noch mit Teilen der alten Klassenversion arbeitet.
</p>
        <p>
Um die neue Version der angepassten Info Klasse aufzurufen muss der Client geschlossen
und wieder neu geöffnet werden.<br />
Erst dann funktioniert die Anpassung wie gewünscht.
</p>
        <p>
Das geschilderte Verhalten kann bei:
</p>
        <p>
1. Erstellen von neuen Methoden<br />
2. Deklarieren einer Variablen in der classDeclaration und Verwendung dieser in einer
anderen Methode
</p>
        <p>
allerdings nicht bei:
</p>
        <p>
1. Anpassungen, die nur innerhalb einer einzelnen Methode durchgeführt werden
</p>
        <p>
beobachtet werden.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=008a147e-fdd7-4998-b6ff-b8f0673f7973" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>&amp;Auml;ndern von Methoden der Klasse Info</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,008a147e-fdd7-4998-b6ff-b8f0673f7973.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,008a147e-fdd7-4998-b6ff-b8f0673f7973.aspx</link>
      <pubDate>Wed, 25 Apr 2007 20:57:04 GMT</pubDate>
      <description>&lt;p&gt;
Möchte man eine Methode der Klasse &lt;strong&gt;&lt;em&gt;Info&lt;/em&gt;&lt;/strong&gt; anpassen oder erweitern,
können dabei unerklärliche Fehler auftreten.
&lt;/p&gt;
&lt;p&gt;
Soll zum Beispiel die Methode &lt;em&gt;&lt;strong&gt;open(FormRun formRun)&lt;/strong&gt;&lt;/em&gt; erweitert
werden und man verwendet hierbei eine Variable die in der &lt;em&gt;&lt;strong&gt;classDeclaration&lt;/strong&gt;&lt;/em&gt; deklariert
ist,&amp;nbsp;erhält man spätestens zur Laufzeit eine Fehlermeldung (dies sogar bei fehlerfreiem
Code, keine Fehlermeldung im Debugger).
&lt;/p&gt;
&lt;p&gt;
Grund hierfür ist, dass in Dynamics AX 4.0&amp;nbsp;die Klasse Info immer nur beim Öffnen
des Clients erzeugt wird und man somit, egal ob die Klasse neu kompiliert wurde oder
nicht, immer noch mit Teilen der alten Klassenversion arbeitet.
&lt;/p&gt;
&lt;p&gt;
Um die neue Version der angepassten Info Klasse aufzurufen muss der Client geschlossen
und wieder neu geöffnet werden.&lt;br&gt;
Erst dann funktioniert die Anpassung wie gewünscht.
&lt;/p&gt;
&lt;p&gt;
Das geschilderte Verhalten kann bei:
&lt;/p&gt;
&lt;p&gt;
1. Erstellen von neuen Methoden&lt;br&gt;
2. Deklarieren einer Variablen in der classDeclaration und Verwendung dieser in einer
anderen Methode
&lt;/p&gt;
&lt;p&gt;
allerdings nicht bei:
&lt;/p&gt;
&lt;p&gt;
1.&amp;nbsp;Anpassungen, die nur innerhalb einer einzelnen Methode durchgeführt werden
&lt;/p&gt;
&lt;p&gt;
beobachtet werden.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=008a147e-fdd7-4998-b6ff-b8f0673f7973" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,008a147e-fdd7-4998-b6ff-b8f0673f7973.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=1cc5046b-1a59-4810-8d97-758ab5de391d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,1cc5046b-1a59-4810-8d97-758ab5de391d.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,1cc5046b-1a59-4810-8d97-758ab5de391d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1cc5046b-1a59-4810-8d97-758ab5de391d</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
Eigendlich wollte ich hier noch die erweiterten Möglichkeiten bei den Einschränkungen
zum Besten geben, das kann man aber schon alles fix und fertig bei <a href="http://www.axaptapedia.com/Expressions_in_query_ranges">Axaptapedia</a> nachlesen. 
<br /><br />
Daher vorerst nur noch die eine Sache die ich noch beschreiben möchte:<br /><br />
Möchte man eine Einschränkung auf einen Array Feld (die Dimension: Abteilung, Kostenstelle,
Kostenträger sind hierfür ein gutes Beispiel) definieren kann diese wie folgt erstellt
werden.<br /><br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.addRange(fieldid2ext(fieldnum(InventTable,
Dimension), 1));<br /><br /></span>Das erstellen der Range bleibt im Grunde gleich, nur das jetzt mittels fieldid2ext
noch der Array Index angegeben wird. Der Index beginnt in Microsoft Dynamics Ax immer
mit 1.<br /><br />
Da nun diese Sache hier nicht mehr behandelt wird, möchte ich noch eine komplett andere
Möglichkeit zeigen Datensätze aus der Datenbank zu holen um diese beispielsweise in
Masken anzuzeigen. Anstelle einer Query kann man auch SQL Anweisungen verwenden.<br /><br /><br />
Das wird ein bisschen Tricky...<br />
Ich fange aber heute nur "einfach" an.<br /><br />
Zuerst bauen wir uns einen neue Form und nennen diese ArtikelSQL (Der Name ist hier
eigendlich egal, ich habe mich aber für eine Artikelmaske entschieden).<br />
Dann legen wir die InventTable mittels Drag&amp;Drop als Datasource fest. Zum Abschluss
zeigen wir noch ein paar Feld (Artikelnummer und Artikelname reicht erstmal aus) über
ein neu hinzugefügtes Grid in dieser Maske an. Fertig - beim Aufruf der Maske erhalten
wir alle Datensätze die sich in der Tabelle InventTable befinden.<br /><br />
Als nächsten Schritt definieren wir eine Variable in der Classdeclaration<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
Source SQLAnweisung;<br /><br /></span>In dieser Variable schreiben wir später unsere SQL Anweisung. Bevor das jedoch
gemacht wird, muss als nächstes noch die Methode executeQuery auf der DataSource überschrieben
werden.<br /><br /><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> executeQuery()<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
if</span> (SQLAnweisung)<br />
    {<br />
        runbuf(SQLAnweisung, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.cursor());<br />
    }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
else</span><br />
    {<br />
        super();<br />
    }<br />
}</span></p><br />
Neu  hinzugekommen ist hier die IF Abfrage, die prüft ob eine SQLAnweisung erstellt
wurde, bzw. ob die Variable SQLAnweisung nicht leer ist. Wurde  keine SQLAnweisung
getroffen, wird die Standardquery auf der DataSource ausgeführt. Wurde aber eine SQLAnweisung
getroffen wird diese nun Anstelle der Query ausgeführt.<br /><br />
Zu guter letzt fehlt nur noch die SQLAnweisung, die erstellt werden muss.<br /><br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> initSQLAnweisung()<br />
{<br />
XppCompiler compiler <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> XppCompiler();<br />
DictTable dictTable= <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> DictTable(Tablenum(InventTAble));<br />
str SELECTAnweisung <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 'SELECT <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">*</span> FROM
'+dictTable.name();<br /><br />
SQLAnweisung <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> '<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> SQLSTMT('+dictTable.name()<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'
'+dictTable.name()<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>')\n{\n'+SELECTAnweisung+';\n}\n';<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (!compiler.compile(SQLAnweisung))<br />
{<br />
setprefix(<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"@SYS57538"</span>);<br />
info (SQLAnweisung);<br />
error (compiler.errorText());<br /></span><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SQLAnweisung <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=
'';</span></span><br />
&lt;&gt;<span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">}<br />
}</span>Diese Methode erstellt die SQL Anweisung. Es reicht nicht aus einfach ein
SELECT Statement zu schreiben, da der Compiler das nicht versteht. Anstelle eines
einzelenen SELECT Statement schreibt man einfach eine Methode drumherum, die dann
über runbuf ausgeführt wird. 
<br />
Das eigendliche SELECT Statement sieht wie folgt aus und wird gleich der Variable
SELECTANweisung zugewiesen.<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
SELECT <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">*</span> FROM
InventTable<br /><br /></span>Über diese einfache Select Anweisung erhalten wir alle Datensätze aus der Tabelle
InventTable. Auf den ersten Blick ist es nicht einfach zu erkenne aber aus 
<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
'<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> SQLSTMT('+dictTable.name()<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'
'+dictTable.name()<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>')\n{\n'+SELECTAnweisung+';\n}\n';<br /><br /></span>wird in der lesbaren Ansicht 
<br /><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> SQLSTMT(InventTable
InventTable)<br />
{<br />
    SELECT <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">*</span> FROM
InventTable;<br />
}</span></p><p>
und der globalen Variablen SQLAnweisung zugewiesen.<br />
Nur um sicher zugehen ob alles richtig geschrieben wurden und keine Kompilierungsfehler
enthalten sind, wird diese Anweisung noch dem Compiler übergeben und kompiliert.<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
compiler.compile(SQLAnweisung)</span><br /><br />
Wurden keine Fehler gefunden ist alles Prima, ansonsten wird die Variable noch gelöscht
um beim Ausführen der Methode executeQuery keine Fehler zu erhalten. Die Ausgabe der
Fehlermeldung vom Compiler ist optional.<br /><br />
Der Aufruf der Methode <font face="Verdana"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"initSQLAnweisung" </span></font>Methode
erfolgt noch dem super() in der Methode init der Maske.<br /></p><p>
Durch die SQL Anweisung hat man den Vorteil auf eine sehr einfache Art&amp;Weise sehr
komplexe Abfragen gestalten zu können. Einige Nachteile gibt es leider auch, die Standardfunktionen
wie Filtern oder Sortieren funktionieren im genannten Beispiel nicht mehr.
</p><p>
Das komplette Beispiel noch als xpo zum Download. Wie immer wurde auch dieses Beispiel
in Microsoft Dynamics Ax 4.0 erstellt.<br /><a href="http://starside.eu/content/binary/Form_ArtikelSQL.zip">Form_ArtikelSQL.zip
(1.08 KB)</a></p><img height="0" src="http://starside.eu/cptrk.ashx?id=38261862-3a22-427b-9100-c15c56753b13" width="0" /><img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=1cc5046b-1a59-4810-8d97-758ab5de391d" /><br /><hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Querys oder doch nicht ?</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,1cc5046b-1a59-4810-8d97-758ab5de391d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,1cc5046b-1a59-4810-8d97-758ab5de391d.aspx</link>
      <pubDate>Thu, 19 Apr 2007 21:51:15 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
Eigendlich wollte ich hier noch die erweiterten Möglichkeiten bei den Einschränkungen
zum Besten geben, das kann man aber schon alles fix und fertig bei &lt;a href="http://www.axaptapedia.com/Expressions_in_query_ranges"&gt;Axaptapedia&lt;/a&gt; nachlesen. 
&lt;br&gt;
&lt;br&gt;
Daher vorerst nur noch die eine Sache die ich noch beschreiben möchte:&lt;br&gt;
&lt;br&gt;
Möchte man eine Einschränkung auf einen Array Feld (die Dimension: Abteilung, Kostenstelle,
Kostenträger sind hierfür ein gutes Beispiel) definieren kann diese wie folgt erstellt
werden.&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.addRange(fieldid2ext(fieldnum(InventTable,
Dimension), 1));&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;Das erstellen der Range bleibt im Grunde gleich, nur das jetzt mittels fieldid2ext
noch der Array Index angegeben wird. Der Index beginnt in Microsoft Dynamics Ax immer
mit 1.&lt;br&gt;
&lt;br&gt;
Da nun diese Sache hier nicht mehr behandelt wird, möchte ich noch eine komplett andere
Möglichkeit zeigen Datensätze aus der Datenbank zu holen um diese beispielsweise in
Masken anzuzeigen. Anstelle einer Query kann man auch SQL Anweisungen verwenden.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Das wird ein bisschen Tricky...&lt;br&gt;
Ich fange aber heute nur "einfach" an.&lt;br&gt;
&lt;br&gt;
Zuerst bauen wir uns einen neue Form und nennen diese ArtikelSQL (Der Name ist hier
eigendlich egal, ich habe mich aber für eine Artikelmaske entschieden).&lt;br&gt;
Dann legen wir die InventTable mittels Drag&amp;amp;Drop als Datasource fest. Zum Abschluss
zeigen wir noch ein paar Feld (Artikelnummer und Artikelname reicht erstmal aus) über
ein neu hinzugefügtes Grid in dieser Maske an. Fertig - beim Aufruf der Maske erhalten
wir alle Datensätze die sich in der Tabelle InventTable befinden.&lt;br&gt;
&lt;br&gt;
Als nächsten Schritt definieren wir eine Variable in der Classdeclaration&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
Source SQLAnweisung;&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;In dieser Variable schreiben wir später unsere SQL Anweisung. Bevor das jedoch
gemacht wird, muss als nächstes noch die Methode executeQuery auf der DataSource überschrieben
werden.&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; executeQuery()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (SQLAnweisung)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; runbuf(SQLAnweisung, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.cursor());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; super();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;br&gt;
Neu&amp;nbsp; hinzugekommen ist hier die IF Abfrage, die prüft ob eine SQLAnweisung erstellt
wurde, bzw. ob die Variable SQLAnweisung nicht leer ist. Wurde&amp;nbsp; keine SQLAnweisung
getroffen, wird die Standardquery auf der DataSource ausgeführt. Wurde aber eine SQLAnweisung
getroffen wird diese nun Anstelle der Query ausgeführt.&lt;br&gt;
&lt;br&gt;
Zu guter letzt fehlt nur noch die SQLAnweisung, die erstellt werden muss.&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; initSQLAnweisung()&lt;br&gt;
{&lt;br&gt;
XppCompiler compiler &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; XppCompiler();&lt;br&gt;
DictTable dictTable= &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; DictTable(Tablenum(InventTAble));&lt;br&gt;
str SELECTAnweisung &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 'SELECT &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;*&lt;/span&gt; FROM
'+dictTable.name();&lt;br&gt;
&lt;br&gt;
SQLAnweisung &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; '&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; SQLSTMT('+dictTable.name()&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;'
'+dictTable.name()&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;')\n{\n'+SELECTAnweisung+';\n}\n';&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (!compiler.compile(SQLAnweisung))&lt;br&gt;
{&lt;br&gt;
setprefix(&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"@SYS57538"&lt;/span&gt;);&lt;br&gt;
info (SQLAnweisung);&lt;br&gt;
error (compiler.errorText());&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SQLAnweisung &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=
'';&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&amp;lt;&amp;gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;}&lt;br&gt;
}&lt;/span&gt;Diese Methode erstellt die SQL Anweisung. Es reicht nicht aus einfach ein
SELECT Statement zu schreiben, da der Compiler das nicht versteht. Anstelle eines
einzelenen SELECT Statement schreibt man einfach eine Methode drumherum, die dann
über runbuf ausgeführt wird. 
&lt;br&gt;
Das eigendliche SELECT Statement sieht wie folgt aus und wird gleich der Variable
SELECTANweisung zugewiesen.&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
SELECT &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;*&lt;/span&gt; FROM
InventTable&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;Über diese einfache Select Anweisung erhalten wir alle Datensätze aus der Tabelle
InventTable. Auf den ersten Blick ist es nicht einfach zu erkenne aber aus 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
'&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; SQLSTMT('+dictTable.name()&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;'
'+dictTable.name()&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;')\n{\n'+SELECTAnweisung+';\n}\n';&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;wird in der lesbaren Ansicht 
&lt;br&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; SQLSTMT(InventTable
InventTable)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;*&lt;/span&gt; FROM
InventTable;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
und der globalen Variablen SQLAnweisung zugewiesen.&lt;br&gt;
Nur um sicher zugehen ob alles richtig geschrieben wurden und keine Kompilierungsfehler
enthalten sind, wird diese Anweisung noch dem Compiler übergeben und kompiliert.&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
compiler.compile(SQLAnweisung)&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
Wurden keine Fehler gefunden ist alles Prima, ansonsten wird die Variable noch gelöscht
um beim Ausführen der Methode executeQuery keine Fehler zu erhalten. Die Ausgabe der
Fehlermeldung vom Compiler ist optional.&lt;br&gt;
&lt;br&gt;
Der Aufruf der Methode &lt;font face=Verdana&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"initSQLAnweisung" &lt;/span&gt;&lt;/font&gt;Methode
erfolgt noch dem super() in der Methode init der Maske.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
Durch die SQL Anweisung hat man den Vorteil auf eine sehr einfache Art&amp;amp;Weise sehr
komplexe Abfragen gestalten zu können. Einige Nachteile gibt es leider auch, die Standardfunktionen
wie Filtern oder Sortieren funktionieren im genannten Beispiel nicht mehr.
&lt;/p&gt;
&lt;p&gt;
Das komplette Beispiel noch als xpo zum Download. Wie immer wurde auch dieses Beispiel
in Microsoft Dynamics Ax 4.0 erstellt.&lt;br&gt;
&lt;a href="http://starside.eu/content/binary/Form_ArtikelSQL.zip"&gt;Form_ArtikelSQL.zip
(1.08 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=38261862-3a22-427b-9100-c15c56753b13" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=1cc5046b-1a59-4810-8d97-758ab5de391d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,1cc5046b-1a59-4810-8d97-758ab5de391d.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=b1d46eb8-15ae-415b-8a13-798fb38f91c8</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,b1d46eb8-15ae-415b-8a13-798fb38f91c8.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,b1d46eb8-15ae-415b-8a13-798fb38f91c8.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=b1d46eb8-15ae-415b-8a13-798fb38f91c8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In Microsoft Dynamics AX werden alle Benutzerberechtigungen über SecurityKeys
gesteuert. SecurityKeys können für Forms, Formcontrols, Tables, Tablefields,
MenuItems, etc. in deren Eigenschaften hinterlegt werden.
</p>
        <p>
Für Klassen ist dies zwar mit Hilfe eines MenuItems und der Implementation der
Methode "<em>static void Main(Args _args)</em>" ebenfalls möglich, doch kann
für eine einzelne Methode kein SecurityKey vergeben werden.
</p>
        <p>
Es gibt allerdings Situationen wo die Codeausführung, abhängig von der jeweiligen
Berechtigung des Benutzers, gesteuert werden soll/muss.<br />
In einem solchen Fall muss im X++ Code eine Überprüfung der Berechtigungen des Benutzers
durchgeführt werden.<br /><br />
Möchte man prüfen, ob ein Benutzer Zugriff auf einen SecurityKey hat, kann dies mit
der Methode <font color="#000000"><strong>hasSecurityAccess</strong></font> erfolgen.<br /><br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (
hasSecurityKeyAccess(securitykeyNum(CustSetup), AccessType::View) )<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.</span><br />
}</span></span></span></p>
        <p>
Möchte man prüfen, ob ein Benutzer Zugriff auf eine Tabelle hat, geht dies mit der
Methode <font color="#000000"><strong>hasTableAccess</strong></font>.<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
if</span> ( hasTableAccess(tablenum(CustTable), AccessType::Edit) )<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.</span><br />
}<br /></span></p>
        <p>
Muss nicht nur die Tabelle, sondern auch ein einzelnes Feld überprüft werden, kann
dies mit der Methode <font color="#000000"><strong>hasFieldAccess</strong></font> gemacht
werden.<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
if</span> ( hasFieldAccess(tablenum(CustTable), fieldnum(CustTable, AccountNum), AccessType::Delete)
)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.</span><br />
}<br /></span></p>
        <p>
Der Parameter <font color="#000000"><strong>AccessType</strong></font> bestimmt hierbei
auf welche Berechtigung das jeweilige Element gepürft wird (Kein Zugriff,
Anzeigen, Bearbeiten, Erstellen, Vollständige Kontrolle).
</p>
        <p>
Alle Methoden (hasSecurityAccess, hasTableAccess, hasFieldAccess) sind globale Methoden,
die in der Klasse Global definiert sind. Somit können diese Methoden an jeder beliebigen
Stelle im Quellcode verwendet werden. Es ist egal ob es sich um die Methode
einer Form, Datasource, Klasse oder Tabelle handelt.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=b1d46eb8-15ae-415b-8a13-798fb38f91c8" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Berechtigungen eines Benutzer mit X++ Code abfragen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,b1d46eb8-15ae-415b-8a13-798fb38f91c8.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,b1d46eb8-15ae-415b-8a13-798fb38f91c8.aspx</link>
      <pubDate>Fri, 13 Apr 2007 17:47:00 GMT</pubDate>
      <description>&lt;p&gt;
In Microsoft Dynamics AX&amp;nbsp;werden alle Benutzerberechtigungen über SecurityKeys
gesteuert. SecurityKeys können für&amp;nbsp;Forms, Formcontrols, Tables,&amp;nbsp;Tablefields,
MenuItems, etc. in deren Eigenschaften hinterlegt werden.
&lt;/p&gt;
&lt;p&gt;
Für Klassen ist dies zwar mit Hilfe eines MenuItems und der Implementation&amp;nbsp;der
Methode&amp;nbsp;"&lt;em&gt;static void Main(Args _args)&lt;/em&gt;" ebenfalls möglich, doch kann
für eine einzelne Methode kein SecurityKey vergeben werden.
&lt;/p&gt;
&lt;p&gt;
Es gibt allerdings Situationen wo die Codeausführung, abhängig von der jeweiligen
Berechtigung des Benutzers, gesteuert werden soll/muss.&lt;br&gt;
In einem solchen Fall muss im X++ Code eine Überprüfung der Berechtigungen des Benutzers
durchgeführt werden.&lt;br&gt;
&lt;br&gt;
Möchte man prüfen, ob ein Benutzer Zugriff auf einen SecurityKey hat, kann dies mit
der Methode &lt;font color=#000000&gt;&lt;strong&gt;hasSecurityAccess&lt;/strong&gt;&lt;/font&gt; erfolgen.&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (
hasSecurityKeyAccess(securitykeyNum(CustSetup), AccessType::View) )&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.&lt;/span&gt;
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&gt;&gt;Möchte man prüfen, ob ein Benutzer Zugriff auf eine Tabelle hat, geht dies mit der
Methode &lt;font color=#000000&gt;&lt;strong&gt;hasTableAccess&lt;/strong&gt;&lt;/font&gt;.&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
if&lt;/span&gt; ( hasTableAccess(tablenum(CustTable), AccessType::Edit) )&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.&lt;/span&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Muss nicht nur die Tabelle, sondern auch ein einzelnes Feld überprüft werden, kann
dies mit der Methode &lt;font color=#000000&gt;&lt;strong&gt;hasFieldAccess&lt;/strong&gt;&lt;/font&gt; gemacht
werden.&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
if&lt;/span&gt; ( hasFieldAccess(tablenum(CustTable), fieldnum(CustTable, AccountNum), AccessType::Delete)
)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Code
ausführen, wenn entsprechende Berechtigung vorhanden ist.&lt;/span&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Der Parameter &lt;font color=#000000&gt;&lt;strong&gt;AccessType&lt;/strong&gt;&lt;/font&gt; bestimmt hierbei
auf welche Berechtigung&amp;nbsp;das jeweilige&amp;nbsp;Element gepürft wird (Kein Zugriff,
Anzeigen, Bearbeiten, Erstellen, Vollständige Kontrolle).
&lt;/p&gt;
&lt;p&gt;
Alle Methoden (hasSecurityAccess, hasTableAccess, hasFieldAccess) sind globale Methoden,
die in der Klasse Global definiert sind. Somit können diese Methoden an jeder beliebigen
Stelle im Quellcode verwendet werden.&amp;nbsp;Es&amp;nbsp;ist egal ob es sich um die Methode
einer Form, Datasource, Klasse oder Tabelle handelt.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=b1d46eb8-15ae-415b-8a13-798fb38f91c8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,b1d46eb8-15ae-415b-8a13-798fb38f91c8.aspx</comments>
      <category>Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=4349376a-5f51-4659-b0a2-6b1d15257b68</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,4349376a-5f51-4659-b0a2-6b1d15257b68.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,4349376a-5f51-4659-b0a2-6b1d15257b68.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=4349376a-5f51-4659-b0a2-6b1d15257b68</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Nachdem
nun in <a href="http://starside.eu/PermaLink,guid,125c04d5-7ec0-4127-8766-e38991039fe2.aspx">diesem
Artikel</a> schon die ersten Schritte unternommen und vorhandene Elemente manipuliert
wurden, werden nun auch neue Elemente hinzuzugefügt. 
<br /></span>
          </font>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <br />
            </span>
          </font>
          <i>
            <font face="Arial" size="2">
              <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Einfügen
einer neuen Formcontrol im Design.</span>
            </font>
          </i>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <p>
              </p>
            </span>
          </font>
          <font face="Arial" size="2">
            <span lang="EN-GB" style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <font face="Arial" size="2">
                <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
                  <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FormRun
fr; 
<br />
Args args <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ARgs(); 
<br />
FormStringControl fsc; 
<br />
; 
<br />
args.name(formstr(InventTable)); 
<br />
fr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FormRun(args); 
<br />
fr.init(); 
<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue Control (Tabellenfeld "AltItemID") im Design anfügen</span><br />
fsc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.design().addDataField(fr.dataSource(1).id(),fieldnum(InventTAble,
altitemid)); 
<br />
fr.run(); 
<br />
fr.wait(); 
<br /></span>
                </span>
              </font>
            </span>
          </font>
        </p>
        <p>
        </p>
        <p>
          <font face="Arial" size="2">
            <font face="Arial" size="2">In dem o.g. Beispiel wird
das Feld Ersatz-Artikelnummer direkt im Design der Form eingefügt. Bei einem Datenfeld
ist es wichtig das als Datasource immer die ID der FormDatasource übergeben wird um
die richtige Referenz zu erhalten. Anstelle eines Datenfeldes kann natürlich auch
jedes andere Formcontrol eingefügt werden, was wiederrum anderen Möglichkeiten der
weiteren Verwendung bieten kann. Möchte man kein Datenfeld erzugen kann mit 
<br /></font>
          </font>
        </p>
        <p>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">.addControl(...</span>
        </p>
auch ein beliebiges FormControl hinzugefügt werden. Über den Enum FormControlType
wird die Art des Controls in Methode addControl als erstes Parameter festgelegt. 
<p></p><p></p><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">element.design().addControl(FormControltype::String, <span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"Neue
Control"</span>);</span></p><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br /></span></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Um
das Feld Ersatz-Artikelnummer Beispieltsweise im Überblick - Grid anzuzeigen muss
die Erzeugung der FormControl auch auf dem Grid geschehen. </span></font></font></p><p></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><i>Hierzu
wird die FormGridControl „Grid“ aus der Maske gesucht und dort das neue Feld hinzugefügt.</i><p></p></span></font></font></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FormRun
fr; 
<br />
Args args <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ARgs(); 
<br />
FormGridControl fgc; 
<br />
; 
<br />
args.name(formstr(InventTable)); 
<br />
fr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FormRun(args); 
<br />
fr.init(); 
<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Zugriff auf FormControl "Grid" aus dem Design </span><br />
fgc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.design().controlName(<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"Grid"</span>); 
<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Dem Grid ein neues Control hinzufügen</span><br />
fgc.addDataField(fr.dataSource(1).id(),fieldnum(InventTAble, altitemid)); 
<br />
fr.run(); 
<br />
fr.wait(); 
<br /><br /></span></span></font></p><p></p><p><font face="Arial" size="2">Eine neues FormControl wird also immer vom Vater (Übergeordneten)
Control aus erzeugt, im zweifelsfall also mindestens auf dem Design der Form.<br /></font></p><p></p><p></p><p><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">parentControl.addControl(… 
<br /><br /></span></span>es muss immer die FormControl gefunden werden auf dem die FormControl
erzeugt werden soll. Neue FormControls können nur auf Container FormControls, wie
Grid, TabPage, Group usw. erzeugt werden.</font></p><p><font size="2"><font face="Arial">Über X++ können alle Eigenschaften der FormControls
manipuliert werden. Je nach ControlTyp stehen unterschiedliche Eigenschaften zur Verfügung. </font></font><br /></p><p><font face="Arial" size="2"><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FormGroupControl
groupCtrl;<br />
FormStringControl stringCtrl;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Neue
Gruppe im Design einfügen</span><br />
groupCtrl <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> element.design().addControl(FormControlType::Group, <span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"Gruppe"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Neue
Zeichenfolge der Gruppehinzufügen</span><br />
stringCtrl <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> groupCtrl.addControl(FormControlType::String, <span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"ZeichenFolge"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Zuweisung
der DataSource</span><br />
stringCtrl.dataSource(element.dataSource().name());<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Zuweisung
des Feldes</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
stringCtrl.dataField(fieldnum(InventtAble, ItemID));</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Zuweisung
einer Methode der Tabelle</span><br />
stringCtrl.dataMethod(<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"ItemName"</span>);</span></p><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">stringCtrl.enabled(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
stringCtrl.visible(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);</span></p></font></p><p></p><p>
In dem Beispiel wird eine Gruppe direkt im Design erzeugt und in dieser Gruppe wird
ein Zeichenfolge eingefügt, die über die Methode ItemName auf der InventTable Daten
anzeigt.<br /></p><p><font face="Arial" size="2"><br /></font></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><i><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><u>Überschreiben
der Standardevents ausserhalb der Form</u></span></font></i></p><p></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Auch
Events wie Modified oder Validate können ausserhalb der Form überschrieben werden.
Hierzu muss der aufgerufenden Form mitgeteilt werden, das dieses nicht mehr in der
Maske passieren soll, sondern in dem aufrufenden Element (zb. In der Class). </span></font></p><p></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Das Überschreiben der Methoden erlauben </span><br />
fR.controlMethodOverload(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>); 
<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Das Objekt festlegen in der die Methoden definiert sind </span><br />
fR.controlMethodOverloadObject(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>); 
<br /><br /></span></span></font></p><p></p><p><font face="Arial" size="2">Nun kann man nicht pauschal für alle Controls eine Methode
definieren, sondern muss für jede Control eine eigende Definition erzeugen. Die Syntax
ist aber immer die gleiche und fängt mit der Benamung der Methode an. D.h. wurden
10 FormControls zur Laufzeit eingefügt müssen für jeden Event der verändert werden
soll eine neue Methode erzeugt werden. Eine Ausnahme, die aber oft zur Regel werden
kann, ist das nur für jeden unterschiedliche Namen der FormControls zusätzliche Methode
erzeugt werden müssen.</font></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">          
ControlName_MethodenName </span></font></p><p></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p></p></span></font><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Als
Beispiel kann die Control ctrlInventTable_ItemId (Artikelnummer im Reiter Übersicht)
wie folgt aussehen um die Änderung auf diesem Feld abzufragen </span></font></p><p></p><p></p><p></p><p class="MsoNormal"><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></span></font></p><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Public
boolean ctrlInventTable_ItemID_modified() 
<br />
{ <br />
   FormStringControl c <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> formrun.controlCallingMethod(); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Die  FormControl, von der der Aufruf erfolgt</span><br />
   boolean ret; <br />
   ; <br />
   ret <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> c.modified(); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Super() der aktuellen FormControl </span></span><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">aufrufen
-&gt;</span></span></span></font><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">modified<br /><br /></span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   return</span> ret; 
<br />
} 
<br /></span></p><p><font face="Arial" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Oben
genannte Methode entspricht der Standard Methode "modified" auf der FormControl "ctrlInventTable_ItemID"</span></font><font face="Courier New" size="2"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"></span></span></font></p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> boolean
modified()<br />
{<br />
    boolean ret;<br /><br />
    ret <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> super();<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
return</span> ret;<br />
}</span></p></span>In den og. Fall hätte man sich das Überschreiben der Methode Modified sparen
können, da nichts gemacht wird als die Standardfunktion aus Dynamics AX aufzurufen.
Es werden aber alle wichtigen Elemente dargestellt um einen ordnungsgemäße Funktionalität
zu gewährleisten. 
<br /><p class="MsoNormal"><i><u>Achtung:</u> Gibt es mehrere Controls in der Form die dieselben Namen haben,
werden auch die überschriebenen Methoden von all diesen Controls benutzt! Somit muss
die Unterschreidung welche Control das Event gerade ausgelöst hat hier abgefragt werden.
Es können aber nur Controls die zur Laufzeit per X++ erzeugt wurden den gleichen Namen
erhalten. Beim "normalen" Erstellen einer Form kann das nicht vorkommen...<br /></i></p></span></font><img height="0" src="http://starside.eu/cptrk.ashx?id=bb3a5718-92af-428e-9dea-d03bd615da76" width="0" /><img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=4349376a-5f51-4659-b0a2-6b1d15257b68" /><br /><hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Manipulation an der Form ausserhalb der Form Teil 2</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,4349376a-5f51-4659-b0a2-6b1d15257b68.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,4349376a-5f51-4659-b0a2-6b1d15257b68.aspx</link>
      <pubDate>Fri, 06 Apr 2007 16:24:45 GMT</pubDate>
      <description>&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Nachdem
nun in &lt;a href="http://starside.eu/PermaLink,guid,125c04d5-7ec0-4127-8766-e38991039fe2.aspx"&gt;diesem
Artikel&lt;/a&gt; schon die ersten Schritte unternommen und vorhandene Elemente manipuliert
wurden, werden nun auch neue Elemente hinzuzugefügt. 
&lt;br&gt;
&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;
&lt;br&gt;
&lt;/span&gt;&lt;/font&gt;&lt;i&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Einfügen
einer neuen Formcontrol im Design.&lt;/span&gt;&lt;/font&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FormRun
fr; 
&lt;br&gt;
Args args &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ARgs(); 
&lt;br&gt;
FormStringControl fsc; 
&lt;br&gt;
; 
&lt;br&gt;
args.name(formstr(InventTable)); 
&lt;br&gt;
fr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FormRun(args); 
&lt;br&gt;
fr.init(); 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue Control (Tabellenfeld "AltItemID") im Design anfügen&lt;/span&gt;
&lt;br&gt;
fsc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.design().addDataField(fr.dataSource(1).id(),fieldnum(InventTAble,
altitemid)); 
&lt;br&gt;
fr.run(); 
&lt;br&gt;
fr.wait(); 
&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;&lt;font face=Arial size=2&gt;In dem o.g. Beispiel wird das Feld
Ersatz-Artikelnummer direkt im Design der Form eingefügt. Bei einem Datenfeld ist
es wichtig das als Datasource immer die ID der FormDatasource übergeben wird um die
richtige Referenz zu erhalten. Anstelle eines Datenfeldes kann natürlich auch jedes
andere Formcontrol eingefügt werden, was wiederrum anderen Möglichkeiten der weiteren
Verwendung bieten kann. Möchte man kein Datenfeld erzugen kann mit 
&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;.addControl(...&lt;/span&gt;
&lt;/p&gt;
auch ein beliebiges FormControl hinzugefügt werden. Über den Enum FormControlType
wird die Art des Controls in Methode addControl als erstes Parameter festgelegt. 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;element.design().addControl(FormControltype::String, &lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"Neue
Control"&lt;/span&gt;);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Um
das Feld Ersatz-Artikelnummer Beispieltsweise im Überblick - Grid anzuzeigen muss
die Erzeugung der FormControl auch auf dem Grid geschehen. &lt;/span&gt;&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;i&gt;Hierzu
wird die FormGridControl „Grid“ aus der Maske gesucht und dort das neue Feld hinzugefügt.&lt;/i&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FormRun
fr; 
&lt;br&gt;
Args args &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ARgs(); 
&lt;br&gt;
FormGridControl fgc; 
&lt;br&gt;
; 
&lt;br&gt;
args.name(formstr(InventTable)); 
&lt;br&gt;
fr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FormRun(args); 
&lt;br&gt;
fr.init(); 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Zugriff auf FormControl "Grid" aus dem Design &lt;/span&gt;
&lt;br&gt;
fgc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.design().controlName(&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"Grid"&lt;/span&gt;); 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Dem Grid ein neues Control hinzufügen&lt;/span&gt;
&lt;br&gt;
fgc.addDataField(fr.dataSource(1).id(),fieldnum(InventTAble, altitemid)); 
&lt;br&gt;
fr.run(); 
&lt;br&gt;
fr.wait(); 
&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;Eine neues FormControl wird also immer vom Vater (Übergeordneten)
Control aus erzeugt, im zweifelsfall also mindestens auf dem Design der Form.&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;parentControl.addControl(… 
&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;es muss immer die FormControl gefunden werden auf dem die FormControl
erzeugt werden soll. Neue FormControls können nur auf Container FormControls, wie
Grid, TabPage, Group usw. erzeugt werden.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;&lt;font face=Arial&gt;Über X++ können alle Eigenschaften der FormControls
manipuliert werden. Je nach ControlTyp stehen unterschiedliche Eigenschaften zur Verfügung. &lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FormGroupControl
groupCtrl;&lt;br&gt;
FormStringControl stringCtrl;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Neue
Gruppe im Design einfügen&lt;/span&gt;
&lt;br&gt;
groupCtrl &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; element.design().addControl(FormControlType::Group, &lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"Gruppe"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Neue
Zeichenfolge der Gruppehinzufügen&lt;/span&gt;
&lt;br&gt;
stringCtrl &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; groupCtrl.addControl(FormControlType::String, &lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"ZeichenFolge"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Zuweisung
der DataSource&lt;/span&gt;
&lt;br&gt;
stringCtrl.dataSource(element.dataSource().name());&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Zuweisung
des Feldes&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
stringCtrl.dataField(fieldnum(InventtAble, ItemID));&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Zuweisung
einer Methode der Tabelle&lt;/span&gt;
&lt;br&gt;
stringCtrl.dataMethod(&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"ItemName"&lt;/span&gt;);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;stringCtrl.enabled(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
stringCtrl.visible(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;/span&gt;
&lt;/p&gt;
&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In dem Beispiel wird eine Gruppe direkt im Design erzeugt und in dieser Gruppe wird
ein Zeichenfolge eingefügt, die über die Methode ItemName auf der InventTable Daten
anzeigt.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;
&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;i&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;u&gt;Überschreiben
der Standardevents ausserhalb der Form&lt;/u&gt; &lt;/span&gt;&lt;/font&gt;&lt;/i&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Auch
Events wie Modified oder Validate können ausserhalb der Form überschrieben werden.
Hierzu muss der aufgerufenden Form mitgeteilt werden, das dieses nicht mehr in der
Maske passieren soll, sondern in dem aufrufenden Element (zb. In der Class). &lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Das Überschreiben der Methoden erlauben &lt;/span&gt;
&lt;br&gt;
fR.controlMethodOverload(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;); 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Das Objekt festlegen in der die Methoden definiert sind &lt;/span&gt;
&lt;br&gt;
fR.controlMethodOverloadObject(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;); 
&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;Nun kann man nicht pauschal für alle Controls eine Methode
definieren, sondern muss für jede Control eine eigende Definition erzeugen. Die Syntax
ist aber immer die gleiche und fängt mit der Benamung der Methode an. D.h. wurden
10 FormControls zur Laufzeit eingefügt müssen für jeden Event der verändert werden
soll eine neue Methode erzeugt werden. Eine Ausnahme, die aber oft zur Regel werden
kann, ist das nur für jeden unterschiedliche Namen der FormControls zusätzliche Methode
erzeugt werden müssen.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ControlName_MethodenName &lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Als
Beispiel kann die Control ctrlInventTable_ItemId (Artikelnummer im Reiter Übersicht)
wie folgt aussehen um die Änderung auf diesem Feld abzufragen &lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Public
boolean ctrlInventTable_ItemID_modified() 
&lt;br&gt;
{&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;FormStringControl c &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; formrun.controlCallingMethod(); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Die&amp;nbsp; FormControl, von der der Aufruf erfolgt&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;boolean ret;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; c.modified(); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Super() der aktuellen FormControl &lt;/span&gt;&lt;/span&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;aufrufen
-&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;modified&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; ret; 
&lt;br&gt;
} 
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Oben genannte
Methode entspricht der Standard Methode "modified" auf der FormControl "ctrlInventTable_ItemID"&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; boolean
modified()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean ret;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ret &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; super();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return&lt;/span&gt; ret;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt;In den og. Fall hätte man sich das Überschreiben der Methode Modified sparen
können, da nichts gemacht wird als die Standardfunktion aus Dynamics AX aufzurufen.
Es werden aber alle wichtigen Elemente dargestellt um einen ordnungsgemäße Funktionalität
zu gewährleisten. 
&lt;br&gt;
&lt;p class=MsoNormal&gt;
&lt;i&gt;&lt;u&gt;Achtung:&lt;/u&gt; Gibt es mehrere Controls in der Form die dieselben Namen haben,
werden auch die überschriebenen Methoden von all diesen Controls benutzt! Somit muss
die Unterschreidung welche Control das Event gerade ausgelöst hat hier abgefragt werden.
Es können aber nur Controls die zur Laufzeit per X++ erzeugt wurden den gleichen Namen
erhalten. Beim "normalen" Erstellen einer Form kann das nicht vorkommen...&lt;br&gt;
&lt;/i&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=bb3a5718-92af-428e-9dea-d03bd615da76" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=4349376a-5f51-4659-b0a2-6b1d15257b68" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,4349376a-5f51-4659-b0a2-6b1d15257b68.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=4013c5a2-8a08-475d-9e33-e993bf6539e6</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,4013c5a2-8a08-475d-9e33-e993bf6539e6.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,4013c5a2-8a08-475d-9e33-e993bf6539e6.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=4013c5a2-8a08-475d-9e33-e993bf6539e6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
Das man in Microsoft Dynamics Ax mittels Drag&amp;Drop einfach Tabellenfelder (Fields)
oder Tabellenfeldgruppen (Fieldgroups) in Masken (Forms) einfügen kann ist allgemein
bekannt. 
<br />
Mittels Tabellenfeldgruppen können die gewünschten Felder in die Masken integriert
werden. Dadurch ist das Hinzufügen oder Entfernen der Tabellenfelder auf einfache
Art Zentral auf Tabellenebene möglich, ohne die Maske anpassen zu müssen.<br /><br />
Was für mich bis dato noch neu war: Es ist auch möglich auf einem Grid eine Tabellenfeldgruppe
zu hinterlegen und direkt diesem FormControl alle Felder, die der Tabellenfeldgruppe
hinterlegt wurden, zuzuweisen. Microsoft hat in der aktuellen Version von Microsoft Dynamics
Ax 4.0 damit auch schon angefangen, dieses in den Forms aktiv zu nutzen. Bisher ist
mir das zumindest noch nicht aufgefallen. In den Masken zur Adressverwaltung ("Address...")
werden hier nun auf dem Reiter "Überblick" die Felder mittels Feldgruppe auf dem Grid
hinzugefügt (bsp: Form "AddressCountryRegion") oder es wird die Tabellenfeldgruppe
direkt dem Grid zugeordnet (bsp: Form "AddressZipCodes"). 
<br /><br />
Die Zuordnung erfolgt immer über die Eigenschaft "DataGroup". Die Eigenschaft "DataSource"
muss selbstverständlich auch hierzu vorher gefüllt werden um dann mittels Lookup in
der Eigenschaft "DataGroup" eine Auswahl auf alle Tabellenfeldgruppen der aktuell
ausgewählten Tabelle zu erhalten.  
<br /><br /><img src="http://starside.eu/content/binary/MaskeAuftrag_EigenschaftDataSource.JPG" border="0" /><br /><font size="1"><i>Eigenschaft der FormGridControl "Grid"<br /><br /><br /></i></font>Nach Auswahl der DataGroup werden alle Felder automatisch dem aktuellen
Objekt zugeordnet.<br /><br /><img src="http://starside.eu/content/binary/FormAuftrag_Grid.jpg" border="0" /><br /><font size="1"><i>FormGridControl erhält nach Zuweisung der Eigenschaft "DataGroup"
alle Felder der ausgewählten Feldgruppe<br /><br /></i><br /></font>Man muss aber beachten, das ein manuelles hinzufügen von Feldern nicht mehr
funktioniert. D.h. im FormDesigner sieht alles prima aus, alle Felder, auch die manuell
hinzugefügten, werden angezeigt, beim Aufruf der Maske sind aber nur die Felder sichtbar,
die auch in der aktuellen Tabellenfeldgruppe hinterlegt wurden. 
<br />
Wird jedoch die Eigenschaft AutoDataGroup auf "Yes" gesetzt ist ein manuelles hinzufügen
von Elementen nicht mehr möglich! Auch bereits vorhandene Elemente werde, sofern manuell
hinzugefügt und nicht in der aktuellen Feldgruppe hinterlegt, wieder entfernt. Wird
eine Feldgruppe mittels Drag&amp;Drop in der Form hinzugefügt, ist die Eigenschaft
AutoDataGroup schon standardmäßig auf "Yes" gesetzt.<br />
Es gilt aber immer: Sobald die DataGroup befüllt ist, werden alle Elemente die nicht
der aktuellen Feldgruppe auf der Tabelle zugeordnet wurde nicht mehr angezeigt/ berücksichtigt.<br /><br />
Meiner Meinung wieder ein Schritt in die richtige Richtung, denn dadurch lassen sich
Anpassungen an einer Form weiter minimieren. Das kann wieder einen verminderten Anpassungsaufwand,
speziell bei Upgrades bedeuten, da bei Masken meiner Erfahrung nach mit die größte
Zeit aufgewendet werden muss.<br /><img height="0" src="http://starside.eu/cptrk.ashx?id=738878e8-d4c1-4f89-95d3-b8dbee09a933" width="0" /><img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=4013c5a2-8a08-475d-9e33-e993bf6539e6" /><br /><hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>FormControls und Tabellen/ Felder/ Gruppen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,4013c5a2-8a08-475d-9e33-e993bf6539e6.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,4013c5a2-8a08-475d-9e33-e993bf6539e6.aspx</link>
      <pubDate>Fri, 30 Mar 2007 21:08:52 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
Das man in Microsoft Dynamics Ax mittels Drag&amp;amp;Drop einfach Tabellenfelder (Fields)
oder Tabellenfeldgruppen (Fieldgroups) in Masken (Forms) einfügen kann ist allgemein
bekannt. 
&lt;br&gt;
Mittels Tabellenfeldgruppen können die gewünschten Felder in die Masken integriert
werden. Dadurch ist das Hinzufügen oder Entfernen der Tabellenfelder auf einfache
Art Zentral auf Tabellenebene möglich, ohne die Maske anpassen zu müssen.&lt;br&gt;
&lt;br&gt;
Was für mich bis dato noch neu war: Es ist auch möglich auf einem Grid eine Tabellenfeldgruppe
zu hinterlegen und direkt diesem FormControl alle Felder, die der Tabellenfeldgruppe
hinterlegt wurden, zuzuweisen. Microsoft hat in der aktuellen Version von Microsoft&amp;nbsp;Dynamics
Ax 4.0 damit auch schon angefangen, dieses in den Forms aktiv zu nutzen. Bisher ist
mir das zumindest noch nicht aufgefallen. In den Masken zur Adressverwaltung ("Address...")
werden hier nun auf dem Reiter "Überblick" die Felder mittels Feldgruppe auf dem Grid
hinzugefügt (bsp: Form "AddressCountryRegion") oder es wird die Tabellenfeldgruppe
direkt dem Grid zugeordnet (bsp: Form "AddressZipCodes"). 
&lt;br&gt;
&lt;br&gt;
Die Zuordnung erfolgt immer über die Eigenschaft "DataGroup". Die Eigenschaft "DataSource"
muss selbstverständlich auch hierzu vorher gefüllt werden um dann mittels Lookup in
der Eigenschaft "DataGroup" eine Auswahl auf alle Tabellenfeldgruppen der aktuell
ausgewählten Tabelle zu erhalten.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
&lt;img src="http://starside.eu/content/binary/MaskeAuftrag_EigenschaftDataSource.JPG" border=0&gt;
&lt;br&gt;
&lt;font size=1&gt;&lt;i&gt;Eigenschaft der FormGridControl "Grid"&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/i&gt;&lt;/font&gt;Nach Auswahl der DataGroup werden alle Felder automatisch dem aktuellen
Objekt zugeordnet.&lt;br&gt;
&lt;br&gt;
&lt;img src="http://starside.eu/content/binary/FormAuftrag_Grid.jpg" border=0&gt;
&lt;br&gt;
&lt;font size=1&gt;&lt;i&gt;FormGridControl erhält nach Zuweisung der Eigenschaft "DataGroup"
alle Felder der ausgewählten Feldgruppe&lt;br&gt;
&lt;br&gt;
&lt;/i&gt;
&lt;br&gt;
&lt;/font&gt;Man muss aber beachten, das ein manuelles hinzufügen von Feldern nicht mehr
funktioniert. D.h. im FormDesigner sieht alles prima aus, alle Felder, auch die manuell
hinzugefügten, werden angezeigt, beim Aufruf der Maske sind aber nur die Felder sichtbar,
die auch in der aktuellen Tabellenfeldgruppe hinterlegt wurden. 
&lt;br&gt;
Wird jedoch die Eigenschaft AutoDataGroup auf "Yes" gesetzt ist ein manuelles hinzufügen
von Elementen nicht mehr möglich! Auch bereits vorhandene Elemente werde, sofern manuell
hinzugefügt und nicht in der aktuellen Feldgruppe hinterlegt, wieder entfernt. Wird
eine Feldgruppe mittels Drag&amp;amp;Drop in der Form hinzugefügt, ist die Eigenschaft
AutoDataGroup schon standardmäßig auf "Yes" gesetzt.&lt;br&gt;
Es gilt aber immer: Sobald die DataGroup befüllt ist, werden alle Elemente die nicht
der aktuellen Feldgruppe auf der Tabelle zugeordnet wurde nicht mehr angezeigt/ berücksichtigt.&lt;br&gt;
&lt;br&gt;
Meiner Meinung wieder ein Schritt in die richtige Richtung, denn dadurch lassen sich
Anpassungen an einer Form weiter minimieren. Das kann wieder einen verminderten Anpassungsaufwand,
speziell bei Upgrades bedeuten, da bei Masken meiner Erfahrung nach mit die größte
Zeit aufgewendet werden muss.&lt;br&gt;
&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=738878e8-d4c1-4f89-95d3-b8dbee09a933" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=4013c5a2-8a08-475d-9e33-e993bf6539e6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,4013c5a2-8a08-475d-9e33-e993bf6539e6.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=2afd368f-49fc-4af4-b3ff-5d58fabb4a4b</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,2afd368f-49fc-4af4-b3ff-5d58fabb4a4b.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,2afd368f-49fc-4af4-b3ff-5d58fabb4a4b.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=2afd368f-49fc-4af4-b3ff-5d58fabb4a4b</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Wie schon in <a href="http://blog.ak-home.net/PermaLink,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx">diesem
Artikel</a> beschrieben ist es auch unter Dynamics AX 4.0 möglich, den Text der Titelleiste
zu verändern.
</p>
        <p>
Hierzu ein kurzes Beispiel:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> workspaceWindowCreated(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> _hWnd)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Put workspace window specific initialization here.</span><br />
str orgTitleBarText, newTitleBarText;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> posBracket,
lenTitle;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Show
the configuration file name in the titlebar - START</span><br /><br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Without
session id:</span><br />
orgTitleBarText <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> WinAPI::getWindowText(_hWnd);<br />
lenTitle <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> strLen(orgTitleBarText);<br />
posBracket <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> strScan(orgTitleBarText, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"["</span>,
1, lenTitle);<br /><br />
newTitleBarText <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> subStr(orgTitleBarText,
1, posBracket);<br />
newTitleBarText <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> strfmt(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"%1%2]"</span>,
newTitleBarText, xInfo::configuration());<br /><br />
WinAPI::setWindowText(_hWnd, newTitleBarText);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Show
the configuration file name in the titlebar - END</span><br />
}</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">Die
Anpassung der Methode "workspaceWindowCreated" der Klasse "Info" liefert folgenden
Text in der Titelleiste:</font>
          </span>
        </p>
        <p>
          <img src="http://blog.ak-home.net/content/binary/Titelleiste.jpg" border="0" />
        </p>
        <p>
Hierbei wird der Name der Dynamics AX Client Configuration, die für diese Session
verwendet, wird innerhalb der eckigen Klammern angezeigt.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=2afd368f-49fc-4af4-b3ff-5d58fabb4a4b" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Ändern des Textes der Titelleiste - Ein Beispiel</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,2afd368f-49fc-4af4-b3ff-5d58fabb4a4b.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,2afd368f-49fc-4af4-b3ff-5d58fabb4a4b.aspx</link>
      <pubDate>Tue, 27 Mar 2007 07:22:24 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Wie schon in &lt;a href="http://blog.ak-home.net/PermaLink,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx"&gt;diesem
Artikel&lt;/a&gt; beschrieben ist es auch unter Dynamics AX 4.0 möglich, den Text der Titelleiste
zu verändern.
&lt;/p&gt;
&lt;p&gt;
Hierzu ein kurzes Beispiel:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; workspaceWindowCreated(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _hWnd)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Put workspace window specific initialization here.&lt;/span&gt;
&lt;br&gt;
str orgTitleBarText, newTitleBarText;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; posBracket,
lenTitle;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Show
the configuration file name in the titlebar - START&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Without
session id:&lt;/span&gt;
&lt;br&gt;
orgTitleBarText &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; WinAPI::getWindowText(_hWnd);&lt;br&gt;
lenTitle &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; strLen(orgTitleBarText);&lt;br&gt;
posBracket &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; strScan(orgTitleBarText, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"["&lt;/span&gt;,
1, lenTitle);&lt;br&gt;
&lt;br&gt;
newTitleBarText &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; subStr(orgTitleBarText,
1, posBracket);&lt;br&gt;
newTitleBarText &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; strfmt(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"%1%2]"&lt;/span&gt;,
newTitleBarText, xInfo::configuration());&lt;br&gt;
&lt;br&gt;
WinAPI::setWindowText(_hWnd, newTitleBarText);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Show
the configuration file name in the titlebar - END&lt;/span&gt;
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;Die
Anpassung der Methode "workspaceWindowCreated" der Klasse "Info" liefert folgenden
Text in der Titelleiste:&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.ak-home.net/content/binary/Titelleiste.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Hierbei wird der Name der Dynamics AX Client Configuration, die für diese Session
verwendet, wird innerhalb der eckigen Klammern angezeigt.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=2afd368f-49fc-4af4-b3ff-5d58fabb4a4b" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,2afd368f-49fc-4af4-b3ff-5d58fabb4a4b.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=ed9ab4cf-611b-488e-8090-dac061c91371</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,ed9ab4cf-611b-488e-8090-dac061c91371.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,ed9ab4cf-611b-488e-8090-dac061c91371.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ed9ab4cf-611b-488e-8090-dac061c91371</wfw:commentRss>
      <title>QueryValues in QueryRanges</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,ed9ab4cf-611b-488e-8090-dac061c91371.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,ed9ab4cf-611b-488e-8090-dac061c91371.aspx</link>
      <pubDate>Mon, 26 Mar 2007 18:13:25 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;font face=Verdana&gt;Es gibt Tage da wundert man sich über Dinge mit denen man alltäglich
zu tun hat...&lt;br&gt;
So geschehen mit QueryRanges und deren QueryValues...&lt;br&gt;
&lt;br&gt;
&lt;/font&gt; 
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;font face=Verdana&gt;Beim
Definieren einer QueryRange ist darauf zu achten, dass die QueryValue als Datentyp
der QueryRange festgelegt wird. Wird beim Filtern auf einem Preis (Real) ein String
als Kriterium festgelegt erhält man je nachdem ob dieser String in einen gültigen
Realwert gewandelt werden konnte unterschiedliche Resultate.&amp;nbsp;Möglicherweise werden,
wenn ein ungültiges Kriterium festgelegt wurde, alle Datensätze zurückgegeben.&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;?xml:namespace prefix = o /&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=a166af9d-eb78-41fe-8bba-55dee7800e7c" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=ed9ab4cf-611b-488e-8090-dac061c91371" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,ed9ab4cf-611b-488e-8090-dac061c91371.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=31125330-500a-4284-9265-3ea36b1d0eed</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=31125330-500a-4284-9265-3ea36b1d0eed</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Unter Microsoft Dynamics AX 3.0 war es recht einfach den Text in der Titelleiste zu
verändern. Dies war sogar auf mehere verschiedene Arten möglich.<br />
Unter Dynamics AX 4.0 funktionieren diese bekannten Methoden leider nicht mehr. 
</p>
        <p>
Allerdings existiert unter Dyanamics AX 4.0 eine neue Möglichkeit den Text in der
Titelleiste zu verändert.<br />
Hierfür ist es nur erforderlich die Methode "workspaceWindowCreated" der Klasse "Info"
zu überschreiben.
</p>
        <p>
Wie dies genau gemacht werden kann, ist in dem Artikel <a href="http://www.axaptapedia.com/Configuration_in_title_bar">Configuration
in title bar</a> auf Axaptapedia beschrieben.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=31125330-500a-4284-9265-3ea36b1d0eed" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>&amp;Auml;ndern des Textes der Titelleiste von Dynamics AX 4.0</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx</link>
      <pubDate>Mon, 26 Mar 2007 18:13:22 GMT</pubDate>
      <description>&lt;p&gt;
Unter Microsoft Dynamics AX 3.0 war es recht einfach den Text in der Titelleiste zu
verändern. Dies war sogar auf mehere verschiedene Arten möglich.&lt;br&gt;
Unter Dynamics AX 4.0 funktionieren diese bekannten Methoden leider nicht mehr. 
&lt;/p&gt;
&lt;p&gt;
Allerdings existiert unter Dyanamics AX 4.0 eine neue Möglichkeit den Text in der
Titelleiste zu verändert.&lt;br&gt;
Hierfür ist es nur erforderlich die Methode "workspaceWindowCreated" der Klasse "Info"
zu überschreiben.
&lt;/p&gt;
&lt;p&gt;
Wie dies genau gemacht werden kann, ist in dem Artikel &lt;a href="http://www.axaptapedia.com/Configuration_in_title_bar"&gt;Configuration
in title bar&lt;/a&gt; auf Axaptapedia beschrieben.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=31125330-500a-4284-9265-3ea36b1d0eed" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,31125330-500a-4284-9265-3ea36b1d0eed.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=8a1e4768-7b59-4e8d-9574-10c6622821b0</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,8a1e4768-7b59-4e8d-9574-10c6622821b0.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,8a1e4768-7b59-4e8d-9574-10c6622821b0.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8a1e4768-7b59-4e8d-9574-10c6622821b0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Der Umgang mit Queries ist auch in Microsoft Dynamics AX sehr einfach, sofern man
mit den Objekten vertraut ist.<br />
Angefangen mit einem einfachen Query, der kann entweder auf Basis eines im AOT (Query)
definierten Querys erzeugt werden<br />
oder auch komplett neu mit x++ erzeugt werden kann.
</p>
        <p>
Folgende Okjekte werden verwendet
</p>
        <p style="MARGIN-RIGHT: 0px">
Query (Abfrage)<br />
QueryRun (führt die Abfrage aus)<br />
QueryBuildDataSource (DataSource in der Abfrage)<br />
QueryBuildRange (Range (Einschränkung) auf der DataSource)
</p>
        <p>
          <br />
Kurzes Beispiel:
</p>
        <p>
Das Ergebniss ist die Ausgabe alle Artikel bei denen die Artikelgruppe "Teile" hinterlegt
wurde.
</p>
        <p>
Auf Basis eines im AOT definierten Queries
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Ein
neues Query Objekt, verwendet wird die Query (Im AOT) "InventTable"</span>
            <br />
Query queryInventTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Query(querystr(InventTable));<br /><br />
QueryRun queryRun;<br />
QueryBuildDataSource queryDS;<br />
QueryBuildRange queryRange;<br />
InventTable inventTable;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource zuordnen</span><br />
queryDS <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryInventTable.dataSourceTable(tablenum(InventTable));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Prüfen ob Range schon vorhanden</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (queryDS.findRange(fieldnum(InventTable,
ItemGroupID)))<br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.findRange(fieldnum(InventTable,
ItemGroupID));<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.addRange(fieldnum(InventTable,
ItemGroupID));<br /><br />
queryRange.value(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Teile"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
queryRun mit dem aktuell neu erstellen query auf Basis des Queries "InventTable" erzeugen</span><br />
queryRun <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> QueryRun(queryInventTable);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
alle Datensätze ausgeben</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">while</span> (queryRun.next())<br />
{<br />
inventTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryRun.get(tablenum(InventTable));<br />
print InventTable.ItemID;<br />
}<br />
pause;<br /><br /></span>
        </p>
        <p>
          <br />
Komplett in X++ definierte Query
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Ein
neues leeres Query Objekt</span>
            <br />
Query query <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Query();<br />
QueryRun queryRun;<br />
QueryBuildDataSource queryDS;<br />
QueryBuildRange queryRange;<br /><br />
InventTable inventTable;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource (Tabelle InventTable) hinzufügen</span><br />
queryDS <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> query.addDataSource(tablenum(InventTable));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Range definineren</span><br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.addRange(fieldnum(InventTable,
ItemGroupID));<br />
queryRange.value(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Teile"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
alternative</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Range definineren</span><br />
query.dataSourceTable(tablenum(InventTable)).addRange(fieldnum(InventTable, ItemGroupID)).value(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Teile"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
queryRun mit dem aktuell neu erstellen query erzeugen</span><br />
queryRun <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> QueryRun(query);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
alle Datensätze ausgeben</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">while</span> (queryRun.next())<br />
{<br />
inventTable <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryRun.get(tablenum(InventTable));<br />
print InventTable.ItemID;<br />
}<br /></span>
        </p>
        <p>
Bei diesem einfachen Query macht es keinen Unterschied ob im AOT definiertes Query
verwendet wird, oder ob man die definition komplett in X++ vornimmt.<br />
Benutzt man ein Query das schon irgendwo definiert wurde und möchte dieses verwenden,
sollte man immer auf schon vorhandene Objekte (siehe findRange)<br />
zurückgegriffen werden sofern schon vorhanden.Ansonsten fügt man immer wieder dasselbe
Objekt hinzu, bei Ranges hat das dann zufolge, das in der Abfrage nicht mehr auf die
aktuell<br />
definierte Range zurückgegriffen wird, sondern auf alle davor definieren Ranges ebenfalls.<br />
Das kann sehr gut in dem unterem Beispiel getestet werden, indem man einfach eine
neue Range auf demselben Feld wie schon zuvor definiert hinzufügt und eine anderen<br />
Wert festlegt.
</p>
        <p>
Das Ergebnis ist die Ausgabe alle Artikel bei denen die Artikelgruppe "Teile" und
"Lampen" hinterlegt wurde.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Range definineren</span>
            <br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.addRange(fieldnum(InventTable,
ItemGroupID));<br />
queryRange.value(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Teile"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue Range auf demselben Feld. ein andere Wert wird festgelegt </span><br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDS.addRange(fieldnum(InventTable,
ItemGroupID));<br />
queryRange.value(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Lampen"</span>);<br /></span>
        </p>
        <p>
          <br />
Der Zugriff auf einzelne Elemente (wie DataSource oder Range) der Query ist jeweils
immer gleich. Bei der DataSource sollte immer beachtet werden, dass es ggf. mehrere
Objekte vom selben Typ (Tabelle) geben könnte. Ein gutes Beispiel hierfür sind wieder
die Artikel (InventTable) mit den drei verknüpften Lagermodulparameter (InventTableModule).
Wir hierbei der Zugriff auf die DataSource über tablenum gesteuert erhält man immer
ein und dieselbe DataSource und nicht wie evtl gewünscht alle drei DataSources.<br />
Der Zugriff sollte dann über den DataSource-Namen erfolgen, der immer eindeutig ist,
sogar dann wenn das hinzufügen per x++ geschieht.
</p>
        <p>
Hinzufügen von drei neuen DataSources und der Zugriff auf jeder DataSource der aktuellen
Abfragen, inkl. Ausgabe des Namen<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"></span></p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Query
query <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Query();<br />
counter dsCount;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource (Tabelle InventTable) hinzufügen</span><br />
queryDSInvent= query.addDataSource(tablenum(InventTable));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//neue
relation auf Lagermodulparameter (3mal)</span><br />
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span> Ausgabe
aller DataSources die im aktuellen Query vorhanden sind<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">for</span> (dsCount <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1;
dsCount &lt;= query.dataSourceCount(); dsCount++)<br />
{<br />
print query.dataSourceNo(dsCount).name();<br />
}<br />
pause;</span>
        </p>
        <p>
Wird der DataSource kein Name zugewiesen erzeugt Dynamics AX automatisch einen eindeutigen
Namen (Tabellenname_Zähler).
</p>
        <p>
Hinterlegt man nun noch bei den LagerModulparametern eine Range (Verkauf, Einkauf,
Lager) auf den Lagertyp hat man im groben die Standardquery (es fehlt noch die Lagerortverwaltung
Tabelle) der Artikelmaske nachgebaut.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Lager</span>
            <br />
queryDS <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDSInvent.addDataSource(tablenum(InventTableModule));<br />
queryDS.relations(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
queryDS.joinMode(JoinMode::InnerJoin);<br />
queryRange <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> queryDs.addRange(fieldnum(InventTableModule,ModuleType));<br />
queryRange.value(queryValue(ModuleInventPurchSales::Invent));</span>
        </p>
        <p>
Prinzipiell kann man mit dieser Query auch die Query auf der Maske InventTable überladen.
Diee Anzeige der Artikel klappt weiterhin wunderbar<br />
nur die Referenzen auf die zusätzlichen FormDataSources geht hierbei verloren. Dadurch
funktioniert die Anzeige und Bearbeitung der Daten aus diesen FormDataSources dann
nicht mehr.
</p>
        <p>
Spasseshalber aber noch der Quellcode, der auch die Query der Form überlädt.
</p>
        <a href="http://starside.eu/content/binary/Job_QueryEinfachFormRun.xpo">Job_QueryEinfachFormRun.xpo
(3,05 KB)</a>
        <img height="0" src="http://starside.eu/cptrk.ashx?id=a104656d-5ae3-4931-83ef-4bf6793e69ba" width="0" />
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=8a1e4768-7b59-4e8d-9574-10c6622821b0" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Erste Schritte mit Queries in Microsoft Dynamics AX</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,8a1e4768-7b59-4e8d-9574-10c6622821b0.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,8a1e4768-7b59-4e8d-9574-10c6622821b0.aspx</link>
      <pubDate>Fri, 23 Mar 2007 21:42:02 GMT</pubDate>
      <description>&lt;p&gt;
Der Umgang mit Queries ist auch in Microsoft Dynamics AX sehr einfach, sofern man
mit den Objekten vertraut ist.&lt;br&gt;
Angefangen mit einem einfachen Query, der kann entweder auf Basis eines im AOT (Query)
definierten Querys erzeugt werden&lt;br&gt;
oder auch komplett neu mit x++ erzeugt werden kann.
&lt;/p&gt;
&lt;p&gt;
Folgende Okjekte werden verwendet
&lt;/p&gt;
&lt;p style="MARGIN-RIGHT: 0px"&gt;
Query (Abfrage)&lt;br&gt;
QueryRun&amp;nbsp;(führt die Abfrage aus)&lt;br&gt;
QueryBuildDataSource&amp;nbsp;(DataSource in der Abfrage)&lt;br&gt;
QueryBuildRange (Range (Einschränkung) auf der DataSource)
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Kurzes Beispiel:
&lt;/p&gt;
&lt;p&gt;
Das Ergebniss ist die Ausgabe alle Artikel bei denen die Artikelgruppe "Teile" hinterlegt
wurde.
&lt;/p&gt;
&lt;p&gt;
Auf Basis eines im AOT definierten Queries
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Ein
neues Query Objekt, verwendet wird die Query (Im AOT) "InventTable"&lt;/span&gt;
&lt;br&gt;
Query queryInventTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Query(querystr(InventTable));&lt;br&gt;
&lt;br&gt;
QueryRun queryRun;&lt;br&gt;
QueryBuildDataSource queryDS;&lt;br&gt;
QueryBuildRange queryRange;&lt;br&gt;
InventTable inventTable;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource zuordnen&lt;/span&gt;
&lt;br&gt;
queryDS &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryInventTable.dataSourceTable(tablenum(InventTable));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Prüfen ob Range schon vorhanden&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (queryDS.findRange(fieldnum(InventTable,
ItemGroupID)))&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.findRange(fieldnum(InventTable,
ItemGroupID));&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.addRange(fieldnum(InventTable,
ItemGroupID));&lt;br&gt;
&lt;br&gt;
queryRange.value(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Teile"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
queryRun mit dem aktuell neu erstellen query auf Basis des Queries "InventTable" erzeugen&lt;/span&gt;
&lt;br&gt;
queryRun &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; QueryRun(queryInventTable);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
alle Datensätze ausgeben&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;while&lt;/span&gt; (queryRun.next())&lt;br&gt;
{&lt;br&gt;
inventTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryRun.get(tablenum(InventTable));&lt;br&gt;
print InventTable.ItemID;&lt;br&gt;
}&lt;br&gt;
pause;&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Komplett in X++ definierte Query
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Ein
neues leeres Query Objekt&lt;/span&gt;
&lt;br&gt;
Query query &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Query();&lt;br&gt;
QueryRun queryRun;&lt;br&gt;
QueryBuildDataSource queryDS;&lt;br&gt;
QueryBuildRange queryRange;&lt;br&gt;
&lt;br&gt;
InventTable inventTable;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource (Tabelle InventTable) hinzufügen&lt;/span&gt;
&lt;br&gt;
queryDS &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; query.addDataSource(tablenum(InventTable));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Range definineren&lt;/span&gt;
&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.addRange(fieldnum(InventTable,
ItemGroupID));&lt;br&gt;
queryRange.value(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Teile"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
alternative&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Range definineren&lt;/span&gt;
&lt;br&gt;
query.dataSourceTable(tablenum(InventTable)).addRange(fieldnum(InventTable, ItemGroupID)).value(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Teile"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
queryRun mit dem aktuell neu erstellen query erzeugen&lt;/span&gt;
&lt;br&gt;
queryRun &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; QueryRun(query);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
alle Datensätze ausgeben&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;while&lt;/span&gt; (queryRun.next())&lt;br&gt;
{&lt;br&gt;
inventTable &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryRun.get(tablenum(InventTable));&lt;br&gt;
print InventTable.ItemID;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Bei diesem einfachen Query macht es keinen Unterschied ob im AOT definiertes Query
verwendet wird, oder ob man die definition komplett in X++ vornimmt.&lt;br&gt;
Benutzt man ein Query das schon irgendwo definiert wurde und möchte dieses verwenden,
sollte man immer auf schon vorhandene Objekte (siehe findRange)&lt;br&gt;
zurückgegriffen werden sofern schon vorhanden.Ansonsten fügt man immer wieder dasselbe
Objekt hinzu, bei Ranges hat das dann zufolge, das in der Abfrage nicht mehr auf die
aktuell&lt;br&gt;
definierte Range zurückgegriffen wird, sondern auf alle davor definieren Ranges ebenfalls.&lt;br&gt;
Das kann sehr gut in dem unterem Beispiel getestet werden, indem man einfach eine
neue Range auf demselben Feld wie schon zuvor definiert hinzufügt und eine anderen&lt;br&gt;
Wert festlegt.
&lt;/p&gt;
&lt;p&gt;
Das Ergebnis ist die Ausgabe alle Artikel bei denen die Artikelgruppe "Teile" und
"Lampen" hinterlegt wurde.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Range definineren&lt;/span&gt;
&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.addRange(fieldnum(InventTable,
ItemGroupID));&lt;br&gt;
queryRange.value(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Teile"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue Range auf demselben Feld. ein andere Wert wird festgelegt &lt;/span&gt;
&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDS.addRange(fieldnum(InventTable,
ItemGroupID));&lt;br&gt;
queryRange.value(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Lampen"&lt;/span&gt;);&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Der Zugriff auf einzelne Elemente (wie DataSource oder Range) der Query ist jeweils
immer gleich. Bei der DataSource sollte immer beachtet werden, dass es ggf. mehrere
Objekte vom selben Typ (Tabelle) geben könnte. Ein gutes Beispiel hierfür sind wieder
die Artikel (InventTable) mit den drei verknüpften Lagermodulparameter (InventTableModule).
Wir hierbei der Zugriff auf die DataSource über tablenum gesteuert erhält man immer
ein und dieselbe DataSource und nicht wie evtl gewünscht alle drei DataSources.&lt;br&gt;
Der Zugriff sollte dann über den DataSource-Namen erfolgen, der immer eindeutig ist,
sogar dann wenn das hinzufügen per x++ geschieht.
&lt;/p&gt;
&lt;p&gt;
Hinzufügen von drei neuen DataSources und der Zugriff auf jeder DataSource der aktuellen
Abfragen, inkl. Ausgabe des Namen&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Query
query &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Query();&lt;br&gt;
counter dsCount;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource (Tabelle InventTable) hinzufügen&lt;/span&gt;
&lt;br&gt;
queryDSInvent= query.addDataSource(tablenum(InventTable));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//neue
relation auf Lagermodulparameter (3mal)&lt;/span&gt;
&lt;br&gt;
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
queryDSInvent.addDataSource(tablenum(InventTableModule)).relations(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt; Ausgabe
aller DataSources die im aktuellen Query vorhanden sind&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;for&lt;/span&gt; (dsCount &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1;
dsCount &amp;lt;= query.dataSourceCount(); dsCount++)&lt;br&gt;
{&lt;br&gt;
print query.dataSourceNo(dsCount).name();&lt;br&gt;
}&lt;br&gt;
pause;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Wird der DataSource kein Name zugewiesen erzeugt Dynamics AX automatisch einen eindeutigen
Namen (Tabellenname_Zähler).
&lt;/p&gt;
&lt;p&gt;
Hinterlegt man nun noch bei den LagerModulparametern eine Range (Verkauf, Einkauf,
Lager) auf den Lagertyp hat man im groben die Standardquery (es fehlt noch die Lagerortverwaltung
Tabelle) der Artikelmaske nachgebaut.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Lager&lt;/span&gt;
&lt;br&gt;
queryDS &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDSInvent.addDataSource(tablenum(InventTableModule));&lt;br&gt;
queryDS.relations(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
queryDS.joinMode(JoinMode::InnerJoin);&lt;br&gt;
queryRange &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; queryDs.addRange(fieldnum(InventTableModule,ModuleType));&lt;br&gt;
queryRange.value(queryValue(ModuleInventPurchSales::Invent));&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Prinzipiell kann man mit dieser Query auch die Query auf der Maske InventTable überladen.
Diee Anzeige der Artikel klappt weiterhin wunderbar&lt;br&gt;
nur die Referenzen auf die zusätzlichen FormDataSources geht hierbei verloren. Dadurch
funktioniert die Anzeige und Bearbeitung der Daten aus diesen FormDataSources dann
nicht mehr.
&lt;/p&gt;
&lt;p&gt;
Spasseshalber aber noch der Quellcode, der auch die Query der Form überlädt.
&lt;/p&gt;
&lt;a href="http://starside.eu/content/binary/Job_QueryEinfachFormRun.xpo"&gt;Job_QueryEinfachFormRun.xpo
(3,05 KB)&lt;/a&gt;&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=a104656d-5ae3-4931-83ef-4bf6793e69ba" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=8a1e4768-7b59-4e8d-9574-10c6622821b0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,8a1e4768-7b59-4e8d-9574-10c6622821b0.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=35a003b9-c75e-4dd8-a32e-65c5949815f5</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,35a003b9-c75e-4dd8-a32e-65c5949815f5.aspx</pingback:target>
      <dc:creator>Mathias Füßler</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,35a003b9-c75e-4dd8-a32e-65c5949815f5.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=35a003b9-c75e-4dd8-a32e-65c5949815f5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Viele
Wege führen nach Rom, so auch in Microsoft Dynamics AX beim Anpassen der Masken (Forms).</span>
          </font>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <br />
            </span>
          </font>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Eine
Form direkt anzupassen kann auf den ersten Blick immer ein einfachere Weg sein, nur
sollte man bedenken das es hier bei einem Update mit die meißten Schwierigkeiten bzw.
die meißte Arbeit geben kann. Dabei kann man fast jede Anpassung an der Maske auch
über X++ steuern.</span>
          </font>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Hier
ein paar einfache Beispiele dafür:<br /><p></p></span>
          </font>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <p>
              </p>
            </span>
          </font>
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <em>Manipulation
der Datasource. </em>
            </span>
          </font>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <p>
                <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FormRun        fr;<br />
Args           args <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Args();<br />
FormDataSource fds;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Form Name InventTable</span><br />
args.name(formstr(InventTable));<br />
fr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FormRun(args);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
init der Form </span><br />
fr.init();<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource der Form</span><br />
fds <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.dataSource(1);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue Range auf der Datasource erzeugen</span><br />
fds.query().dataSourceTable(tablenuM(InventTable)).addRange(fieldnum(InventTable,
itemID)).value(“Wert”);<br />
fr.run();<br />
fr.wait();</span>
              </p>
            </span>
          </font>
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
            </span>
          </font>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">In dem
o.g. Beispiel wird eine neue Range auf der Datasource „InventTable“ erzeugt, ohne
einen direkten Eingriff auf der Form zu machen. 
<p></p></span>
          </font>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <p>
              </p>
            </span>
          </font>
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <em>Weitere
Möglichkeiten der Datasource Manipulation </em>
            </span>
          </font>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
            </span>
          </font>
        </p>
        <font face="Arial" size="2">
          <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
            <p>
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource darf nicht editierbar sein </span>
                <br />
fds <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.dataSource(1); 
<br />
fds.allowEdit(False); 
<br /></span>
            </p>
            <p>
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Prinzipiell
kann über X++ alles manipuliert werden, was auch direkt in der Form manipuliert werden
kann.<br /></span>
            </p>
            <p class="MsoNormal">
Der Zugriff auf einzelne Felder der Datasource erfolgt über die Methode object(),
es muss nur noch die Kennung des Objektes übergeben (Feldnummer) um Zugriff zu erhalten. 
</p>
            <p>
            </p>
          </span>
        </font>
        <p>
        </p>
        <p class="MsoNormal">
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
            </span>
          </font>
        </p>
        <p>
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Artikelnummer ausblenden </span>
                <br />
fds <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.dataSource(1); 
<br />
fds.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span>(fieldnum(InventTable,
ItemID)).visible(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>); 
<br /></span>
            </span>
          </font>
        </p>
        <p>
          <br />
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              </span>
            </span>
          </font>
        </p>
        <font size="2">
          <font face="Arial">Man erhält den vollen Zugriff auf die Eigenschaften
und kann nach belieben die Objekte verändern. Das einzige was zusätzlich noch gemacht
werden muss, ist den Aufruf der Maske zu verändern. So kann ein neues MenuItem erstellt
werden, welches das Ursprüngliche MenuItem ersetzt oder es wird einfach das MenuItem
verändert. So wird anstelle der Maske eine Klasse aufgerufen, die die Manipulation
an der Maske vornimmt. Performanceeinbußen habe ich noch nicht oder nur im geringen
Maße feststellen können.<br /><br /></font>
        </font>
        <p>
        </p>
        <p>
          <font face="Arial" size="2">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Die
einzigen wirklichen Probleme die ich bei solchen Formanpassungen hatte, war das Einfügen
einer neuen Formdatasource. Man kann die FormDatasource zur Laufzeit in die Form einfügen,
leider muss die Form aber geschlossen und wieder neu aufgerufen werden um Zugriff
auf die Formdatasource zu erhalten und um diese dann im Design der Form nutzen zu
können. Bei manchen Forms kam es beim Neuaufruf der Form zu sehr seltsamen Verhalten,
wie zum Beispiel,  das Formcontrols die automatisch Deklariert wurden (Autodeclaration
= Yes) ihre Wertigkeit verlieren. So wurde bespielsweise aus einer FormStringControl
eine FormDataSource. Hier ist also bei der Anwendung Vorsicht geboten.</span>
          </font>
        </p>
        <p>
Anbei noch ein Job der die Kreditorenmaske manipuliert. Es wird hier eine neue Datasource
(Bestellungen) angefügt und in einem neuen Grid angezeigt. Seltsamerweiße klappt dieses
Vorgehen mit der Kreditormaske sehr gut, bei den Debitoren bekam ich nur o.g. Fehlermeldungen
bei Aufruf.<br />
 
</p>
        <p>
          <i>Der ursprünglich Link scheint nicht zu funktionieren. Hier nochmal ein neuer Versuch</i>
          <br />
        </p>
        <a href="http://starside.eu/content/binary/Job_MaskeKreditorBestellung.xpo">Job_MaskeKreditorBestellung.xpo
(2,52 KB)</a>
        <br />
        <br />
Und wenn das auch nicht funktionieren sollte, nochmal als Text...<br /><br /><p><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Changed on 15 Mär 2007 at 21:14:18 by jinx (starside.eu)</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Manipulation des Aufrufes der Maske Kreditoren</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> MaskeKreditorBestellung(Args
_args)<br />
{<br />
FormRun fr;<br />
Args args <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Args();<br />
FormRun neuformRun;<br />
FormBuildDataSource formBuildDataSource;<br />
FormGridControl fgc;<br />
FormGroupControl fGroupCtrl;<br />
;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Form Name VendTable -&gt; Kreditoren</span><br />
args.name(formstr(VendTable));<br />
fr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FormRun(args);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue DataSource einfügen</span><br />
formBuildDataSource <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.form().addDataSource(<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"PurchTable"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Tabelle der Datasource zuordnen</span><br />
formBuildDataSource.table(tablenum(PurchTable));<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Datasource mit der Tabelle "VendTable" verknüpfen</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Wichtig: Unbedingt den Namen der Datasource übergeben!</span><br />
formBuildDataSource.joinSource(fr.form().dataSource(1).name());<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Art der Verknüpfung festlegen</span><br />
formBuildDataSource.linkType(1);<br /><br />
formBuildDataSource.allowCreate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
formBuildDataSource.allowDelete(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
formBuildDataSource.allowEdit(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue Gruppe Erzeugen</span><br />
fGroupCtrl <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fr.form().design().addControl(FormControlType::Group,<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"PurchOderGroup"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Die Neue Datasource der neuen Gruppe zuordnen</span><br />
fGroupCtrl.dataSource(formBuildDataSource.id());<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neues Grid erzeugen</span><br />
fgc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fGroupCtrl.addControl(FormControlType::Grid,<span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)">"PurchOderGrid"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Die Neue Datasource dem neuen Grid zuordnen</span><br />
fgc.dataSource(formBuildDataSource.id());<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Feld "Bestellnummer" ins Grid einfügen</span><br />
fgc.addDataField(formBuildDataSource.id(), fieldnum(PurchTable, PurchID));<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Feld "Kreditorennummer" ins Grid einfügen</span><br />
fgc.addDataField(formBuildDataSource.id(), fieldnum(PurchTable, OrderAccount));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Die Form in der wir gerade die Datasource eingefügt haben, den Args übergeben</span><br />
args.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span>(fr.form());<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Neue FormRun aufgrund der Manipulierten Form erzeugen und aufrufen</span><br />
neuformRun <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> classFactory.formRunClass(args);<br />
neuformRun.init();<br />
neuformRun.run();<br />
neuformRun.wait();<br />
}</span></p><br /><img height="0" src="http://starside.eu/cptrk.ashx?id=125c04d5-7ec0-4127-8766-e38991039fe2" width="0" /><img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35a003b9-c75e-4dd8-a32e-65c5949815f5" /><br /><hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Manipulation an der Form ausserhalb der Form</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,35a003b9-c75e-4dd8-a32e-65c5949815f5.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,35a003b9-c75e-4dd8-a32e-65c5949815f5.aspx</link>
      <pubDate>Fri, 16 Mar 2007 18:19:27 GMT</pubDate>
      <description>&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Viele Wege
führen nach Rom, so auch in Microsoft Dynamics AX beim Anpassen der Masken (Forms).&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;
&lt;br&gt;
&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Eine Form
direkt anzupassen kann auf den ersten Blick immer ein einfachere Weg sein, nur sollte
man bedenken das es hier bei einem Update mit die meißten Schwierigkeiten bzw. die
meißte Arbeit geben kann. Dabei kann man fast jede Anpassung an der Maske auch über
X++ steuern.&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Hier ein
paar einfache Beispiele dafür:&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;em&gt;Manipulation
der Datasource. &lt;/em&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FormRun&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fr;&lt;br&gt;
Args&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Args();&lt;br&gt;
FormDataSource fds;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Form Name InventTable&lt;/span&gt;
&lt;br&gt;
args.name(formstr(InventTable));&lt;br&gt;
fr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FormRun(args);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
init der Form &lt;/span&gt;
&lt;br&gt;
fr.init();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource der Form&lt;/span&gt;
&lt;br&gt;
fds &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.dataSource(1);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue Range auf der Datasource erzeugen&lt;/span&gt;
&lt;br&gt;
fds.query().dataSourceTable(tablenuM(InventTable)).addRange(fieldnum(InventTable,
itemID)).value(“Wert”);&lt;br&gt;
fr.run();&lt;br&gt;
fr.wait();&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;In dem o.g.
Beispiel wird eine neue Range auf der Datasource „InventTable“ erzeugt, ohne einen
direkten Eingriff auf der Form zu machen. 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;em&gt;Weitere
Möglichkeiten der Datasource Manipulation &lt;/em&gt;&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource darf nicht editierbar sein &lt;/span&gt;
&lt;br&gt;
fds &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.dataSource(1); 
&lt;br&gt;
fds.allowEdit(False); 
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Prinzipiell
kann über X++ alles manipuliert werden, was auch direkt in der Form manipuliert werden
kann.&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Der Zugriff auf einzelne Felder der Datasource erfolgt über die Methode object(),
es muss nur noch die Kennung des Objektes übergeben (Feldnummer) um Zugriff zu erhalten. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Artikelnummer ausblenden &lt;/span&gt;
&lt;br&gt;
fds &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.dataSource(1); 
&lt;br&gt;
fds.&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt;(fieldnum(InventTable,
ItemID)).visible(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;); 
&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;font size=2&gt;&lt;font face=Arial&gt;Man erhält den vollen Zugriff auf die Eigenschaften
und kann nach belieben die Objekte verändern. Das einzige was zusätzlich noch gemacht
werden muss, ist den Aufruf der Maske zu verändern. So kann ein neues MenuItem erstellt
werden, welches das Ursprüngliche MenuItem ersetzt oder es wird einfach das MenuItem
verändert. So wird anstelle der Maske eine Klasse aufgerufen, die die Manipulation
an der Maske vornimmt. Performanceeinbußen habe ich noch nicht oder nur im geringen
Maße feststellen können.&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Arial size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Die einzigen
wirklichen Probleme die ich bei solchen Formanpassungen hatte, war das Einfügen einer
neuen Formdatasource. Man kann die FormDatasource zur Laufzeit in die Form einfügen,
leider muss die Form aber geschlossen und wieder neu aufgerufen werden um Zugriff
auf die Formdatasource zu erhalten und um diese dann im Design der Form nutzen zu
können. Bei manchen Forms kam es beim Neuaufruf der Form zu sehr seltsamen Verhalten,
wie zum Beispiel,&amp;nbsp; das Formcontrols die automatisch Deklariert wurden (Autodeclaration
= Yes) ihre Wertigkeit verlieren. So wurde bespielsweise aus einer FormStringControl
eine FormDataSource. Hier ist also bei der Anwendung Vorsicht geboten.&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Anbei noch ein Job der die Kreditorenmaske manipuliert. Es wird hier eine neue Datasource
(Bestellungen) angefügt und in einem neuen Grid angezeigt. Seltsamerweiße klappt dieses
Vorgehen mit der Kreditormaske sehr gut, bei den Debitoren bekam ich nur o.g. Fehlermeldungen
bei Aufruf.&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;Der ursprünglich Link scheint nicht zu funktionieren. Hier nochmal ein neuer Versuch&lt;/i&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://starside.eu/content/binary/Job_MaskeKreditorBestellung.xpo"&gt;Job_MaskeKreditorBestellung.xpo
(2,52 KB)&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
Und wenn das auch nicht funktionieren sollte, nochmal als Text...&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Changed on 15 Mär 2007 at 21:14:18 by jinx (starside.eu)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Manipulation des Aufrufes der Maske Kreditoren&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; MaskeKreditorBestellung(Args
_args)&lt;br&gt;
{&lt;br&gt;
FormRun fr;&lt;br&gt;
Args args &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Args();&lt;br&gt;
FormRun neuformRun;&lt;br&gt;
FormBuildDataSource formBuildDataSource;&lt;br&gt;
FormGridControl fgc;&lt;br&gt;
FormGroupControl fGroupCtrl;&lt;br&gt;
;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Form Name VendTable -&amp;gt; Kreditoren&lt;/span&gt;
&lt;br&gt;
args.name(formstr(VendTable));&lt;br&gt;
fr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FormRun(args);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue DataSource einfügen&lt;/span&gt;
&lt;br&gt;
formBuildDataSource &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.form().addDataSource(&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"PurchTable"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Tabelle der Datasource zuordnen&lt;/span&gt;
&lt;br&gt;
formBuildDataSource.table(tablenum(PurchTable));&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Datasource mit der Tabelle "VendTable" verknüpfen&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Wichtig: Unbedingt den Namen der Datasource übergeben!&lt;/span&gt;
&lt;br&gt;
formBuildDataSource.joinSource(fr.form().dataSource(1).name());&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Art der Verknüpfung festlegen&lt;/span&gt;
&lt;br&gt;
formBuildDataSource.linkType(1);&lt;br&gt;
&lt;br&gt;
formBuildDataSource.allowCreate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
formBuildDataSource.allowDelete(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
formBuildDataSource.allowEdit(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue Gruppe Erzeugen&lt;/span&gt;
&lt;br&gt;
fGroupCtrl &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fr.form().design().addControl(FormControlType::Group,&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"PurchOderGroup"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Die Neue Datasource der neuen Gruppe zuordnen&lt;/span&gt;
&lt;br&gt;
fGroupCtrl.dataSource(formBuildDataSource.id());&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neues Grid erzeugen&lt;/span&gt;
&lt;br&gt;
fgc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fGroupCtrl.addControl(FormControlType::Grid,&lt;span style="FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;"PurchOderGrid"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Die Neue Datasource dem neuen Grid zuordnen&lt;/span&gt;
&lt;br&gt;
fgc.dataSource(formBuildDataSource.id());&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Feld "Bestellnummer" ins Grid einfügen&lt;/span&gt;
&lt;br&gt;
fgc.addDataField(formBuildDataSource.id(), fieldnum(PurchTable, PurchID));&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Feld "Kreditorennummer" ins Grid einfügen&lt;/span&gt;
&lt;br&gt;
fgc.addDataField(formBuildDataSource.id(), fieldnum(PurchTable, OrderAccount));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Die Form in der wir gerade die Datasource eingefügt haben, den Args übergeben&lt;/span&gt;
&lt;br&gt;
args.&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt;(fr.form());&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Neue FormRun aufgrund der Manipulierten Form erzeugen und aufrufen&lt;/span&gt;
&lt;br&gt;
neuformRun &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; classFactory.formRunClass(args);&lt;br&gt;
neuformRun.init();&lt;br&gt;
neuformRun.run();&lt;br&gt;
neuformRun.wait();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;img height=0 src="http://starside.eu/cptrk.ashx?id=125c04d5-7ec0-4127-8766-e38991039fe2" width=0&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=35a003b9-c75e-4dd8-a32e-65c5949815f5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,35a003b9-c75e-4dd8-a32e-65c5949815f5.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Oft wird ein Export von Dynamics AX Daten in ein Exceldokument benötigt. Z.B. für
einfache Auswertungen oder für Datenimporte in andere Systeme. 
</p>
        <p>
Hier ein kurzes Beispiel, wie man aus Dynamics AX ein neues Exceldokument per Code
erstellen kann.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> CreateExcelDokument(Args
_args)<br />
{<br />
   SysExcelApplication xlsApplication;<br />
   SysExcelWorkBooks xlsWorkBookCollection;<br />
   SysExcelWorkBook xlsWorkBook;<br />
   SysExcelWorkSheets xlsWorkSheetCollection;<br />
   SysExcelWorkSheet xlsWorkSheet;<br />
   SysExcelRange xlsRange;<br />
   CustTable custTable;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   int</span> row <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1;<br />
   str fileName;<br />
   ;<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Name des Exceldokuments.</span><br />
   fileName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"C:\\test.xsl"</span>;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Excel initalisieren und öffnen.</span><br />
   xlsApplication <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> SysExcelApplication::construct();<br />
   xlsApplication.visible(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Neues Excel Worksheet erzeugen.</span><br />
   xlsWorkBookCollection <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> xlsApplication.workbooks();<br />
   xlsWorkBook <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> xlsWorkBookCollection.add();<br />
   xlsWorkSheetCollection <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> xlsWorkBook.worksheets();<br />
   xlsWorkSheet <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> xlsWorkSheetCollection.itemFromNum(1);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Zellenüberschriften in das Worksheet schreiben.</span><br />
   xlsWorkSheet.cells().item(row,1).value('Account Num');<br />
   xlsWorkSheet.cells().item(row,2).value('Name');<br /><br />
   row++;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Excel Worksheet mit Daten füllen (Excel-Zellen füllen).</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   while</span> select
custTable<br />
   {<br />
      xlsWorkSheet.cells().item(row,1).value(custTable.AccountNum);<br />
      xlsWorkSheet.cells().item(row,2).value(custTable.Name);<br />
      row++;<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Prüfen ob das Dokument schon existiert.</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   if</span>(WinApi::fileExists(fileName))<br />
   {<br />
      WinApi::deleteFile(fileName);<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Excel Dokument speichern.</span><br />
   xlsWorkbook.saveAs(fileName);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Excel schließen.</span><br />
   xlsApplication.quit();<br />
   xlsApplication.finalize();<br />
}</span>
        </p>
        <p>
          <br />
 
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Exceldokument aus Dynamics AX erstellen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8.aspx</link>
      <pubDate>Thu, 14 Sep 2006 08:54:10 GMT</pubDate>
      <description>&lt;p&gt;
Oft wird ein Export von Dynamics AX Daten in ein Exceldokument benötigt. Z.B. für
einfache Auswertungen oder für Datenimporte in andere Systeme. 
&lt;/p&gt;
&lt;p&gt;
Hier ein kurzes Beispiel, wie man aus Dynamics AX ein neues Exceldokument per Code
erstellen kann.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; CreateExcelDokument(Args
_args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelApplication xlsApplication;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelWorkBooks xlsWorkBookCollection;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelWorkBook xlsWorkBook;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelWorkSheets xlsWorkSheetCollection;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelWorkSheet xlsWorkSheet;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;SysExcelRange xlsRange;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;CustTable custTable;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/span&gt; row &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;str fileName;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Name des Exceldokuments.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;fileName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"C:\\test.xsl"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Excel initalisieren und öffnen.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsApplication &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; SysExcelApplication::construct();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsApplication.visible(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Neues Excel Worksheet erzeugen.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkBookCollection &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; xlsApplication.workbooks();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkBook &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; xlsWorkBookCollection.add();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheetCollection &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; xlsWorkBook.worksheets();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheet &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; xlsWorkSheetCollection.itemFromNum(1);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Zellenüberschriften in das Worksheet schreiben.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheet.cells().item(row,1).value('Account Num');&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheet.cells().item(row,2).value('Name');&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;row++;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Excel Worksheet mit Daten füllen (Excel-Zellen füllen).&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/span&gt; select
custTable&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheet.cells().item(row,1).value(custTable.AccountNum);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkSheet.cells().item(row,2).value(custTable.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;row++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Prüfen ob das Dokument schon existiert.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt;(WinApi::fileExists(fileName))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WinApi::deleteFile(fileName);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Excel Dokument speichern.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsWorkbook.saveAs(fileName);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Excel schließen.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsApplication.quit();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;xlsApplication.finalize();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,3cbc771e-9e85-48bb-ab6f-dbfcf0d463b8.aspx</comments>
      <category>Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=7c80598c-33d3-4eea-8f9d-bbc2a37b92ef</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,7c80598c-33d3-4eea-8f9d-bbc2a37b92ef.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,7c80598c-33d3-4eea-8f9d-bbc2a37b92ef.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7c80598c-33d3-4eea-8f9d-bbc2a37b92ef</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Wer auf der Suche nach Dokumentation zu / über Dynamics Ax 4.0 ist, sollte mal einen
Blick auf diese Seite werfen:<br /><font size="2"><a href="http://www.microsoft.com/dynamics/ax/using/default.mspx">Using
Microsoft Dynamics AX<a></a></a></font></p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=7c80598c-33d3-4eea-8f9d-bbc2a37b92ef" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dokumentation zu Dynamics AX 4.0</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,7c80598c-33d3-4eea-8f9d-bbc2a37b92ef.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,7c80598c-33d3-4eea-8f9d-bbc2a37b92ef.aspx</link>
      <pubDate>Fri, 28 Jul 2006 17:57:07 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Wer auf der Suche nach Dokumentation zu / über Dynamics Ax 4.0 ist, sollte mal einen
Blick auf diese Seite werfen:&lt;br&gt;
&lt;font size=2&gt;&lt;a href="http://www.microsoft.com/dynamics/ax/using/default.mspx"&gt;Using
Microsoft Dynamics AX&lt;a&gt;
&lt;/font&gt;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=7c80598c-33d3-4eea-8f9d-bbc2a37b92ef" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,7c80598c-33d3-4eea-8f9d-bbc2a37b92ef.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/Administration;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=faa36633-c94a-47b1-a5ad-79535e49c13d</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,faa36633-c94a-47b1-a5ad-79535e49c13d.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,faa36633-c94a-47b1-a5ad-79535e49c13d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=faa36633-c94a-47b1-a5ad-79535e49c13d</wfw:commentRss>
      <title>FormStringControl - Property SearchMode</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,faa36633-c94a-47b1-a5ad-79535e49c13d.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,faa36633-c94a-47b1-a5ad-79535e49c13d.aspx</link>
      <pubDate>Thu, 27 Jul 2006 08:55:53 GMT</pubDate>
      <description>&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Mit dieser Property lässt sich bestimmen,
ob ein Feld ein Eingabe- oder Suchfeld sein soll.&lt;br&gt;
Dies ist gerade bei der Verwendung von Gridcontrols hilfreich, da keine zusätzlichen
Filter- oder Suchfunktionen eingebaut werden müssen.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Die Property kann folgende Werte
annehmen:&lt;/font&gt;
&lt;/p&gt;
&lt;ul type=disc&gt;
&lt;li class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt"&gt;
&lt;font size=3&gt;&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;&lt;i&gt;&lt;strong&gt;None&lt;/strong&gt;&lt;/i&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt; 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;
&lt;font size=3&gt;&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;Eingaben in diesem Feld
ist möglich. Das Feld ist somit ein Eingabe und kein Suchfeld&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;ul type=disc&gt;
&lt;li class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l1 level1 lfo2; tab-stops: list 36.0pt"&gt;
&lt;font size=3&gt;&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;&lt;strong&gt;&lt;i&gt;Search After
Input&lt;/i&gt; 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Das Feld ist ein Suchfeld. Eingaben
in die Datenbank sind über dieses Feld nicht mehr möglich.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Wird in dem Feld eine Eingabe vorgenommen,
wird nach dem Verlassen des Datensatzes eine Abfrage der Datenbank durchgeführt. Es
werden der Feldeingabe entsprechende Datensätze angezeigt. Es wird auf den eingegebenen
Wert gefiltert.&lt;/font&gt;
&lt;/p&gt;
&lt;ul type=disc&gt;
&lt;li class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l2 level1 lfo3; tab-stops: list 36.0pt"&gt;
&lt;font size=3&gt;&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;&lt;strong&gt;&lt;i&gt;Search On
Typing&lt;/i&gt; 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Das Feld ist ein Suchfeld. Eingaben
in die Datenbank sind über dieses Feld nicht mehr möglich.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;Sobald in diesem Feld eine Eingabe
erfolgt, wird automatisch zu dem der Eingabe entsprechenden Datensatz gesprungen.
Gleiches verhalten wie im AOT.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=faa36633-c94a-47b1-a5ad-79535e49c13d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,faa36633-c94a-47b1-a5ad-79535e49c13d.aspx</comments>
      <category>Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=9ce1715e-188e-4838-9cff-36811354fe7f</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,9ce1715e-188e-4838-9cff-36811354fe7f.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,9ce1715e-188e-4838-9cff-36811354fe7f.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9ce1715e-188e-4838-9cff-36811354fe7f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Dynamics Ax erlaubt das mehrmalige Anmelden unter einer Benutzerkennung.<br />
So kann ein Benutzer eine beliebige Anzahl an Sitzungen mit seiner Benutzerkennung
öffnen.
</p>
        <p>
Möchte man aber die mögliche Anzahl an Sitzungen unter einer Benutzerkennung begrenzen,
ist dafür<br />
eine Anpassung der Info Klasse notwendig.
</p>
        <p>
          <a href="http://spaces.msn.com/fredshen/Blog/">Fred Shen</a> beschreibt in seinem
Blog, wie diese <a href="http://spaces.msn.com/fredshen/blog/cns!B32E9346DBBAE4E3!173.entry">Anpassung</a> auszusehen
hat.
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=9ce1715e-188e-4838-9cff-36811354fe7f" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Sitzungen in Dynamics Ax begrenzen</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,9ce1715e-188e-4838-9cff-36811354fe7f.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,9ce1715e-188e-4838-9cff-36811354fe7f.aspx</link>
      <pubDate>Fri, 26 May 2006 10:38:32 GMT</pubDate>
      <description>&lt;p&gt;
Dynamics Ax erlaubt das mehrmalige Anmelden unter einer Benutzerkennung.&lt;br&gt;
So kann ein&amp;nbsp;Benutzer&amp;nbsp;eine beliebige Anzahl an Sitzungen mit seiner Benutzerkennung
öffnen.
&lt;/p&gt;
&lt;p&gt;
Möchte man aber die mögliche Anzahl an Sitzungen unter einer Benutzerkennung begrenzen,
ist dafür&lt;br&gt;
eine Anpassung der Info Klasse notwendig.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://spaces.msn.com/fredshen/Blog/"&gt;Fred Shen&lt;/a&gt; beschreibt in seinem
Blog, wie diese &lt;a href="http://spaces.msn.com/fredshen/blog/cns!B32E9346DBBAE4E3!173.entry"&gt;Anpassung&lt;/a&gt; auszusehen
hat.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=9ce1715e-188e-4838-9cff-36811354fe7f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,9ce1715e-188e-4838-9cff-36811354fe7f.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/Administration;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=3390d3e7-c530-4489-9773-802da59ef79e</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,3390d3e7-c530-4489-9773-802da59ef79e.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,3390d3e7-c530-4489-9773-802da59ef79e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=3390d3e7-c530-4489-9773-802da59ef79e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Langsam ist der Zeitpunkt gekommen, zu dem sich auch ein Dynamics Ax Entwickler mit
dem Thema .NET beschäftigen sollte.
</p>
        <p>
Ich stimme fast jedem zu der sagt, dass man bei Dynamics Ax 3.0 eigentlich keinerlei
.NET Kenntisse benötigt.<br />
Allerdings wird sich das mit Dynamics Ax 4.0, durch die erweiterte Integration zwischen
Dynamics Ax und .NET, ändern.
</p>
        <p>
Deshalb sollte man nicht auf den Release von Dynamics Ax 4.0 warten, sondern sein
Wissen schon jetzt erweitern.
</p>
        <p>
Einen guten Einstieg in die .NET Welt bietet die MSDN Webcast-Serie von Bernd Marquardt, <a href="http://www.microsoft.com/germany/msdn/webcasts/serien/MSDNWCS-0604-01.mspx">Get
Sharper Now! - C# für Einsteiger und Umsteiger </a>(ich gehe davon aus, dass die Sprache
C# die erste Wahl sein wird, jedenfalls für die meisten Dynamics Ax Entwickler).
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=3390d3e7-c530-4489-9773-802da59ef79e" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Dynamics Ax Entwickler - Get Sharper Now!</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,3390d3e7-c530-4489-9773-802da59ef79e.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,3390d3e7-c530-4489-9773-802da59ef79e.aspx</link>
      <pubDate>Wed, 24 May 2006 19:23:49 GMT</pubDate>
      <description>&lt;p&gt;
Langsam ist der Zeitpunkt gekommen, zu dem sich auch ein Dynamics Ax Entwickler mit
dem Thema .NET beschäftigen sollte.
&lt;/p&gt;
&lt;p&gt;
Ich stimme fast jedem zu der&amp;nbsp;sagt, dass man bei Dynamics Ax 3.0 eigentlich keinerlei
.NET Kenntisse benötigt.&lt;br&gt;
Allerdings wird sich das mit Dynamics Ax 4.0, durch die erweiterte Integration zwischen
Dynamics Ax und .NET, ändern.
&lt;/p&gt;
&lt;p&gt;
Deshalb sollte man nicht auf den Release von Dynamics Ax 4.0 warten, sondern sein
Wissen schon jetzt erweitern.
&lt;/p&gt;
&lt;p&gt;
Einen guten Einstieg in die .NET Welt bietet die MSDN Webcast-Serie von Bernd Marquardt, &lt;a href="http://www.microsoft.com/germany/msdn/webcasts/serien/MSDNWCS-0604-01.mspx"&gt;Get
Sharper Now! - C# für Einsteiger und Umsteiger &lt;/a&gt;(ich gehe davon aus, dass die Sprache
C# die erste Wahl sein wird, jedenfalls&amp;nbsp;für die meisten Dynamics Ax Entwickler).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=3390d3e7-c530-4489-9773-802da59ef79e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,3390d3e7-c530-4489-9773-802da59ef79e.aspx</comments>
      <category>.NET;Dynamics Ax;Dynamics Ax/Programmierung</category>
    </item>
    <item>
      <trackback:ping>http://blog.ak-home.net/Trackback.aspx?guid=86ba9aee-12e2-48f2-967a-ebff5867a952</trackback:ping>
      <pingback:server>http://blog.ak-home.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.ak-home.net/PermaLink,guid,86ba9aee-12e2-48f2-967a-ebff5867a952.aspx</pingback:target>
      <dc:creator>Axel Kühn</dc:creator>
      <wfw:comment>http://blog.ak-home.net/CommentView,guid,86ba9aee-12e2-48f2-967a-ebff5867a952.aspx</wfw:comment>
      <wfw:commentRss>http://blog.ak-home.net/SyndicationService.asmx/GetEntryCommentsRss?guid=86ba9aee-12e2-48f2-967a-ebff5867a952</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Oft muss von Dynamics Ax aus z.B. auf eine Datei zugegriffen werden.<br />
Hierbei muss man beachten, dass die Pfadangabe zu der Datei eine Escape-Sequenz darstellt/enthält.
</p>
        <p>
          <font face="Courier New">
            <strong>Bsp.:<br />
str file = "C:\\test\\test.csv";</strong>
          </font>
        </p>
        <p>
Es existiert aber eine, soweit mir bekannt allerdings undokumentierte, Möglichkeit
den Dateipfad auch ohne Escapezeichen anzugeben (raw string).
</p>
        <p>
          <font face="Courier New">
            <strong>Bsp.:<br /></strong>
          </font>
          <font face="Courier New">
            <strong>str file = @"C:\Test\test.csv";</strong> <br /></font>
        </p>
        <p>
Zusätzlich kann man bei Verwendung von <font face="Courier New">@""</font> auch Zeilenumbrüche
innerhalb des String zu verwenden/schreiben.
</p>
        <p>
          <font face="Courier New">Bsp.:<br />
str text = @"Das ist ein Text<br />
mit mehr<br />
als einer Zeile";</font>     
</p>
        <img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=86ba9aee-12e2-48f2-967a-ebff5867a952" />
        <br />
        <hr />
Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben
gegeben. Die Verwendung erfolgt auf eigene Gefahr. Copyright © Axel Kühn (Aku's AX
Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</body>
      <title>Escapesequenzen in Zeichenketten (verbatim literals)</title>
      <guid isPermaLink="false">http://blog.ak-home.net/PermaLink,guid,86ba9aee-12e2-48f2-967a-ebff5867a952.aspx</guid>
      <link>http://blog.ak-home.net/PermaLink,guid,86ba9aee-12e2-48f2-967a-ebff5867a952.aspx</link>
      <pubDate>Wed, 24 May 2006 09:19:45 GMT</pubDate>
      <description>&lt;p&gt;
Oft muss von Dynamics Ax aus z.B. auf eine Datei zugegriffen werden.&lt;br&gt;
Hierbei muss man beachten, dass die Pfadangabe zu der Datei eine Escape-Sequenz darstellt/enthält.
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;strong&gt;Bsp.:&lt;br&gt;
str&amp;nbsp;file = "C:\\test\\test.csv";&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Es&amp;nbsp;existiert aber&amp;nbsp;eine, soweit mir bekannt allerdings undokumentierte, Möglichkeit
den Dateipfad auch ohne Escapezeichen anzugeben (raw string).
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;strong&gt;Bsp.:&lt;br&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;str file = @"C:\Test\test.csv";&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
&lt;/p&gt;
&gt; 
&lt;p&gt;
Zusätzlich kann man bei Verwendung von &lt;font face="Courier New"&gt;@""&lt;/font&gt; auch Zeilenumbrüche
innerhalb des String zu verwenden/schreiben.
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;Bsp.:&lt;br&gt;
str text = @"Das ist ein Text&lt;br&gt;
mit mehr&lt;br&gt;
als einer&amp;nbsp;Zeile";&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.ak-home.net/aggbug.ashx?id=86ba9aee-12e2-48f2-967a-ebff5867a952" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Es wird keine Haftung oder Gewährleistung auf die Richtigkeit der gemachten Angaben gegeben. Die Verwendung erfolgt auf eigene Gefahr.

Copyright © Axel Kühn (Aku's AX Blog, http://blog.ak-home.net) and Mathias Füßler (jinx's AX Blog, http://starside.eu)</description>
      <comments>http://blog.ak-home.net/CommentView,guid,86ba9aee-12e2-48f2-967a-ebff5867a952.aspx</comments>
      <category>Dynamics Ax;Dynamics Ax/HowTo;Dynamics Ax/Programmierung</category>
    </item>
  </channel>
</rss>