<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="https://www.schweda.net/style_feed.css" ?>
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:atom="http://www.w3.org/2005/Atom"	
	xmlns:dc="http://purl.org/dc/elements/1.1/" > 
<channel>
    <title>schweda.net - Blog</title>
    <link>https://www.schweda.net/</link>
    <description>schweda.net - Blog - Blog-Beitraege - Dynamics AX 2009</description>
    <language>de-at</language>
    <copyright>Copyright 2006-2026</copyright>
    <generator>schweda.net</generator>
    <managingEditor>heinz.schweda@schweda.net (Heinz Schweda)</managingEditor>
    <webMaster>heinz.schweda@schweda.net (Heinz Schweda)</webMaster>
    <category>Blog</category>
	<atom:link href="https://www.schweda.net/blog_rss.php?vtid=ax2009" rel="self" type="application/rss+xml" />
<item>
<title><![CDATA["OpenPrinter"-Fehler beim Anzeigen eines Berichtes am Bildschirm]]></title>
<description><![CDATA[
<p>Wenn beim Anzeigen eines Berichtes am Bildschirm folgender Fehler auftritt, muss man im Windows einen Standarddrucker einrichten.
</p>


<blockquote>

<p>OpenPrinter_1: rc:0 LastError:3012(0xbc4) Es wurden keine Drucker gefunden.
</p>

</blockquote>


<p>&nbsp;
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Wed, 16 Feb 2022 10:58:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=706</link>
<comments>https://www.schweda.net/blog_ax.php?bid=706</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=706</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=706</wfw:commentRss>
</item>
<item>
<title><![CDATA[Sonderzeichen im XML-Header einer Methode verwenden]]></title>
<description><![CDATA[
<p>Manchmal muss man im XML-Header einer Methode Sonderzeichen verwenden, um den Code gut dokumentieren zu k&ouml;nnen. Damit dieser Header trotzdem wohlgeformt ist und nicht als Best-Practice-Abweichung gekennzeichnet wird, kann man einen CDATA-Abschnitt einsetzen.
</p>


<pre class="pre_blog_axcode">
/// &lt;version&gt;
///  1.0
/// &lt;/version&gt;
/// &lt;summary&gt;
/// &lt;![CDATA[ Replaces following special characters: &amp;, % ]]&gt;
/// &lt;/summary&gt;
private void someMethod()
{
    //...do something...
}
</pre>


<p>Ohne diesen CDATA-Abschnitt w&uuml;rde AX folgende BP-Abweichung ausgeben:
</p>


<p>&nbsp;
</p>


<blockquote>

<p>Die XML-Dokumentation ist nicht wohlgeformt.
</p>

</blockquote>


<p>&nbsp;
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 18 Jun 2016 10:04:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=605</link>
<comments>https://www.schweda.net/blog_ax.php?bid=605</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=605</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=605</wfw:commentRss>
</item>
<item>
<title><![CDATA[Namen der Shared Projects nach einem String durchsuchen]]></title>
<description><![CDATA[
<p>Um sich alle (Shared-)Projekte ausgeben zu lassen, die einen bestimmten Text im Namen tragen, kann man den folgenden Code verwenden.
</p>


<pre class="pre_blog_axcode">
static void searchProjectName(Args _args)
{
    ProjectNode projectNode;

    #AOTExport

    projectNode    = infolog.projectRootNode();
    projectNode    = projectNode.AOTfindChild(#expProjectShared);
    projectNode    = projectNode.AOTfirstChild();

    while(projectNode)
    {
        setPrefix(projectNode.name());

        if(strScan(projectNode.name(), &quot;BR_&quot;, 0, 60))
        {
            info(projectNode.name());
        }

        projectNode    = projectNode.AOTnextSibling();
    }
}
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 21 May 2016 19:09:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=598</link>
<comments>https://www.schweda.net/blog_ax.php?bid=598</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=598</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=598</wfw:commentRss>
</item>
<item>
<title><![CDATA[Beim Öffnen einer Form den Filter aufmachen]]></title>
<description><![CDATA[
<p>Um direkt beim &Ouml;ffnen eines Formulares das Filter-Fenster zu &ouml;ffnen, kann man beispielsweise diesen Code verwenden:
</p>


<pre class="pre_blog_axcode">
public void run()
{
    super();
    if(dataSourceName_ds.queryRun().prompt())
    {
        dataSourceName_ds.research();
    }
}
</pre>


<p>&nbsp;
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Thu, 17 Sep 2015 20:00:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=583</link>
<comments>https://www.schweda.net/blog_ax.php?bid=583</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=583</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=583</wfw:commentRss>
</item>
<item>
<title><![CDATA[Statt Parameter-Listen einen DataContract verwenden]]></title>
<description><![CDATA[
<p>Wer schon einmal die Parameter einer Methode erweitern musste, kennt vielleicht das Problem: Wenn man Gl&uuml;ck hat kann man seinen neuen Parameter am Ende einf&uuml;gen und mit einem Default-Wert vorbelegen.<br />
<br />
Hat man nicht ganz so viel Gl&uuml;ck und muss entweder der Parameter zwischen den vorhandenen einbauen oder darf/kann keinen Default-Wert angeben so muss man den gesamten AOT nach den Aufrufen dieser Methode durchsuchen (die Querverweise helfen hier enorm) und diese entsprechend anpassen.<br />
<br />
Aufgrund dieser Problematik gehe ich bei meinen Methoden nun oft den Weg, da&szlig; ich nur einen einzigen Parameter einf&uuml;ge, und zwar vom Typ einer - nennen wir sie einfach einmal DataContract-Klasse.<br />
<br />
DataContracts sind dem einen oder anderen vielleicht aus dem SSRS-Umfeld bekannt, aber die selbe Logik kann ich auch in vielen anderen Situationen anwenden.<br />
<br />
So sieht eine solche DataContract-Klasse beispielweise wie folgt aus:
</p>


<div class="div_blog_axcode">classDeclaration MyDataContract<br />
{<br />
&nbsp;&nbsp;&nbsp; ItemId itemId;<br />
&nbsp; &nbsp; Qty qty;<br />
}
</div>


<p>&nbsp;
</p>


<div class="div_blog_axcode">Public ItemId parmItemId(ItemId _itemId = itemId)<br />
{<br />
&nbsp;&nbsp;&nbsp; itemId = _itemId;<br />
&nbsp;&nbsp;&nbsp; return itemId;<br />
}
</div>


<p>&nbsp;
</p>


<div class="div_blog_axcode">Public Qty parmQty(Qty _qty = qty)<br />
{<br />
&nbsp;&nbsp;&nbsp; qty = _qty;<br />
&nbsp;&nbsp;&nbsp; return qty;<br />
}
</div>


<p><br />
Eine Methode k&ouml;nnte dann wie folgt aussehen:
</p>


<div class="div_blog_axcode">Public void myMethod(MyDataContract _dataContract)<br />
{<br />
&nbsp;&nbsp;&nbsp; // &hellip; do something&hellip;<br />
&nbsp;&nbsp;&nbsp; info(_dataContract.parmItemId());<br />
}
</div>


<p><br />
Aufrufen muss ich eine solche Methode so:
</p>


<div class="div_blog_axcode">MyDataContract dataContract;<br />
dataContract = new MyDataContract();<br />
dataContract.parmItemId(&quot;A1000&quot;);<br />
dataContract.parmQty(123);<br />
<br />
Object.myMethod(dataContract);
</div>


<p><br />
Kommt nun sp&auml;ter ein neuer Parameter hinzu, muss ich den lediglich entsprechend in der DataContract-Klasse einf&uuml;gen und die Logik in der Methode erweitern. Die Methodenaufrufe k&ouml;nnen u.U. so bleiben wie sie waren, lediglich die Aufrufe wo die ge&auml;nderten Parameter ber&uuml;cksichtigt werden m&uuml;ssen, m&uuml;ssen angepasst werden.<br />
<br />
Und zu guter Letzt kann ich solche DataContract-Klassen nat&uuml;rlich f&uuml;r mehrere Methoden verwenden.<br />
&nbsp;
</p>


<p>&nbsp;
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 14 Jul 2015 14:57:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=579</link>
<comments>https://www.schweda.net/blog_ax.php?bid=579</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=579</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=579</wfw:commentRss>
</item>
<item>
<title><![CDATA[CSV-Datei in Dynamics AX importieren/einlesen]]></title>
<description><![CDATA[
<p>MIt Hilfe der <strong>CommaTextIo</strong>-Klasse kann man CSV-Dateien in Dynamics AX einlesen. Der hier gezeigte Job zeigt ein einfaches Beispiel f&uuml;r die Verwendung dieser Klasse.
</p>


<pre class="pre_blog_axcode">
static void importCSVFile(Args _args)
{
    Filename fileName = @&quot;c:	empcsvimport.csv&quot;;
    CommaTextIo commaTextIo = new CommaTextIo(fileName, &quot;r&quot;);
    container lineCon;

    commaTextIo.inFieldDelimiter(&#39;;&#39;);
    commaTextIo.inRecordDelimiter(&#39; &#39;);
    while (commaTextIo.status() == IO_Status::OK)
    {
        lineCon = commaTextIo.read();

        info(strFmt(&quot;%1 %2 %3&quot;, conPeek(lineCon, 1), conPeek(lineCon, 2), conPeek(lineCon, 3)));
    }
}
</pre>


<p>Prinzipiell ginge dies auch genauso mit der <strong>TextIo</strong>-Klasse (oder <strong>AsciiIo</strong>), allerdings muss man dabei beachten, da&szlig; diese Klassen beispielsweise unerwartete Ergebnisse liefern k&ouml;nnen, wenn der <em>inFieldDelimiter </em>- in meinem Beispiel ein Strichpunkt - innerhalb eines Textes vorkommt.
</p>


<p>&nbsp;
</p>


<p>Folgende&nbsp;Beispieldatei w&uuml;rde anders verarbeitet, als vielleicht vom Entwickler erwartet. Die dritte Spalte in der dritten Zeile w&uuml;rde von der <em>read()</em>-Methode als zwei Spalten interpretiert werden.
</p>


<pre class="pre_blog_axcode">
100;450,00;Customername1
101;1200,00;Customername2
102;50,28;&quot;Customername 3; Second customername&quot;
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Thu, 02 Jul 2015 18:21:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=573</link>
<comments>https://www.schweda.net/blog_ax.php?bid=573</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=573</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=573</wfw:commentRss>
</item>
<item>
<title><![CDATA[Projekt beim Starten der Entwicklungsumgebung öffnen]]></title>
<description><![CDATA[
<p>Kurzer Tipp f&uuml;r zwischendurch: Wer l&auml;ngere Zeit an ein und dem selben Projekt arbeitet, kann sich dieses Projekt in den Benutzeroptionen unter <em>Extras &gt; Optionen</em> im Register <em>Entwicklung</em> als <em>Start Projekt</em> hinterlegen.
</p>

<p><a target="_blank" href="http://www.schweda.net/pictures/blogpics/ax2012_options_myproject.jpg"><img height="201" width="465" border="0" alt="Screesnhot" title="Screenshot" src="http://www.schweda.net/pictures/blogpics/tb_ax2012_options_myproject.jpg" /></a>
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 30 May 2015 17:14:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=577</link>
<comments>https://www.schweda.net/blog_ax.php?bid=577</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=577</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=577</wfw:commentRss>
</item>
<item>
<title><![CDATA[Bestellposition per Code erstellen]]></title>
<description><![CDATA[
<p>Ein einfach gehaltenes Beispiel wir man unter Verwendung der AX&lt;Table&gt;-Klasse der Tabelle PurchLine eine Bestellposition per Code erstellen kann.
</p>


<pre class="pre_blog_axcode">
static void createPurchLine(Args _args)
{
    axPurchLine axPurchLine;
    purchLine purchLine;
   
    axPurchLine = AxPurchLine::newPurchLine(purchLine);
    axPurchLine.validateInput(true);
    axPurchLine.continueOnError(false);
   
    axpurchLine.parmPurchId(&quot;P00001&quot;);
    axpurchLine.parmItemId(&quot;1000&quot;);
    axPurchLine.parmPurchQty(10);
    axPurchLine.parmPurchPrice(24.50);
    axPurchLine.save();
}
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Fri, 29 May 2015 17:47:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=574</link>
<comments>https://www.schweda.net/blog_ax.php?bid=574</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=574</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=574</wfw:commentRss>
</item>
<item>
<title><![CDATA[Erstellen einer AX<Table>-Klasse II]]></title>
<description><![CDATA[
<p>Ben&ouml;tigt man f&uuml;r eine Tabelle eine sog. <strong>AX&lt;Table&gt;-Klasse</strong> kann man sich diese mit Hilfe der Klasse <strong>AxGenerateAxBCClass </strong>generieren lassen.
</p>


<p>Dazu einfach diese Klasse im AOT&nbsp;per rechter Maustaste aufrufen und dem Assistenten folgen oder folgenden Job anpassen und ausf&uuml;hren:
</p>


<pre class="pre_blog_axcode">
static void generateAXTableClass(Args _args)
{
    AxGenerateAxBCClass axGenerateAxBCClass;
    
    axGenerateAxBCClass = new AxGenerateAxBCClass();
    axGenerateAxBCClass.parmTableId(tableNum(MyNewTable));
    axGenerateAxBCClass.run();
}
</pre>


<p>Die auf diese Art &amp;&nbsp;Weise generierte Klasse muss unter manchen Umst&auml;nden noch etwas bearbeitet werden, dennoch geht der Vorgang rascher von der Hand, als die Klasse komplett selbst erstellen zu m&uuml;ssen.
</p>


<p>Und wenn sich die Tabelle &auml;ndert, beispielweise wenn neue Felder hinzukommen, kann man die <strong>AxGenerateAxBCClass </strong>einfach nochmals aufrufen und die AX&lt;Table&gt;-Klasse wird entsprechend erweitert.
</p>


<p>Wie man solche AX-Klassen verwendet, habe ich u.a. <a href="http://www.schweda.net/blog_ax.php?bid=494" target="_self" title="Erstellen einer Entität per Code">hier beschrieben</a>.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 23 May 2015 15:54:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=575</link>
<comments>https://www.schweda.net/blog_ax.php?bid=575</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=575</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=575</wfw:commentRss>
</item>
<item>
<title><![CDATA[Label eines Dialogfeldes ermitteln/auslesen]]></title>
<description><![CDATA[
<p>Vor kurzem wollte ich in der <em>validate()</em>-Methode einer von <strong>RunBase </strong>abgeleiteten Klasse ein Fehlermeldung einbauen, die als Teil das Label eines Dialogfeldes verwendet.
</p>


<p>Dabei musste ich feststellen, da&szlig; dies gar nicht so einfach ist, wie ich es mir vorgestellt h&auml;tte.
</p>


<p>Die verf&uuml;gbare Methode <em>dialogField.fieldControl().Label()</em> funktioniert offenbar nur dann, wenn man dem Dialogfeldes explizit ein eigenes Label zugewiesen hat (und dieses nicht dynamisch &uuml;ber den EDT gezogen wird).
</p>


<p>Deshalb im folgenden ein kurzer Job, der zeigt wie man das Label eines Dialogfeldes auslesen kann. Die gleiche Logik l&auml;sst sich nat&uuml;rlich u.a. auch in einer Klasse, die von RunBase/RunBaseBatch abgeleitet wurde, verwenden.
</p>


<pre class="pre_blog_axcode">
static void getDialogFieldLabel(Args _args) 
{ 
    Dialog dialog = new Dialog(); 
    DialogField df_Project; 
    DialogField df_AmountMST; 

    str getLabel(DialogField _df) 
    { 
        formStringControl fsc; 
        
        fsc = _df.fieldControl(); 
        
        return fsc.labelText(); 
    } 
     
    df_project   = dialog.addField(typeId(ProjId), &quot;Mein Projekt&quot;); 
    df_AmountMST = dialog.addField(typeId(AmountMST)); 
    
    dialog.run(); 

    info(getLabel(df_project)); 
    info(getLabel(df_AmountMST)); 
}
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 23 Dec 2014 13:27:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=554</link>
<comments>https://www.schweda.net/blog_ax.php?bid=554</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=554</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=554</wfw:commentRss>
</item>
<item>
<title><![CDATA[Eine bestimmte Dimension als Dialogfeld einbinden]]></title>
<description><![CDATA[
<p>Wenn man in Dynamics AX 2009 (oder fr&uuml;heren Versionen) eine bestimmte Dimension als Dialogfeld verwenden m&ouml;chte, kann man sich einen eigenen Extended Datatype (abgeleitet von <em>Criterias</em>) wie im folgenden beschrieben anlegen. Entscheidend sind dabei die Relations dieses EDTs.<br />
<br />
Im Beispiel soll beispielsweise der Kostentr&auml;ger als Dialogfeld angeboten werden.
</p>


<p><img alt="Screenshot EDT" height="93" src="http://www.schweda.net/pictures/blogpics/ax_dimensioncostcenter.jpg" title="Screenshot EDT" width="321" />
</p>


<p>Der Beispiel-Code ist einer von RunBase abgeleitenden Klasse entnommen.
</p>


<pre class="pre_blog_axcode">
protected Object dialog(DialogRunbase dialog, boolean forceOnClient)
{
    Object ret;

    ret = super(dialog, forceOnClient);

    df_project = ret.addField(TypeId(DimensionCostCenter));

    return ret;
}
</pre>


<p>Der so angepasste Dialog sollte wie folgt aussehen:
</p>


<p><img alt="Screenshot Dialog" height="176" src="http://www.schweda.net/pictures/blogpics/ax_dimensioncostcenter_dialog.jpg" title="Screenshot Dialog" width="333" />
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Fri, 19 Dec 2014 19:11:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=555</link>
<comments>https://www.schweda.net/blog_ax.php?bid=555</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=555</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=555</wfw:commentRss>
</item>
<item>
<title><![CDATA[Ursache von Fehlermeldungen ermitteln]]></title>
<description><![CDATA[
<p>In Dynamics AX k&ouml;nnen unterschiedliche (Fehler-)Meldungen auftreten, die meisten kommen von der Applikation, es gibt aber auch Meldungen, die vom AX-Client ausgegeben werden.
</p>

<p>Leider sind nicht alle Meldungen so sprechend, da&szlig; man (als Entwickler) sofort wei&szlig;, was nun zu tun ist. Deshalb gibt es, je nachdem um welche Art von Fehlermeldung es sich handelt, unterschiedliche Herangehensweisen, wie man die Ursache der Meldung findet.
</p>

<h2>Meldung &uuml;ber das Infolog der Applikation
</h2>

<p><a href="http://www.schweda.net/pictures/blogpics/ax_infolog_example_1.jpg"><img title="Screenshot infolog" border="0" alt="Screenshot Infolog" align="right" width="200" height="150" style="padding-bottom: 10px; padding-left: 10px" src="http://www.schweda.net/pictures/blogpics/tb_ax_infolog_example_1.jpg" /></a>Bei manchen Meldungen gen&uuml;gt ein Doppelklick auf die Meldung im <strong>Infolog </strong>und man landet im Code, welcher die Meldung geworfen hat (vorausgesetzt man befindet sich als Benutzer gerade im Entwicklungsmodus).
</p>
<br /><a class="div_blog_category_gotodetail" href="https://www.schweda.net/blog_ax.php?bid=513" target="_self" title="Weiterlesen...">Weiterlesen...</a>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Mon, 09 Jun 2014 18:30:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=513</link>
<comments>https://www.schweda.net/blog_ax.php?bid=513</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=513</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=513</wfw:commentRss>
</item>
<item>
<title><![CDATA[Beispiel für die Verwendung von RecordInsertList]]></title>
<description><![CDATA[
<p>Ein kurzes Code-Beispiel wie man unter der Verwendung von RecordInsertList Datens&auml;tze in einer Tabelle auf sehr performante Art &amp; Weise erstellen kann. Wer RecordInsertList nicht kennt, kann <a href="http://msdn.microsoft.com/en-us/library/recordinsertlist.aspx" target="_blank" title="MSDN">hier</a> mehr dar&uuml;ber erfahren.
</p>


<pre class="pre_blog_axcode">
static void HowToUseRecordInsertList(Args _args)
{
    DMOPerfTest DMOPerfTest;
    RecordInsertList RecordInsertList;
    Counter c;
    FromTime fromTime = timeNow();
    
    RecordInsertList = new RecordInsertList(tableNum(DMOPerfTest));
    
    for (c=1;c&lt;=10000;c++)
    {
        DMOPerfTest.clear();    
        DMOPerfTest.AccountNum = int2str(c);
        
        if(DMOPerfTest.validateWrite())
        {
            RecordInsertList.add(DMOPerfTest);
        }
    }
    
    RecordInsertList.insertDatabase();
    
    info(strFmt(&quot;Total time consumed: %1&quot;, timeConsumed(fromTime, timeNow())));
}
</pre>


<p>Die im Beispiel verwendete Tabelle <em>DMOPerfTest </em>wurde f&uuml;r dieses Beispiel erstellt und ist Out-of-the-box nicht Bestandteil von Dynamics AX.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sun, 25 May 2014 17:04:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=509</link>
<comments>https://www.schweda.net/blog_ax.php?bid=509</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=509</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=509</wfw:commentRss>
</item>
<item>
<title><![CDATA[Objekte per Code zu einem Projekt hinzufügen]]></title>
<description><![CDATA[
<p>Nachstehend ein kurzer Job, mit dessen Hilfe man AOT-Elemente zu einem bestehenden Shared Project hinzuf&uuml;gen kann.
</p>

<div class="div_blog_axcode">static void AddNodeToSharedProject(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; projectNode projectNode;<br />
&nbsp;&nbsp;&nbsp; TreeNode treeNode;<br />
&nbsp;&nbsp;&nbsp; #AOT<br />
&nbsp;&nbsp;&nbsp; #AOTExport <br />
<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp; = infolog.projectRootNode();<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp; = projectNode.AOTfindChild(#expProjectShared);<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp; = projectNode.AOTfindChild('MyProject');<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // Add objects<br />
&nbsp;&nbsp;&nbsp; treenode = TreeNode::findNode(#TablesPath+'\\'+tableid2name(tablenum(CustGroup)));<br />
&nbsp;&nbsp;&nbsp; projectNode.addNode(treenode);<br />
<br />
&nbsp;&nbsp;&nbsp; treenode = TreeNode::findNode(#TablesPath+'\\'+tableid2name(tablenum(VendGroup)));<br />
&nbsp;&nbsp;&nbsp; projectNode.addNode(treenode);<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; treenode = TreeNode::findNode(#ClassesPath+'\\'+classStr(PriceDisc));<br />
&nbsp;&nbsp;&nbsp; projectNode.addNode(treenode);<br />
}
</div>

<p>Das ge&auml;nderte Projekt sieht beispielsweise wie folgt aus:
</p>

<p><img title="Screenshot" alt="Screenshot" style="padding-left: 10px" src="http://www.schweda.net/pictures/blogpics/ax_sharedprojectaddnode.jpg" border="0" align="left" height="158" width="245" />
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 29 Mar 2014 19:28:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=504</link>
<comments>https://www.schweda.net/blog_ax.php?bid=504</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=504</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=504</wfw:commentRss>
</item>
<item>
<title><![CDATA[Werte eines Base-Enums durchlaufen]]></title>
<description><![CDATA[
<pre class="pre_blog_axcode">
SysDictEnum SysDictEnum = new SysDictEnum(enumNum(SalesStatus));
int i;

for (i=0;i&lt;SysDictEnum.values();i++)
{
    info(SysDictEnum.index2Label(i));
}
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 11 Mar 2014 21:20:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=478</link>
<comments>https://www.schweda.net/blog_ax.php?bid=478</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=478</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=478</wfw:commentRss>
</item>
<item>
<title><![CDATA[SQL-Fehler beim Öffnen/Synchronisieren einer Tabelle]]></title>
<description><![CDATA[
<p>Tritt beim &Ouml;ffnen oder Synchronisieren einer - meist neu erstellten - Tabelle der folgende Fehler auf
</p>

<blockquote>

<p>Ein Datensatz in Table1 (Table1) kann nicht ausgew&auml;hlt werden.<br />
Die SQL-Datenbank hat einen Fehler gemeldet.
</p>

</blockquote>

<p>so kann die Ursache sein, da&szlig; die Tabelle ein Feld enth&auml;lt, dessen Name ein &quot;Reserved Word&quot; der SQL-Datenbank ist. Beispielsweise darf ein Feld nicht <em>Primary </em>genannt werden.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 11 Mar 2014 21:19:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=503</link>
<comments>https://www.schweda.net/blog_ax.php?bid=503</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=503</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=503</wfw:commentRss>
</item>
<item>
<title><![CDATA[Makro innerhalb eines SELECT-Statements verwenden]]></title>
<description><![CDATA[
<p>Das Beispiel listet beispielsweise nur aktive St&uuml;cklistenpositionen (Tabelle <em>BOM</em>) auf (aktiv &uuml;ber die Felder <em>FromDate </em>und <em>ToDate</em>). L&auml;sst man den zweiten Parameter des Makros leer (dateNull()), so werden alle St&uuml;cklistenpositionen gelistet.
</p>


<pre class="pre_blog_axcode">
static void useMacroInSelectStatement(Args _args)
{
    bom bom;
    date emptyDate;
    
    // parameters: %1 = table instance, %2 date, %3 empty date value
    #localmacro.bomDateFilter
        &amp;&amp; ( %2 == dateNull() || (
            ((%1.FromDate &lt;= %2) &amp;&amp; (%1.ToDate &gt;= %2)) ||
            ((%1.FromDate == %3) &amp;&amp; (%1.ToDate == %3)) ||
            ((%1.FromDate &lt;= %2) &amp;&amp; (%1.ToDate == %3)) ||
            ((%1.FromDate == %3) &amp;&amp; (%1.ToDate &gt;= %2))
            ))
    #endMacro
    ;
    
    while select bom
    where bom.ItemId == &#39;123&#39;
    #bomDateFilter(bom, systemDateGet(), emptyDate)
    {
        info(bom.bomid);
    }
}
</pre>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 25 Jan 2014 12:21:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=498</link>
<comments>https://www.schweda.net/blog_ax.php?bid=498</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=498</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=498</wfw:commentRss>
</item>
<item>
<title><![CDATA[Welche Felder werden in einem automatisch generierten Lookup angezeigt?]]></title>
<description><![CDATA[
<p>Mir wurde diese Frage vor&nbsp;kurzem selbst gestellt&nbsp;und konnte diese allerdings nur zum Teil beantworten.
</p>

<p>Ich wusste aber noch, da&szlig; ich schon einmal eine Seite gesehen hatte, wo dies genau erkl&auml;rt wird. Aber ich wusste weder noch wo, noch konnte ich sie &uuml;ber diverse Suchmaschinen finden.
</p>

<p>Aber in alten Unterlagen fand ich die Quelle dann doch, der Trick um die Quelle auch mit Google und Konsorten zu finden ist, mit dem altem Namen von Microsoft Dynamics AX - <strong>Axapta </strong>danach zu suchen!
</p>

<p>Tut man dies, so findet man rasch folgende Seite:
</p>

<p><a title="Axaptapedia" target="_blank" href="http://www.axaptapedia.com/index.php?title=Lookups">http://www.axaptapedia.com/index.php?title=Lookups</a>
</p>
<br /><a class="div_blog_category_gotodetail" href="https://www.schweda.net/blog_ax.php?bid=500" target="_self" title="Weiterlesen...">Weiterlesen...</a>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Thu, 16 Jan 2014 21:43:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=500</link>
<comments>https://www.schweda.net/blog_ax.php?bid=500</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=500</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=500</wfw:commentRss>
</item>
<item>
<title><![CDATA[Verwenden einer Assembly/DLL in Dynamics AX]]></title>
<description><![CDATA[
<p>Um eine DLL in Dynamics AX verwenden zu k&ouml;nnen, muss diese im References-Knoten des AOT hinzugef&uuml;gt werden.<br />
<br />
Dazu per rechter Maustaste auf den Knoten klicken und&nbsp; Referenz hinzuf&uuml;gen ausw&auml;hlen. Dadurch &ouml;ffnet sich ein Dialog, wo abh&auml;ngig vom &quot;Speicherort&quot; der DLL wie folgt vorgegangen werden muss:
</p>

<ul>
    
<li>Wurde die DLL bereits im Global Assembly Cache (GAC) registriert, sollte sie bereits in der Liste aufscheinen wo sie nun &uuml;ber das Kontrollk&auml;stchen links selektiert und mit Ausw&auml;hlen ausgew&auml;hlt werden kann.<br />
    <br />
    Um eine DLL im GAC zu registrieren ist es notwendig, da&szlig; die DLL signiert wurde. <br />
    Registriert werden kann sie &uuml;ber die Kommandozeile mit folgendem Befehl <br />
    &quot;gacutil /i myClassLibrary.dll&quot;
</li>

</ul>

<ul>
    
<li>Wurde die DLL beispielsweise im BIN-Verzeichnis des Clients abgelegt, muss man zuerst &uuml;ber die Durchsuchen-Schaltfl&auml;che die DLL aus dem BIN-Verzeichnis ausw&auml;hlen. Nun sollte sie in der Liste aufscheinen wo sie &uuml;ber das Kontrollk&auml;stchen links selektiert und mit Ausw&auml;hlen ausgew&auml;hlt werden kann.
</li>

</ul>

<p>In beiden F&auml;llen muss nun der Dialog mit OK best&auml;tigt werden.
</p>
<br /><a class="div_blog_category_gotodetail" href="https://www.schweda.net/blog_ax.php?bid=477" target="_self" title="Weiterlesen...">Weiterlesen...</a>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sun, 29 Dec 2013 20:45:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=477</link>
<comments>https://www.schweda.net/blog_ax.php?bid=477</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=477</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=477</wfw:commentRss>
</item>
<item>
<title><![CDATA[Word-Dokument mit Tabelle per Code erstellen]]></title>
<description><![CDATA[
<p><img alt="Microsoft Word" src="http://www.schweda.net/pictures/blogpics/microsoft_word_logo_2013.jpg" style="float:right; padding-left:10px" title="Microsoft Word" />Anbei ein einfach gehaltener Job, der ein Word-Dokument mit einer Tabelle per Code erstellt. Das Beispiel legt auch den Rahmen und dessen Farbe der Tabelle fest.<br />
Voraussetzung ist ein lokal installiertes Microsoft Word.
</p>


<pre class="pre_blog_axcode">
static void CreateWordFileWithTable(Args _args)
{
    COM wordApplication;
    COM wordTables;
    COM wordTable;
    COM wordSelection;
    COM wordTableRows;
    COM wordRange;
    COM wordTableCell;
    COM wordTableCellRange;
    COM wordDocuments;
    COM wordDocument;
    COM wordTableBorders;
    ;
 
    // Initialize Word object and document
    wordApplication = new COM(&quot;Word.Application&quot;);
    wordDocuments = wordApplication.documents();
    wordDocuments.add();
    wordDocument = wordDocuments.item(1);
 
    wordSelection = wordApplication.selection();
    wordRange = wordSelection.range();
 
    // Get table collection
    wordTables = wordSelection.tables();
 
    // Create table with 3 rows and 5 columns
    wordTable = wordTables.add(wordRange, 3, 5);
 
    // Fill cell: First line, second column
    wordTableCell = wordTable.Cell(1, 2);
    wordTableCellRange = wordTableCell.range();
    wordTableCellRange.text(&quot;Hello&quot;);

    // Fill cell: Second line, third column
    wordTableCell = wordTable.Cell(2, 3);
    wordTableCellRange = wordTableCell.range();
    wordTableCellRange.text(&quot;World&quot;);
 
    // Enable table borders
    wordTableBorders = wordTable.borders();
    wordTableBorders.enable(true);

    // Add colored borders
    wordTableBorders.InsideLineStyle(3);
    wordTableBorders.OutsideLineStyle(5);
    wordTableBorders.OutsideColorIndex(2);
 
    // Get table row collection and add a new row
    wordTableRows = wordTable.rows();
    wordTableRows.add();
 
    // Open word
    wordApplication.visible(true);
    wordApplication.finalize();
}
</pre>




<p>Das per obigem Code erstellte Word-Dokument sieht wie folgt aus:
</p>


<p><a href="http://www.schweda.net/pictures/blogpics/ax_createwordwithtable.jpg" target="_blank"><img alt="Screenshot" height="64" src="http://www.schweda.net/pictures/blogpics/tb_ax_createwordwithtable.jpg" title="Screenshot" width="465" /></a>
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 21 Dec 2013 17:32:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=490</link>
<comments>https://www.schweda.net/blog_ax.php?bid=490</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=490</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=490</wfw:commentRss>
</item>
<item>
<title><![CDATA[Erstellen einer AX<Table>-Klasse]]></title>
<description><![CDATA[
<p>Ben&ouml;tigt man f&uuml;r eine Tabelle eine sog. <strong>AX&lt;Table&gt;-Klasse</strong> kann man sich diese mit Hilfe der Klasse <strong>AxGenerateAxBCClass </strong>generieren lassen.
</p>


<p>Dazu einfach diese Klasse im AOT&nbsp;per rechter Maustaste aufrufen und dem Assistenten folgen.
</p>


<p>Die auf diese Art &amp;&nbsp;Weise generierte Klasse muss unter manchen Umst&auml;nden noch etwas bearbeitet werden, dennoch geht der Vorgang rascher von der Hand, als die Klasse komplett selbst erstellen zu m&uuml;ssen.
</p>


<p>Und wenn sich die Tabelle &auml;ndert, beispielweise wenn neue Felder hinzukommen, kann man die <strong>AxGenerateAxBCClass </strong>einfach nochmals aufrufen und die AX&lt;Table&gt;-Klasse wird entsprechend erweitert.
</p>


<p>Wie man solche AX&lt;Table&gt;-Klassen verwendet, habe ich u.a. <a href="http://www.schweda.net/blog_ax.php?bid=494" target="_self" title="Erstellen einer Entität per Code">hier beschrieben</a>.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 12 Nov 2013 15:27:00 +0100</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=495</link>
<comments>https://www.schweda.net/blog_ax.php?bid=495</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=495</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=495</wfw:commentRss>
</item>
<item>
<title><![CDATA[Beispiel für einen Datumsfilter einer FormDataSource]]></title>
<description><![CDATA[
<p>Im folgenden ein Beispiel, wie man bei einer FormDataSource einen QueryBuildRange aufbaut, welcher nur tagesaktuelle Datens&auml;tze anzeigt.
</p>

<p>Im Beispiel enth&auml;lt unsere FormDataSource namens <em>DataSourceName </em>zwei Datumsfelder namens <em>FromDate </em>und <em>ToDate </em>und es sollen abh&auml;ngig von einer Checkbox nur Datens&auml;tze angezeigt werden, die &quot;heute&quot; g&uuml;ltig sind.
</p>

<div class="div_blog_axcode">public void applyFilter()<br />
{<br />
&nbsp;&nbsp;&nbsp; queryBuildRange qbr;<br />
<br />
&nbsp;&nbsp;&nbsp; qbr = sysQuery::findOrCreateRange(DataSourceName_ds.queryBuildDataSource(), fieldNum(DataSourceName, recId));<br />
<br />
&nbsp;&nbsp;&nbsp; if( !ShowExpiredCheckBox.checked())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; qbr.value(strfmt('('+<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '((%5.%2 &lt;= %1) &amp;&amp; (%5.%3 &gt;= %1)) || ' +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '((%5.%2 == %4) &amp;&amp; (%5.%3 == %4)) || ' +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '((%5.%2 &lt;= %1) &amp;&amp; (%5.%3 == %4)) || ' +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '((%5.%3 &gt;= %1) &amp;&amp; (%5.%2 == %4)) ' +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ')',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date2StrXpp(systemDateGet()),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldstr(DataSourceName, FromDate),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldstr(DataSourceName, ToDate),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date2StrXpp(dateNull()),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tableId2name(tableNum(DataSourceName))));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; qbr.value(SysQuery::valueUnlimited());<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>

<p>Der Aufruf obiger Methode kann beispielsweise in der <em>executeQuery()</em> der Datasource erfolgen.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sun, 01 Sep 2013 15:43:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=475</link>
<comments>https://www.schweda.net/blog_ax.php?bid=475</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=475</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=475</wfw:commentRss>
</item>
<item>
<title><![CDATA[X++ -Statement generieren um Datensätze anzulegen]]></title>
<description><![CDATA[
<p>Vor kurzem hatte ich die Notwendigkeit einige Datens&auml;tze von einer AX-Umgebung in eine andere zu kopieren. Es ging um eine sehr flache Tabelle (d.h. ohne gro&szlig;artige Referenzen auf andere Tabellen oder Datens&auml;tze), wodurch ich folgenden Job daf&uuml;r nutzen konnte.
</p>

<p>Der Job durchl&auml;uft ein Select-Statement (ganz am Ende des Jobs) und kopiert mir in die Zwischenablage ein X++-Statement, mit welchem man die Datens&auml;tze - beispielsweise &uuml;ber einen eigenen Job - einf&uuml;gen kann.
</p>

<p>Inspiriert ist der Code &uuml;brigens von der Methode <em>buildInsertScript()</em> des Formulares <em>SysRecordInfo</em>.<br />
&nbsp;
</p>

<div class="div_blog_axcode">static void buildInsertScriptAX2009(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; CustGroup CustGroup;<br />
<br />
&nbsp;&nbsp;&nbsp; #define.indent('&nbsp;&nbsp;&nbsp; ')<br />
<br />
&nbsp;&nbsp;&nbsp; SysDictTable dictTable;<br />
&nbsp;&nbsp;&nbsp; Counter&nbsp;&nbsp;&nbsp;&nbsp; fieldCounter;<br />
&nbsp;&nbsp;&nbsp; Counter&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter;<br />
&nbsp;&nbsp;&nbsp; DictEnum&nbsp;&nbsp;&nbsp; dictEnum;<br />
&nbsp;&nbsp;&nbsp; DictField&nbsp;&nbsp; dictFieldTemp;<br />
&nbsp;&nbsp;&nbsp; DictField&nbsp;&nbsp; dictFieldArray;<br />
&nbsp;&nbsp;&nbsp; str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue;<br />
&nbsp;&nbsp;&nbsp; TextBuffer&nbsp; textBuffer;<br />
&nbsp;&nbsp;&nbsp; Source&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source;<br />
<br />
&nbsp;&nbsp;&nbsp; boolean setFieldValue(fieldId _fieldId, common _common)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = &quot;&quot;;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.baseType() != Types::Container)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strfmt(&quot;%1&quot;, _common.(_fieldId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (dictFieldTemp.baseType())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::String :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strReplace(fieldValue, '\n', '\\n');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = '\&quot;' + fieldValue + '\&quot;';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Container :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = '[' + fieldValue + ']';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Enum :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictEnum = new DictEnum(dictFieldTemp.enumId());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = dictEnum.name() + '::' + dictEnum.index2Symbol(_common.(_fieldId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Real :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = num2str(_common.(_fieldId), 2, -1, 1, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Date :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = date2str(_common.(_fieldId), 123,2,4,2,4,4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fieldValue == '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strReplace(fieldValue, '/', '\\');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::UtcDateTime :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = DateTimeUtil::toStr(_common.(_fieldId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fieldValue == '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; void loopRecord(common _common)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source += #indent + strfmt('%1.clear();\r\n', dictTable.name());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (fieldCounter = dictTable.fieldNext(0); fieldCounter &gt; 0; fieldCounter = dictTable.fieldNext(fieldCounter))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldTemp = new DictField(dictTable.id(), fieldCounter);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.isSystem())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.arraySize() &gt; 1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (arrayCounter &lt;= dictFieldTemp.arraySize())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldArray = new DictField(dictTable.id(), fieldId2Ext(dictFieldTemp.id(),arrayCounter));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (setFieldValue(dictFieldArray.id(), _common))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source = source + #indent + strfmt(&quot;%1.%2 = %3;&quot;, dictTable.name(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldArray.name(DbBackend::Native, arrayCounter),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue) + '\r\n';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (setFieldValue(fieldCounter, _common))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source = source + #indent + strfmt(&quot;%1.%2 = %3;&quot;, dictTable.name(), dictFieldTemp.name(), fieldValue) + '\r\n';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source += #indent + strfmt('%1.insert();\r\n', dictTable.name());<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; ;<br />
<br />
&nbsp;&nbsp;&nbsp; // Modify needed records here<br />
&nbsp;&nbsp;&nbsp; dictTable = new SysDictTable(tableNum(CustGroup));<br />
<br />
&nbsp;&nbsp;&nbsp; while select CustGroup<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loopRecord(CustGroup);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp; textBuffer = new TextBuffer();<br />
&nbsp;&nbsp;&nbsp; textBuffer.setText(source);<br />
&nbsp;&nbsp;&nbsp; textBuffer.toClipboard();<br />
<br />
&nbsp;&nbsp;&nbsp; info(&quot;@SYS87601&quot;);<br />
}
</div>

<p>Das Ergebnis des Jobs ist in der Zwischenablage zu finden, und sieht beispielsweise wie folgt aus:
</p>

<div class="div_blog_axcode">CustGroup.clear();<br />
CustGroup.CustGroup = &quot;K-DRITT&quot;;<br />
CustGroup.Name = &quot;Kunden Drittland&quot;;<br />
CustGroup.ClearingPeriod = &quot;&quot;;<br />
CustGroup.PaymTermId = &quot;&quot;;<br />
CustGroup.TaxGroupId = &quot;&quot;;<br />
CustGroup.PaymIdType = &quot;&quot;;<br />
CustGroup.insert();<br />
CustGroup.clear();<br />
CustGroup.CustGroup = &quot;K-EU&quot;;<br />
CustGroup.Name = &quot;Kunden EU&quot;;<br />
CustGroup.ClearingPeriod = &quot;&quot;;<br />
CustGroup.PaymTermId = &quot;&quot;;<br />
CustGroup.TaxGroupId = &quot;&quot;;<br />
CustGroup.PaymIdType = &quot;&quot;;<br />
CustGroup.insert();<br />
CustGroup.clear();<br />
CustGroup.CustGroup = &quot;K-INL&quot;;<br />
CustGroup.Name = &quot;Kunden Inland&quot;;<br />
CustGroup.ClearingPeriod = &quot;&quot;;<br />
CustGroup.PaymTermId = &quot;&quot;;<br />
CustGroup.TaxGroupId = &quot;&quot;;<br />
CustGroup.PaymIdType = &quot;&quot;;<br />
CustGroup.insert();<br />
&nbsp;
</div>

<p>In Dynamics AX 2012 sieht der gleiche Job etwas anders aus:
</p>

<div class="div_blog_axcode">static void buildInsertScriptAX2012(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; CustGroup CustGroup;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; #define.indent('&nbsp;&nbsp;&nbsp; ')<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; SysDictTable dictTable;<br />
&nbsp;&nbsp;&nbsp; Counter&nbsp;&nbsp;&nbsp;&nbsp; fieldCounter;<br />
&nbsp;&nbsp;&nbsp; Counter&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter;<br />
&nbsp;&nbsp;&nbsp; DictEnum&nbsp;&nbsp;&nbsp; dictEnum;<br />
&nbsp;&nbsp;&nbsp; DictField&nbsp;&nbsp; dictFieldTemp;<br />
&nbsp;&nbsp;&nbsp; DictField&nbsp;&nbsp; dictFieldArray;<br />
&nbsp;&nbsp;&nbsp; str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue;<br />
&nbsp;&nbsp;&nbsp; TextBuffer&nbsp; textBuffer;<br />
&nbsp;&nbsp;&nbsp; Source&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source;<br />
<br />
&nbsp;&nbsp;&nbsp; boolean setFieldValue(common _common, FieldName _fieldName, ArrayIdx _arrayIndex = 1)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = &quot;&quot;;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.baseType() != Types::Container)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strFmt(&quot;%1&quot;, _common.getFieldValue(_fieldName, _arrayIndex));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (dictFieldTemp.baseType())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::String :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strReplace(fieldValue, '\n', '\\n');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = '\&quot;' + fieldValue + '\&quot;';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Container :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = '[' + fieldValue + ']';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Enum :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictEnum = new DictEnum(dictFieldTemp.enumId());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = dictEnum.name() + '::' + dictEnum.value2Symbol(_common.getFieldValue(_fieldName, _arrayIndex));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Real :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = num2str(_common.getFieldValue(_fieldName, _arrayIndex), 2, -1, 1, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::Date :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = date2str(_common.getFieldValue(_fieldName, _arrayIndex), 123,2,4,2,4,4, DateFlags::None);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fieldValue == '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = strReplace(fieldValue, '/', '\\');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Types::UtcDateTime :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue = DateTimeUtil::toStr(_common.getFieldValue(_fieldName, _arrayIndex));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fieldValue == '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; void loopRecord(common _common)&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (fieldCounter = dictTable.fieldNext(0); fieldCounter &gt; 0; fieldCounter = dictTable.fieldNext(fieldCounter))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldTemp = new DictField(dictTable.id(), fieldCounter);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.isSystem())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dictFieldTemp.arraySize() &gt; 1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (arrayCounter &lt;= dictFieldTemp.arraySize())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldArray = new DictField(dictTable.id(), dictFieldTemp.id(), arrayCounter);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (setFieldValue(_common, dictFieldArray.name(), arrayCounter))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source = source + #indent + strFmt(&quot;%1.%2 = %3;&quot;, dictTable.name(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictFieldArray.name(DbBackend::Native, arrayCounter),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fieldValue) + '\r\n';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrayCounter++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (setFieldValue(_common, dictFieldTemp.name()))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source = source + #indent + strFmt(&quot;%1.%2 = %3;&quot;, dictTable.name(), dictFieldTemp.name(), fieldValue) + '\r\n';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source += #indent + strFmt('%1.insert();\r\n', dictTable.name());<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // Modify needed records here&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; dictTable = new SysDictTable(tableNum(CustGroup));<br />
<br />
&nbsp;&nbsp;&nbsp; while select CustGroup<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loopRecord(CustGroup);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp; textBuffer = new TextBuffer();<br />
&nbsp;&nbsp;&nbsp; textBuffer.setText(source);<br />
&nbsp;&nbsp;&nbsp; textBuffer.toClipboard();<br />
<br />
&nbsp;&nbsp;&nbsp; info(&quot;@SYS87601&quot;);<br />
}
</div>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Tue, 13 Aug 2013 20:35:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=472</link>
<comments>https://www.schweda.net/blog_ax.php?bid=472</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=472</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=472</wfw:commentRss>
</item>
<item>
<title><![CDATA[Tipps und Tricks zum Thema Kompilierung]]></title>
<description><![CDATA[
<p><a href="http://www.schweda.net/pictures/blogpics/ax2009_compiler_output.jpg" target="_blank"><img width="465" height="155" border="0" src="http://www.schweda.net/pictures/blogpics/tb_ax2009_compiler_output.jpg " alt="Compiler output" title="Compiler output" /></a>
</p>

<p>Kompilieren geh&ouml;rt zum t&auml;glich Brot eines Entwicklers. Leider weist genau dieser Vorgang in Dynamics AX - nennen wir es - Besonderheiten auf.
</p>

<p><strong>Besonderheit 1: Kein Fortschrittsbalken</strong>
</p>

<p>Wir kennen es alle, man kompiliert eine gr&ouml;ssere Menge an Objekten oder vielleicht den ganzen AOT und m&ouml;chte zumindest ungef&auml;hr wissen, wie lange dies noch dauert.
</p>

<p>Standardm&auml;ssig gibt&rsquo;s es kaum eine M&ouml;glichkeit dies einzusehen, vor allem wenn der AX-Client seit dem Start der Kompilierung vielleicht schon &quot;eingefroren&quot; ist.
</p>

<p>In vielen F&auml;llen kann man [CTRL]+[PAUSE] dr&uuml;cken, dadurch wird die Kompilierung kurz angehalten und man kann im Client sehen, bei welchem Objekt man gerade ist. In dem Pause-Dialog sollte man nat&uuml;rlich tunlichst auf [NEIN] klicken, wenn man die Kompilierung danach fortsetzen m&ouml;chte.
</p>

<p>Kein echter Fortschrittsbalken, aber zumindest ein Indikator wo man gerade steht.
</p>
<br /><a class="div_blog_category_gotodetail" href="https://www.schweda.net/blog_ax.php?bid=473" target="_self" title="Weiterlesen...">Weiterlesen...</a>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Sat, 03 Aug 2013 19:15:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=473</link>
<comments>https://www.schweda.net/blog_ax.php?bid=473</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=473</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=473</wfw:commentRss>
</item>
<item>
<title><![CDATA[Text-Datei per X++ drucken]]></title>
<description><![CDATA[
<p>Ein kurzes Beispiel, wie man aus AX heraus via Notepad eine Text-Datei ausdrucken kann.
</p>


<pre class="pre_blog_axcode">
static void printTextFileFromAX(Args _args)
{
    WinAPI::shellExecute(&quot;c:&#092;&#092;windows&#092;&#092;system32&#092;&#092;NOTEPAD.EXE&quot;,  @&#39;/pt &quot;c:&#092;temp&#092;test.txt&quot; &quot;An OneNote 2010 senden&quot;&#39;);
}
</pre>


<p>Hinweise: &quot;An OneNote 2010 senden&quot; ist dabei der Name des Druckers. Das Beispiel wurde in Dynamics AX 2012 verwendet, sollte allerdings auch in fr&uuml;heren Versionen verwendbar sein.
</p>]]></description>
<category>Microsoft Dynamics AX (Axapta)</category>
<pubDate>Thu, 11 Jul 2013 20:50:00 +0200</pubDate>
<link>https://www.schweda.net/blog_ax.php?bid=471</link>
<comments>https://www.schweda.net/blog_ax.php?bid=471</comments>
<guid isPermaLink="true">https://www.schweda.net/blog_ax.php?bid=471</guid>
<author>heinz.schweda@schweda.net (Heinz Schweda)</author>
<wfw:commentRss>https://www.schweda.net/blog_ax.php?bid=471</wfw:commentRss>
</item>
</channel>
</rss>	
