<?xml version="1.0" encoding="iso-8859-1"?><?xml-stylesheet type="text/css" href="http://www.schweda.net/style_feed.css" ?>


<feed version="0.3" xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
  <title>Blog von Heinz Schweda</title>
  <link rel="alternate" type="text/html" hreflang="de" href="http://www.schweda.net/" />
 <link rel="self" type="application/atom+xml" 
   href="http://www.schweda.net/blog_atom.php"/>
  <rights>Copyright (c) 2006, Heinz Schweda</rights>

  <updated>2006-08-01T12:00:00Z</updated>
  <author>
    <name>Heinz Schweda</name>
  </author>
<id>tag:schweda.net,2006:1</id>



 
<entry>
<id>tag:schweda.net,2010-08-05:id391</id><title type="text">Shared Project mit X++ erstellen II</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>In einem <a title="Shared Project mit X++ erstellen" target="_self" href="http://www.schweda.net/blog_ax.php?nid=sharedproject1">fr&uuml;heren Beitrag</a> habe ich ja hier schon einen Job ver&ouml;ffentlicht, mit dessen Hilfe man sich per X++ ein Shared Project erstellen kann. Basierend auf der neu <a title="selectMultiple und selectSingle" target="_self" href="http://www.schweda.net/blog_ax.php?nid=selectmultiple">entdeckten Funktion selectMultiple</a> habe ich diesen nun etwas erweitert, der Benutzer hat mit dessen Hilfe nun die M&ouml;glichkeit, ein Shared Project zu erstellen und dabei f&uuml;r die aktuell ben&ouml;tigten Datentypen eigene Gruppenknoten innerhalb dieses Projektes zu erstellen.
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 280px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">static void CreateSharedProjectUsingSelectMultiple(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; DictEnum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DictEnum;<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conValues;<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conSelectedValues;<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conSelectMultiple;<br />
&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i;<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectNode;<br />
&nbsp;&nbsp;&nbsp; projectGroupNode&nbsp;&nbsp;&nbsp; projectGroupNode;<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode;<br />
&nbsp;&nbsp;&nbsp; treeNodeName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameOfProject;<br />
&nbsp;&nbsp;&nbsp; groupNodeType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupNodeType;<br />
&nbsp;&nbsp;&nbsp; treeNodeName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupNodeName;<br />
&nbsp;&nbsp;&nbsp; dialog&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dialog;<br />
&nbsp;&nbsp;&nbsp; dialogField&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dfProjectName;<br />
&nbsp;&nbsp;&nbsp; #AOTExport<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; // Create dialog<br />
&nbsp;&nbsp;&nbsp; dialog = new dialog();<br />
&nbsp;&nbsp;&nbsp; dfProjectName = dialog.addFieldValue(typeId(treeNodeName), &quot;NameOfproject&quot;, &quot;Name of project&quot;);<br />
&nbsp;&nbsp;&nbsp; if( !dialog.run())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; nameOfProject = dfProjectName.value() ? dfProjectName.value() : &quot;Unknown&quot;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; // Add available values to container<br />
&nbsp;&nbsp;&nbsp; DictEnum = new DictEnum(enumName2Id(identifierStr(GroupNodeType)));<br />
&nbsp;&nbsp;&nbsp; for(i=1;i&lt;DictEnum.values();i++)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conValues = conIns(conValues, conLen(conValues)+1, [DictEnum.index2Label(i), i, false]);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // Call selectMultiple<br />
&nbsp;&nbsp;&nbsp; conSelectMultiple = selectMultiple(&quot;Please select&quot;, &quot;Please select the needed project-groups&quot;, conValues);<br />
&nbsp;&nbsp;&nbsp; conSelectedValues = conPeek(conSelectMultiple, 2);<br />
&nbsp;&nbsp;&nbsp; if( !conPeek(conSelectMultiple, 1))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; // Create shared project<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; myProjectNode&nbsp; = projectNode.AOTfindChild(nameOfProject);<br />
<br />
&nbsp;&nbsp;&nbsp; if( !myProjectNode)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode = projectNode.AOTadd(nameOfProject);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; myProjectNode&nbsp;&nbsp;&nbsp;&nbsp; = myProjectNode.getRunNode();<br />
<br />
&nbsp;&nbsp;&nbsp; if(conPeek(conSelectMultiple, 1))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=1; i&lt;=conLen(conSelectedValues); i++)<br />
&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; groupNodeName = DictEnum.index2Label(conPeek(conSelectedValues, i));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !projectGroupNode)<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; myProjectNode.AOTadd(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.projectGroupType(DictEnum.name2Value(groupNodeName));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; projectGroupNode.AOTsave();<br />
<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTrefresh();<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTrun();<br />
}
</div>

<p>Obiger Code funktioniert meines Wissens nach in Dynamics AX 4.0 und Dynamics AX 2009.
</p>

<p>&nbsp;
</p>

<p>&nbsp;
</p>]]></content>
<published>2010-08-05T19:15:44Z</published>
<updated>2010-08-05T19:15:44Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=391"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-08-05:id390</id><title type="text">selectMultiple und selectSingle</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Beim St&ouml;bern in den vorgefertigten Methoden in der <em>global</em>-Klasse bin ich auf zwei Funktionen gestossen, die ich schon fr&uuml;her das eine oder andere Mal gebraucht h&auml;tte: <strong>selectMultiple </strong>und <strong>selectSingle</strong>.
</p>

<p>Was k&ouml;nnen diese Funktionen? Man &uuml;bergibt Ihnen einen Container mit m&ouml;glichen Werten und als R&uuml;ckgabewert erh&auml;lt man ebenfalls einen Container mit den vom Benutzer ausgew&auml;hlten Werten. Dazwischen wird ein Dialog generiert, der nicht benutzerfreundlicher sein k&ouml;nnte, wie ich finde.
</p>

<p><a href="http://www.schweda.net/pictures/blogpics/AX2009selectMultiple.jpg"><img height="207" border="0" width="447" title="SelectMultiple" alt="" src="http://www.schweda.net/pictures/blogpics/AX2009selectMultiple_small.jpg" /></a>
</p>


<p>Obiger Dialog wurde &uuml;ber den nachstehenden Job erzeugt.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 280px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;">static void selectMultiple(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp; conValues;<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp; conSelectedValues;<br />
&nbsp;&nbsp;&nbsp; container&nbsp;&nbsp; conSelectMultiple;<br />
&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i;<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; conValues = conIns(conValues, conLen(conValues)+1, [&quot;Dynamics AX 3.0\nAlias Microsoft Business Solutions Axapta 3.0&quot;, &quot;30&quot;, false]);<br />
&nbsp;&nbsp;&nbsp; conValues = conIns(conValues, conLen(conValues)+1, [&quot;Dynamics AX 4.0&quot;, &quot;40&quot;, false]);<br />
&nbsp;&nbsp;&nbsp; conValues = conIns(conValues, conLen(conValues)+1, [&quot;Dynamics AX 2009&quot;, &quot;50&quot;, true]);<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; conSelectMultiple = selectMultiple(&quot;Bitte w&auml;hlen Sie aus&quot;, &quot;Bitte w&auml;hlen Sie Ihre verwendeten Dynamics AX-Versionen aus&quot;, conValues, [&quot;Version&quot;, &quot;Bemerkung&quot;]);<br />
&nbsp;&nbsp;&nbsp; conSelectedValues = conPeek(conSelectMultiple, 2);<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; if(conPeek(conSelectMultiple, 1))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=1; i&lt;=conLen(conSelectedValues); i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info(conPeek(conSelectedValues, i));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>

<p><strong>selectSingle </strong>funktioniert vom Prinzip her genauso, mit dem einzigen Unterschied da&szlig; der Benutzer nur einen Wert ausw&auml;hlen kann.
</p>

<p>In einem Job, mit dessen Hilfe man per <a href="http://www.schweda.net/blog_ax.php?nid=sharedproject2" target="_self" title="Shared Project per X++ erstellen II">X++ ein Shared Project</a> erstellt, habe ich mein neues Wissen auch schon angewendet.
</p>]]></content>
<published>2010-08-05T19:23:36Z</published>
<updated>2010-08-05T19:23:36Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=390"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-07-19:id389</id><title type="text">Feldwert eines aufrufenden Objektes ermitteln</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>In vielen Objekten sieht man Kontrukte wie das folgende, die dazu dienen, einen Wert aus dem aufrufenden Datensatz zu ermitteln.
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 260px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">if (element.args() &amp;&amp; element.args().record())<br />
{<br />
&nbsp;&nbsp;&nbsp; switch (element.args().dataset())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case tablenum(PurchLine)&nbsp;&nbsp;&nbsp; :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itemIdCaller = element.args().record().(fieldNum(purchLine, ItemId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case tablenum(SalesLine)&nbsp;&nbsp;&nbsp; :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itemIdCaller = element.args().record().(fieldNum(SalesLine, ItemId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case tablenum(SalesQuotationLine)&nbsp;&nbsp;&nbsp; :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itemIdCaller = element.args().record().(fieldNum(SalesQuotationLine, ItemId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>

<p>Einfacher geht&rsquo;s mit&nbsp;unten dem stehenden&nbsp;St&uuml;ckchen Code! Der grosse Vorteil von diesem ist, da&szlig; wann immer man das Objekt von einem Datensatz aus aufruft, der ein Feld namens <em>itemId</em> enth&auml;lt, die Logik&nbsp;abgearbeitet wird&nbsp;ohne da&szlig; man jede Tabelle einzeln im switch-Statement ber&uuml;cksichtigen muss.
</p>


<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 150px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">if (element.args() &amp;&amp; element.args().record())<br />
{<br />
&nbsp;&nbsp;&nbsp; sysDictTable = new sysDictTable(element.args().dataset());<br />
&nbsp;&nbsp;&nbsp; if(sysDictTable.fieldName2Id('itemId'))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itemIdCaller = element.args().record().(sysDictTable.fieldName2Id('itemId'));<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>]]></content>
<published>2010-07-19T09:17:07Z</published>
<updated>2010-07-19T09:17:07Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=389"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-07-24:id388</id><title type="text">Liste aller Felder einer Tabelle ausgeben</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Unl&auml;ngst ben&ouml;tigte ich eine Liste aller Felder einer Tabelle mit deren Datentypen. Daf&uuml;r habe ich mir den folgenden Job - im Beispiel f&uuml;r die Tabelle <em>custGroup </em>- geschrieben:
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 300px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">static void listAllFields4Table(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; dictTable&nbsp;&nbsp; dictTable = new dictTable(tableNum(<strong>custGroup</strong>));<br />
&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currFieldId = 0;<br />
&nbsp;&nbsp;&nbsp; counter&nbsp;&nbsp;&nbsp;&nbsp; c = 0;<br />
&nbsp;&nbsp;&nbsp; dictField&nbsp;&nbsp; dictField;<br />
&nbsp;&nbsp;&nbsp; counter&nbsp;&nbsp;&nbsp;&nbsp; a = 0;<br />
&nbsp;&nbsp;&nbsp; common&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; common;<br />
&nbsp;&nbsp;&nbsp; str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enumName;<br />
&nbsp;&nbsp;&nbsp; ;<br />
<br />
&nbsp;&nbsp;&nbsp; common = DictTable.makeRecord();<br />
&nbsp;&nbsp;&nbsp; setPrefix(strFmt(&quot;Fields of table %1&quot;,&nbsp; tableId2name(common.TableId)));<br />
<br />
&nbsp;&nbsp;&nbsp; currFieldId = 0;<br />
&nbsp;&nbsp;&nbsp; c = 0; <br />
&nbsp;&nbsp;&nbsp; do<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currFieldId = dictTable.fieldNext(currFieldId); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(currFieldId != 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictField = new dictField(common.TableId, currFieldId); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(dictField.arraySize() == 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; info(&nbsp;&nbsp; strFmt(&quot;%1: %2 [%3%4]&quot;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictTable.fieldName(currFieldId),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictField.label(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictField.baseType(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dictField.enumId() ? strFmt(&quot; %1&quot;, enumId2Name(dictField.enumId())) : &quot;&quot;)<br />
&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; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(dictField.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; for(a=1;a&lt;=dictField.arraySize();a++)<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; info(&nbsp;&nbsp; strFmt(&quot;%1 [%2]: %3 [%4]&quot;,<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; dictTable.fieldName(currFieldId),<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; a,<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; dictField.label(),<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; dictField.baseType())<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; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c++;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; while (c &lt; dictTable.fieldCnt());<br />
}
</div>


<p>Das Ergebnis dieses Jobs sieht wie folgt aus:
</p>

<p><img title="List of Table fields" alt="List of table fields" width="409" height="423" src="http://www.schweda.net/pictures/blogpics/ListTableFields.jpg" />
</p>]]></content>
<published>2010-07-24T10:59:21Z</published>
<updated>2010-07-24T10:59:21Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=388"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-07-20:id386</id><title type="text">Prüfungen durchführen beim/vor dem Schliessen eines Formulares</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>M&ouml;chte/mu&szlig; man beim bzw. vor dem Schliessen eines Formulares etwas tun, z.B. Pr&uuml;fungen durchf&uuml;hren, so stellt Dynamics AX daf&uuml;r einige Methoden zur Verf&uuml;gung, die in einer bestimmten Reihenfolge abgearbeitet werden. Da ich selbst mir diese Reihenfolge nicht merke, habe ich&nbsp;sie hier kurz notiert.
</p>

<p>Beim Schliessen eines Formulares &uuml;ber einen OK-Commandbutton:
</p>

<ul>
    
<li>closeOK
</li>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>Beim Schliessen eines Formulares &uuml;ber einen CANCEL-Commandbutton:
</p>

<ul>
    
<li>closeCancel
</li>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>Beim Schliessen eines Formulares &uuml;ber &quot;das rote X&quot; bzw. der ESC-Taste:
</p>

<ul>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>&nbsp;
</p>


<p>Bei einer Lookup-Form verh&auml;lt es sich etwas anders:
</p>

<p>Beim Schliessen eines Formulares &uuml;ber einen OK-Commandbutton:
</p>

<ul>
    
<li>closeSelect
</li>
    
<li>closeOK
</li>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>Beim Schliessen eines Formulares &uuml;ber einen CANCEL-Commandbutton:
</p>

<ul>
    
<li>closeSelect
</li>
    
<li>closeOK
</li>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>Beim Schliessen eines Formulares &uuml;ber &quot;das rote X&quot; bzw. der ESC-Taste:
</p>

<ul>
    
<li>canClose
</li>
    
<li>close
</li>

</ul>

<p>Daraus ergibt sich, da&szlig; die optimale Methode f&uuml;r Pr&uuml;fungen die <strong>canClose</strong>-Methode ist.
</p>

<p>Hier nun noch ein kurzer Job, der ein Formular &ouml;ffnet und nach dessen Schliessen ermittelt, wie das Formular geschlossen wurde:
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 260px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">static void OpenForm(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; FormRun form = null;<br />
&nbsp;&nbsp;&nbsp; Args&nbsp;&nbsp;&nbsp; formParams = new Args();<br />
&nbsp;&nbsp;&nbsp; ;&nbsp;<br />
&nbsp;&nbsp;&nbsp; formParams.name(formStr(CustTable));<br />
&nbsp;&nbsp;&nbsp; form = classFactory.formRunClass(formParams);<br />
&nbsp;&nbsp;&nbsp; form.init();<br />
&nbsp;&nbsp;&nbsp; form.run();<br />
&nbsp;&nbsp;&nbsp; form.wait();<br />
<br />
&nbsp;&nbsp;&nbsp; if(form.closed())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setPrefix(&quot;Form was closed.&quot;);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(form.closedOk())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info(&quot;Form was closed by OK-Button.&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(form.closedCancel())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info(&quot;Form was closed by CANCEL-Button.&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info(&quot;Form was closed by CLOSE-Button.&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>

<p>&nbsp;
</p>]]></content>
<published>2010-07-20T13:39:44Z</published>
<updated>2010-07-20T13:39:44Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=386"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-08-12:id384</id><title type="text">Auslesen von HTML-Quelltext in Dynamics AX 2009</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Vor kurzem wurde ich gefragt, wie man denn in Dynamics AX 2009 den HTML-Quelltext einer Webseite ausliest. Bittesch&ouml;n...
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 280px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;">static void GetHTMLSourceCode(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; CLRObject&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; castObject&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null;<br />
&nbsp;&nbsp;&nbsp; System.Net.HttpWebRequest&nbsp;&nbsp; request&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null;<br />
&nbsp;&nbsp;&nbsp; System.Net.HttpWebResponse&nbsp; response&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null;<br />
&nbsp;&nbsp;&nbsp; System.IO.StreamReader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; streamReader&nbsp;&nbsp;&nbsp; = null;<br />
&nbsp;&nbsp;&nbsp; System.Text.Encoding&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; encoding&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null; <br />
<br />
&nbsp;&nbsp;&nbsp; url&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url = &quot;http://www.yourdomain.com/yoursite.html&quot;;<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; new InteropPermission(InteropKind::ClrInterop).assert();<br />
&nbsp;&nbsp;&nbsp; castObject = System.Net.WebRequest::Create(url);<br />
&nbsp;&nbsp;&nbsp; request = castObject;<br />
&nbsp;&nbsp;&nbsp; response = request.GetResponse();<br />
&nbsp;&nbsp;&nbsp; encoding = System.Text.Encoding::get_UTF8();<br />
&nbsp;&nbsp;&nbsp; streamReader = new System.IO.StreamReader(response.GetResponseStream(), encoding);<br />
&nbsp;&nbsp;&nbsp; info(streamReader.ReadToEnd());<br />
}
</div>]]></content>
<published>2010-08-12T19:33:07Z</published>
<updated>2010-08-12T19:33:07Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=384"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-08-14:id383</id><title type="text">Label in einer bestimmten Sprache auslesen</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Um in X++ ein Label in einer ganz bestimmten Sprache auszugeben, nutzt man am besten die Methode labelId2String2 der SysLabel-Klasse:
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 50px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;">info(<span style="color: rgb(0, 0, 255);">any2str</span>(SysLabel::labelId2String2(literalStr(<span style="color: rgb(255, 0, 0);">&quot;@SYS14204&quot;</span>),<span style="color: rgb(255, 0, 0);">&quot;de-at&quot;</span>)));
</div>]]></content>
<published>2010-08-14T15:23:48Z</published>
<updated>2010-08-14T15:23:48Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=383"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-05-15:id381</id><title type="text">AxInventTable: Artikel per Code anlegen in Dynamics AX 2009</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Um einen Artikel in Dynamics AX 2009 anzulegen kann man sich - wie schon in <a href="http://www.schweda.net/blog_ax.php?bid=193" target="_self" title="AxInventTable">fr&uuml;heren Versionen</a> - der Klasse <strong>axInventTable</strong> bedienen. Dies Klasse hat den grossen Vorteil, da&szlig; sie sich auch um jene Tabellen k&uuml;mmert, die neben der <em>inventTable </em>bef&uuml;llt werden m&uuml;ssen, also die drei Datens&auml;tze in der <em>inventTableModule </em>und jenen in der <em>InventItemLocation</em>, soda&szlig; der Artikel sofort in der Form <em>InventTable </em>aufscheint.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 160px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;"><span style="color: rgb(0, 0, 255);">static void</span> createItemUsingAxInventTable(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; axInventTable axInventTable;<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; axInventTable = axInventTable::construct();<br />
&nbsp;&nbsp;&nbsp; axInventTable.parmItemId(<span style="color: rgb(255, 0, 0);">'NewItemId'</span>);<br />
&nbsp;&nbsp;&nbsp; axInventTable.save();<br />
}
</div>

<p>Etwas sollte man bei Verwendung der Klasse allerdings ber&uuml;cksichtigen: Obiger Job erstellt den Artikel, ohne eventuelle Pflichtfelder wie z.B. die Artikelgruppe zu bef&uuml;llen. Das aber auch nur, wenn es keine Datensatzvorlage vom Typ <strong>Unternehmensvorlage </strong>gibt. Gibt es eine solche Standardvorlage f&uuml;r den Artikelstamm, so nutzt AX diese!
</p>

<p>&nbsp;
</p>]]></content>
<published>2010-05-15T20:10:16Z</published>
<updated>2010-05-15T20:10:16Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=381"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-05-05:id380</id><title type="text">Firmwareupgrade beim HDC-350</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Basierend auf ein Kommentar zu meinem <a title="HDC-350" target="_self" href="http://www.schweda.net/blog.php?bid=363">ersten Beitrag zum Kabelreceiver HDC-350</a> habe ich vor einigen Tagen tats&auml;chlich ein Firmware-Update gewagt.
</p>

<p>Dabei bin ich wie folgt vorgegangen:
</p>

<ul>
    
<li>Herunterladen und Entpacken&nbsp;des Firmwarearchivs
</li>
    
<li>Anschlie&szlig;en des Kabelreceivers &uuml;ber die serielle Schnittstelle
</li>
    
<li>Starten des Kabelreceivers &uuml;ber die Fernbedienung
</li>
    
<li>Starten der Datei LoaderHD.exe (Achtung: Unter Windows Vista und Windows 7 muss die Datei ggf. als Administrator ausgef&uuml;hrt werden)
</li>
    
<li>Bet&auml;tigen der Schaltfl&auml;che &quot;Start Update&quot;
</li>

</ul>

<p><img title="HD Loader" alt="" width="465" height="104" src="http://www.schweda.net/pictures/blogpics/tb_hdc350_firmwareupgrade.jpg" />
</p>

<p>Nach kurzer Zeit meldete der Updatevorgang &quot;Update OK&quot; und ich konnte den Kabelreceiver wieder an unseren Fernseher anschliessen.
</p>

<p>Auf den ersten Blick konnte ich leider keinerlei Verbesserungen feststellen - was nicht heissen soll, da&szlig; sie nicht da w&auml;ren -&nbsp;und man sieht leider&nbsp;in keinem Men&uuml; oder &auml;hnlichen, welche Firmwareversion aktuell installiert ist.&nbsp;Da der Receiver aber tadellos funktioniert hat - auch Senderlisten usw. waren erhalten geblieben - ist dies ein vernachl&auml;ssigbarer Sch&ouml;nheitsfehler.
</p>

<p>Da&szlig; ich die neue Firmware tats&auml;chlich installiert hatte, habe ich erst beim Formatieren eines USB-Sticks gemerkt, hier kam tats&auml;chlich eine Meldung, wenn der Vorgang abgeschlossen war.
</p>

<p>Was meine ganz pers&ouml;nliche Liste an unterst&uuml;tzen USB-Devices anbelangt, hier hat sich nichts ver&auml;ndert. Nach wie vor werden einige meiner Ger&auml;te nicht erkannt, schade!
</p>]]></content>
<published>2010-05-05T21:37:34Z</published>
<updated>2010-05-05T21:37:34Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=380"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-06-24:id379</id><title type="text">Ansprechen der seriellen Schnittstelle unter Dynamics AX 2009</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Mithilfe der Klasse <a href="http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx" target="_blank" title="MSDN SerialPorts">SerialPorts</a> aus&nbsp;dem .net-Framework kann man unter Dynamics AX 2009 recht bequem auf die serielle Schnittstelle zugreifen. Nachstehend dazu ein kurzes Code-Beispiel, wie man ein Display, wie man es z.B. von Kassensystemen kennt, ansteuern kann.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 240px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;"><span style="color: rgb(0, 0, 255);">static void</span> sendText2SerialPort(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; System.IO.Ports.SerialPort&nbsp;SerialPort;<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 0, 255);">str</span>&nbsp;deleteDisplay = <span style="color: rgb(0, 0, 255);">num2char</span>(hex2int(<span style="color: rgb(255, 0, 0);">&quot;0C&quot;</span>));<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; SerialPort = new System.IO.Ports.SerialPort(<span style="color: rgb(255, 0, 0);">'com4'</span>);<br />
&nbsp;&nbsp;&nbsp; SerialPort.Open(); <br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 0, 255);">if</span>(SerialPort.get_IsOpen())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SerialPort.Write(deleteDisplay); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SerialPort.Write(<span style="color: rgb(255, 0, 0);">'Welcome World!'</span>); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SerialPort.Close();<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</div>

<p>&nbsp;
</p>]]></content>
<published>2010-06-24T19:47:11Z</published>
<updated>2010-06-24T19:47:11Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=379"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-06-04:id378</id><title type="text">Druckoptionen von Berichten können nicht geändert werden</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>In Dynamics AX 2009 scheint es einen kleinen Bug zu geben, der bei Reports, welche &uuml;ber eine von <strong>RunBaseReport </strong>abgeleitete Klasse gestartet werden, dazu f&uuml;hrt, da&szlig; sich die Druckoptionen nicht &auml;ndern lassen.
</p>

<p>Um diesen Bug zu umgehen,&nbsp;kann man&nbsp;die Methode <strong>dialogUpdatePrinterSettings</strong>, wie in nachstehendem Beispiel beschrieben, &uuml;berschreiben.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 170px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;"><span style="color: rgb(0, 0, 255);">public void</span> dialogUpdatePrinterSettings(Dialog dialog)<br />
{<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// --&gt; (1) Workaround to update printJobSettings and dialog<br />
</span>&nbsp;&nbsp;&nbsp; this.printJobSettings().unpackPrintJobSettings(this.reportRun().packPrintJobSettings());<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// &lt;-- (1)<br />
</span><br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 0, 255);">super</span>(dialog);<br />
}
</div>]]></content>
<published>2010-06-04T18:37:52Z</published>
<updated>2010-06-04T18:37:52Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=378"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-05-01:id377</id><title type="text">Start- und Enddatum des aktuellen Geschäftsjahres ermitteln</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Um das Start- und Enddatum des aktuellen Gesch&auml;ftsjahres zu ermitteln, kann man sich nachstehender Methode bedienen. Diese liefert einen Container zur&uuml;ck, dessen erstes Element das Start- und dessen zweites Element das Enddatum des Gesch&auml;ftsjahres enth&auml;lt.
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 40px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">ledgerPeriod::findFiscalYearDates(systemdateget());
</div>]]></content>
<published>2010-05-01T20:02:48Z</published>
<updated>2010-05-01T20:02:48Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=377"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-06-10:id376</id><title type="text">Eine von RunBasebatch abgeleitete Klasse ist nicht im Stapel lauffähig</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Vor kurzem hatte ich die Aufgabenstellung, eine Klasse die bereits von RunBase abgeleitet worden war, stapelf&auml;hig zu gestalten. So weit so einfach, dachte ich mir und habe in der <em>ClassDeclaration </em>der Klasse <strong>extends runBase </strong>durch<strong> extends runBaseBatch </strong>ersetzt. Ich hatte danach zwar den entsprechenden Register im Dialog, die Klasse wurde aber dennoch immer sofort ausgef&uuml;hrt :-(
</p>

<p>Nach etwas herumprobieren hatte ich schlussendlich in der Methode <strong>getFromDialog </strong>den Fehler entdeckt: Diese war so programmiert, da&szlig; sie per <em>return true </em>immer <em>true </em>retouniert, das runBaseBatch-Framework ben&ouml;tigt an dieser Stelle allerdings ein <em>return super()</em>.
</p>

<p>Kleine Ursache, grosse Wirkung.
</p>]]></content>
<published>2010-06-10T20:39:23Z</published>
<updated>2010-06-10T20:39:23Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=376"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-04-17:id372</id><title type="text">Shared Project mit X++ erstellen</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Nachstehend ein Beispiel, mit dem man in Dynamics AX 2009 per X++ ein Projekt erstellen, und Elemente zu diesem Projekt hinzuf&uuml;gen kann.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 300px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;">static void CreateSharedProject(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectNode;<br />
&nbsp;&nbsp;&nbsp; projectGroupNode&nbsp;&nbsp;&nbsp; projectGroupNode;<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode;<br />
&nbsp;&nbsp;&nbsp; treeNodeName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameOfProject;<br />
&nbsp;&nbsp;&nbsp; groupNodeType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupNodeType;<br />
&nbsp;&nbsp;&nbsp; treeNodeName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupNodeName;<br />
&nbsp;&nbsp;&nbsp; #AOT<br />
&nbsp;&nbsp;&nbsp; ;<br />
<br />
&nbsp;&nbsp;&nbsp; nameOfProject = <span style="color: rgb(255, 0, 0);">'MyProject'</span>;<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Create shared project</span><br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp; = infolog.projectRootNode();<br />
&nbsp;&nbsp;&nbsp; projectNode&nbsp;&nbsp;&nbsp; = projectNode.AOTfindChild(<span style="color: rgb(255, 0, 0);">'Shared'</span>);<br />
&nbsp;&nbsp;&nbsp; myProjectNode&nbsp; = projectNode.AOTfindChild(nameOfProject);<br />
<br />
&nbsp;&nbsp;&nbsp; if( !myProjectNode)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode = projectNode.AOTadd(nameOfProject);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; myProjectNode&nbsp;&nbsp;&nbsp;&nbsp; = myProjectNode.getRunNode();<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Add groupnode 'Tables'</span><br />
&nbsp;&nbsp;&nbsp; groupNodeName = <span style="color: rgb(255, 0, 0);">'Tables'</span>;<br />
&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp; if( !projectGroupNode)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTadd(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.projectGroupType(GroupNodeType::Tables);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Add some tables to groupnode 'Tables'</span><br />
&nbsp;&nbsp;&nbsp; if( !projectGroupNode.findGroupMember(<span style="color: rgb(255, 0, 0);">'SalesTable'</span>, UtilElementType::Table))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.addUtilNode(UtilElementType::Table, <span style="color: rgb(255, 0, 0);">'SalesTable'</span>);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; if( !projectGroupNode.findGroupMember(<span style="color: rgb(255, 0, 0);">'SalesLine'</span>, UtilElementType::Table))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.addUtilNode(UtilElementType::Table, <span style="color: rgb(255, 0, 0);">'SalesLine'</span>);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; projectGroupNode.AOTsave();<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Add groupnode 'Forms'</span><br />
&nbsp;&nbsp;&nbsp; groupNodeName = <span style="color: rgb(255, 0, 0);">'Forms'</span>;<br />
&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp; if( !projectGroupNode)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTadd(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode = myProjectNode.AOTfindChild(groupNodeName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.projectGroupType(GroupNodeType::Forms);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Add form 'SalesTable' to groupnode 'Forms'</span><br />
&nbsp;&nbsp;&nbsp; if( !projectGroupNode.findGroupMember(<span style="color: rgb(255, 0, 0);">'SalesTable'</span>, UtilElementType::Form))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; projectGroupNode.addUtilNode(UtilElementType::Form, <span style="color: rgb(255, 0, 0);">'SalesTable'</span>);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; projectGroupNode.AOTsave();<br />
<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTsave();<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTrefresh();<br />
&nbsp;&nbsp;&nbsp; myProjectNode.AOTrun();<br />
}
</div>

<p>Das&nbsp;im Beispiel&nbsp;erstellte Projekt s&auml;he wie folgt aus:
</p>

<p><img height="188" width="265" title="My Project" alt="my Project" src="http://www.schweda.net/pictures/blogpics/dax2009_myproject.jpg" />
</p>]]></content>
<published>2010-04-17T21:38:25Z</published>
<updated>2010-04-17T21:38:25Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=372"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-03-26:id371</id><title type="text">Zugriff auf die Zwischenablage per X++</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>In Dynamics AX kann man selbstverst&auml;ndlich auch auf die Zwischenablage zugreifen, ein kurzes Codebeispiel dazu im folgenden. Funktioniert &uuml;brigens zumindest seit Axpata 2.5.
</p>

<div style="padding: 5px; background-color: rgb(255, 255, 204); width: 460px; font-family: courier new,helvetica; white-space: nowrap; height: 150px; color: rgb(0, 0, 0); font-size: 12px; overflow: scroll;"><span style="color: rgb(0, 0, 255);">static void</span> useClipboard(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; textBuffer&nbsp; textBuffer = <span style="color: rgb(0, 0, 255);">new</span> textBuffer();<br />
&nbsp;&nbsp;&nbsp; ; &nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);"><br />
&nbsp;&nbsp;&nbsp; // Write to clipboard</span><br />
&nbsp;&nbsp;&nbsp; textBuffer.appendText(<span style="color: rgb(255, 0, 0);">'Hello world!'</span>);<br />
&nbsp;&nbsp;&nbsp; textBuffer.toClipboard();<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 102, 0);">// Read from clipboard</span><br />
&nbsp;&nbsp;&nbsp; textBuffer.fromClipboard();<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0, 0, 255);">info</span>(textBuffer.getText());<br />
}
</div>]]></content>
<published>2010-03-26T19:49:10Z</published>
<updated>2010-03-26T19:49:10Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=371"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-07-31:id370</id><title type="text">Palette verlagern per X++</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Folgend etwas X++ Code, mit dessen Hilfe man eine Palette verlagern kann, also genau das, was die Schaltfl&auml;che &quot;Palette verlagern&quot; in Formular Palette tut.
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 110px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">wmsPalletMove = <span style="color: rgb(0,0,255)">new</span> wmsPalletMove();<br />
wmsPalletMove.parmWMSPalletId(<span style="color: rgb(255,0,0)">'00000022_117'</span>);<br />
wmsPalletMove.parmToInventLocationId(<span style="color: rgb(255,0,0)">'300'</span>);<br />
wmsPalletMove.parmToLocationId(<span style="color: rgb(255,0,0)">'01'</span>);<br />
<span style="color: rgb(0,0,255)">if</span>(wmsPalletMove.validate())<br />
&nbsp;&nbsp; wmsPalletMove.run();
</div>

<p>&nbsp;
</p>]]></content>
<published>2010-07-31T18:11:11Z</published>
<updated>2010-07-31T18:11:11Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=370"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-03-19:id369</id><title type="text">Buchen von Lieferschein und Rechnung per Code</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Mit Hilfe der <strong>salesFormLetter</strong>-Klasse(n) von Dynamics AX ist es m&ouml;glich, Auftragsbest&auml;tigung, Lieferschein und/oder Rechnung f&uuml;r einen Auftrag mit nur wenigen Zeilen Code zu buchen. Nachstehend ein Beispiel, in dem f&uuml;r einen Auftrag alle drei auf einmal gebucht werden:
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 290px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px"><span style="color: rgb(0,0,255)">static void</span> postSalesFormLetter(Args _args)<br />
{<br />
&nbsp;&nbsp;&nbsp; SalesFormLetter salesFormLetter;<br />
&nbsp;&nbsp;&nbsp; salesTable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; salesTable = salesTable::find(<span style="color: rgb(255,0,0)">'01234'</span>);<br />
&nbsp;&nbsp;&nbsp; ; &nbsp;&nbsp;&nbsp; <span style="color: rgb(0,0,255)"><br />
<br />
&nbsp;&nbsp;&nbsp; ttsBegin</span>; <br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0,102,0)">// Best&auml;tigung buchen<br />
</span>&nbsp;&nbsp;&nbsp; salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);&nbsp;<br />
&nbsp;&nbsp;&nbsp; salesFormLetter.update( salesTable,<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; 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; SalesUpdate::All,<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; AccountOrder::None,<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; NoYes::No,<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; NoYes::No);&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0,102,0)">// Lieferschein buchen</span><br />
&nbsp;&nbsp;&nbsp; salesFormLetter = SalesFormLetter::construct(DocumentStatus::PackingSlip);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; salesFormLetter.update( salesTable,<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; 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; SalesUpdate::All,<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; AccountOrder::None,<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; NoYes::No,<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; NoYes::No); &nbsp;&nbsp;&nbsp;<br />
<span style="color: rgb(0,102,0)"><br />
&nbsp;&nbsp;&nbsp; // Rechnung buchen</span><span style="color: rgb(0,102,0)"><br />
</span>&nbsp;&nbsp;&nbsp; salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; salesFormLetter.update( salesTable,<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; 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; SalesUpdate::All,<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; AccountOrder::None,<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; NoYes::No,<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; NoYes::No);<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(0,0,255)">ttsCommit</span>;<br />
}
</div>

<p>Getestet in Dynamics AX 2009.
</p>]]></content>
<published>2010-03-19T23:28:24Z</published>
<updated>2010-03-19T23:28:24Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=369"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-02-04:id366</id><title type="text">Eintrag &quot;Einstellungen&quot; im Kontextmenü freischalten</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p style="text-align: left;"><img width="223" height="209" align="right" src="http://www.schweda.net/pictures/blogpics/ax2009_contextmenu_settings.jpg" alt="Kontextmen&uuml; von AX2009" style="border: 1px solid ; margin-bottom: 10px; margin-left: 10px;" />Jeder Entwickler kennt ihn und die meisten benutzen ihn auch regelm&auml;ssig: Den Eintrag &quot;Einstellungen&quot; im Kontextmen&uuml; eines Formulares.
</p>

<p>Wie man diesen Eintrag &uuml;ber die Berechtigungsverwaltung von Dynamics AX entfernt oder hinzuf&uuml;gt, wusste ich allerdings bis dato nicht. Erst ein Request beim Hersteller, den ein Kollege abgesetzt hat, hat mich auf die richtige Spur gebracht:
</p>

<p>Unter <strong>Sicherheit / Verwaltung / Sonstiges / Fomular &quot;Personalisierung&quot;</strong> muss man die Berechtigung auf mindestens &quot;Bearbeiten&quot; setzen, damit der Eintrag im Kontextmen&uuml; aufscheint.
</p>

<p>Und jetzt erkl&auml;r mir mal einer, wie man das selbst finden soll...
</p>]]></content>
<published>2010-02-04T21:00:35Z</published>
<updated>2010-02-04T21:00:35Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=366"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-01-19:id365</id><title type="text">Versenden einer Mail an alle Online-Benutzer in Dynamics AX 4.0 und AX 2009</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Folgende Schritte sind in Dynamics AX notwendig, um allen Online-Benutzern eine E-Mail zu senden:
</p>

<ol>
    
<li>Eintragen des zu verwendenden SMTP-Servers unter <strong>Verwaltung / Einstellungen / E-Mail-Parameter</strong>
</li>
    
<li>Erstellen eines E-Mail-Vorlage vom Typ System unter <strong>Grundeinstellungen / Einstellungen /&nbsp; E-Mail-Vorlage<br />
    </strong>Hier kann der Betreff und der Text der zu versendenden Mail um den Platzhalter %username% erweitert werden.
</li>
    
<li>Versenden der Mail unter <strong>Verwaltung / Periodisch / E-Mail-Aussendung</strong>
</li>

</ol>

<p>Man kann auch an alle Benutzer einer Installation versenden.
</p>

<p>F&uuml;r technisch Interessierte: Die verantwortliche Klasse ist die SysEmailBroadCast.
</p>]]></content>
<published>2010-01-19T09:20:33Z</published>
<updated>2010-01-19T09:20:33Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=365"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-02-11:id364</id><title type="text">Unterschied zwischen update und doUpdate u.ä.</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Mir pers&ouml;nlich dreht sich ja immer der Magen um, wenn ich in einer Produktivumgebung einen St&uuml;ckchen Code mit <em>doUpdate() </em>oder Konsorten entdecke, trotzdem verwende ich solcherart Methoden auch gerne f&uuml;r den einen oder anderen Aktualisierungsjob. Wer den Unterschied zwischen dem Aufruf von <em>update() </em>und <em>doUpdate()</em> nicht kennt, kann diesen in der MSDN nachlesen...oder aber auch in der nachstehenden Tabelle.
</p>

<table width="100%" cellspacing="1" cellpadding="1" border="0">
    <tbody>
        <tr>
            
<td valign="top"><strong>Methode</strong>
</td>
            
<td valign="top"><strong>Bemerkung</strong>
</td>
        </tr>
        <tr>
            
<td valign="top">insert vs. doInsert
</td>
            
<td valign="top">Bei Verwendung von doInsert wird die insert-Methode der Tabelle nicht aufgerufen
</td>
        </tr>
        <tr>
            
<td valign="top">delete vs. doDelete
</td>
            
<td valign="top">Bei Verwendung von doDelete wird eine &uuml;berschriebene delete-Methode der Tabelle nicht aufgerufen, sondern nur die delete-Methode des xRecord. D.h. DeleteActions werden dennoch ausgef&uuml;hrt
</td>
        </tr>
        <tr>
            
<td>update vs. doUpdate
</td>
            
<td>Bei Verwendung von doUpdate wird die update-Methode der Tabelle nicht aufgerufen
</td>
        </tr>
    </tbody>

</table>

<p>&nbsp;
</p>]]></content>
<published>2010-02-11T19:31:39Z</published>
<updated>2010-02-11T19:31:39Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=364"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-02-07:id363</id><title type="text">Erfahrungsbericht DVB-C-Receiver HDC-350</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Vor einiger Zeit wurde unser Kabelanschlu&szlig; um ein digitales Signal erweitert, als musste schnell ein digitaler HDTV-Kabelreceiver her. Auf Empfehlung unserer Genossenschaft (Sozialbau) wurden wir bei einem Wiener Unternehmen mit dem Kabelreceiver <strong>HDC-350</strong> f&uuml;ndig. Erstens war das Ger&auml;t mit knapp 100 EUR sehr g&uuml;nstig und stellte &uuml;ber einen USB-Anschlu&szlig; die M&ouml;glichkeit zur Verf&uuml;gung, einen USB-Speicher anzuschlie&szlig;en und den Receiver als Festplattenrekorder (PVR) zu verwenden.
</p>

<p>Leider ist es aber genau diese PVR-Funktion, die bei dem Ger&auml;t eher schlecht als recht funktioniert. Zum einen erkennt der USB-Anschlu&szlig; nur sehr wenige Ger&auml;te, eine Positiv- wie Negativ-Liste der von mir getesten Ger&auml;te findet ihr im folgenden, zum anderen hat das Ger&auml;t die eine oder andere Macke.
</p>


<p>Zum Beispiel kommt es immer wieder vor, da&szlig; einzelne Aufnahmen nicht mehr abspielbar sind. Diese Aufnahmen verhalten sich so, als w&uuml;rden sie direkt nach dem Start an deren Ende springen. Solche Aufnahmen kann man nur noch l&ouml;schen.
</p>

<p>Findet man aber einen USB-Speicher, der vom Receiver erkannt wird und sieht von den genannten Problemchen ab, funktioniert die Aufnahme dank EPG sehr gut.
</p>

<p>Solche Aufnahmen kann man &uuml;brigens mit der Software PC2Box am PC archivieren, dies ist aber eine Sache f&uuml;r sich. Ich bin sicherlich technisch nicht unerfahren, aber eine derart rudiment&auml;re Software zum Download anzubieten ist schon fast eine Gemeinheit. Der &quot;normale&quot; PC-User kann mit dieser vermutlich nichts anfangen.
</p>

<p>Aber es gibt nicht nur negatives von dem Receiver zu berichten. Das wichtigste ist bei einem solchen Ger&auml;t die Bildqualit&auml;t und die Bedienung. Leider fehlen mir hinsichtlich Bid- und Tonqualit&auml;t Vergleichsm&ouml;glichkeiten, das Bild ist auf jeden Fall besser als Analog ;-)
</p>

<p>Zum Ton bliebt zu erw&auml;hnen, da&szlig; das Ger&auml;t &uuml;ber einen optischen Ausgang verf&uuml;gt, wodurch man es z.B. leicht an ein Heimkinosystem anschlie&szlig;en kann. &Uuml;ber die Fernbedienung kann man rein theroetisch sogar unterschiedliche Tonspuren der jeweils ausgestrahlten Sendung anw&auml;hlen, seltsamerweise hat dies aber zumindest bei uns keinerlei Effekt. Ich kann aber nicht beurteilen ob das am Ger&auml;t liegt, oder an unserem Kabelsignal.
</p>

<p>Au&szlig;erdem liegt dem <strong>HDC-350 </strong>neben einer Fernbedienung auch ein sog. Fernbedienungsauge dabei, womit es m&ouml;glich ist den Receiver unsichtbar aufzustellen. Sehr praktisch!
</p>

<p>Alles in allem ist mein pers&ouml;nliches Fazit: Kleiner, recht g&uuml;nstiger HDTV-Kabelreceiver, mit dem mit etwas Gl&uuml;ck auch Aufnahmen gelingen.
</p>

<p><strong>Positivliste</strong>
</p>

<ul>
    
<li>Hitachi Travelstar 40 GB (DK13FA-40) USB-Festplatte 1,8&quot;
</li>
    
<li>Silvercrest USB-Stick 1 GB
</li>
    
<li>Super Talent USB-Stick 4 GB
</li>

</ul>

<p><strong>Negativliste</strong>
</p>

<ul>
    
<li>Sandisk Cruzer Micro USB-Stick 16 GB (U3-Software mit entsprechender Software entfernt)
</li>
    
<li>Samsung HM030GC 2,5&quot; Festplatte 30 GB
</li>

</ul>

<p>&Uuml;brigens: Nat&uuml;rlich habe ich mir erlaubt, beim Hersteller nachzufragen, welche Anforderungen an USB-Speicher gestellt werden, damit diese problemlos erkannt werden, leider blieben meine Mails bis dato unbeantwortet...
</p>]]></content>
<published>2010-02-07T13:49:45Z</published>
<updated>2010-02-07T13:49:45Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=363"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2009-12-07:id362</id><title type="text">Zertifizierungsprüfung Microsoft Dynamics AX 2009 Trade &amp; Logistics</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p><img width="120" height="59" align="right" src="http://www.schweda.net/pictures/blogpics/mcbmss_0709_simple_w120.jpg" alt="Microsoft Certified Business Management Solutions Specialist" style="padding: 10px 10px 14px;" />Kurzer Eintrag in eigener Sache:
</p>

<p>Heute morgen habe ich eine weitere Microsoft Zertifizierungspr&uuml;fung - der genaue Titel lautete <strong>Microsoft Dynamics AX 2009 Trade &amp; Logistics</strong> - erfolgreich abgelegt.
</p>]]></content>
<published>2009-12-07T20:44:49Z</published>
<updated>2009-12-07T20:44:49Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=362"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-03-04:id361</id><title type="text">Notizen zur RecId</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Die RecId ist die mehr oder weniger eindeutige Kennung eines Datensatzes in Dynamics AX. Mehr oder weniger deshalb, weil es auf die verwendete Version von Dynamics AX bzw. Axapta ankommt:
</p>

<table width="100%" cellspacing="1" cellpadding="1" border="0">
    <tbody>
        <tr>
            
<td valign="top"><strong>Version&nbsp; <br />
            </strong>
</td>
            
<td valign="top"><strong>Bemerkung</strong>
</td>
        </tr>
        <tr>
            
<td valign="top">3.0
</td>
            
<td valign="top">RecId pro Mandant eindeutig (&uuml;ber alle Tabellen)
</td>
        </tr>
        <tr>
            
<td valign="top">4.0
</td>
            
<td valign="top">RecId pro Tabelle eindeutig (&uuml;ber alle Mandanten) <br />
            D.h. die selbe RecId kann in zwei oder mehreren Tabellen vorkommen, das ist auch der Grund, warum ein Feld einer Tabelle vom Typ RefRecId als EDT mit einer Relation abgebildet werden muss!
</td>
        </tr>
        <tr>
            
<td valign="top">2009
</td>
            
<td valign="top">Wie&nbsp;bei Version&nbsp;4.0
</td>
        </tr>
    </tbody>

</table>

<p>&nbsp;
</p>]]></content>
<published>2010-03-04T19:37:22Z</published>
<updated>2010-03-04T19:37:22Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=361"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2009-12-04:id360</id><title type="text">PageFooter sind nicht immer dort, wo sie sein sollten</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Ich kenne kein einziges AX-Projekt, in dem nicht zumindest einer der Berichte Auftragsbest&auml;tigung, Ausgangslieferschein oder Ausgangsrechnung angepasst worden sind. Und deshalb stolpere ich auch immer wieder &uuml;ber das selbe Problem: Man erweitert einen Bericht (Report) um einen PageFooter, der aber nicht auf jeder Seite angedruckt werden soll.
</p>


<p>Die meisten Entwickler l&ouml;sen dies einfach &uuml;ber die zur Section geh&ouml;rige Methode <em>executeSection() </em>wobei sie den Aufruf <em>super() </em>ah&auml;nigig von irgendwelchen Kriterien ausf&uuml;hren oder nicht. Man findet z.B. solcherart Code des &ouml;fteren:
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 150px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">

<p>public void executeSection()<br />
{<br />
&nbsp;&nbsp;&nbsp; ;<br />
&nbsp;&nbsp;&nbsp; if (salesFormLetterReport.isFooterPresentForCurrentPrintSetting())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();<br />
&nbsp;&nbsp;&nbsp; }<br />
}
</p>

</div>

<p>Obiger Code ist z.B. aus dem PageFooter namens <em>FooterText </em>aus dem Report <em>SalesConfirm </em>(=Auftragsbest&auml;tigung). Hier ist das Ziel der Methode, den sog. Fusszeilentext in dieser Section immer nur dann anzudrucken, wenn dies in den Druckverwaltungseinstellungen f&uuml;r diesen Bericht (unter <strong>Debitoren / Einstellungen / Formulareinstellungen / Allgemeines / Druckverwaltung</strong>) entsprechend parametriert ist.
</p>

<p>Dynamics AX ist nun aber leider so dumm, da&szlig; es sich - obwohl hier vielleicht gar kein Text parametriert ist - dennoch am Bericht den entsprechenden Platz reserviert. D.h. beim Ausdrucken des entsprechenden Dokumentes &quot;rutschen&quot; evtl. andere PageFooter zu weit hinauf und man verliert wertvollen Platz f&uuml;r Auftragspositionen o.&auml;.
</p>

<p>Einfach umgehen kann man dieses Fehlverhalten &uuml;ber das deaktivieren der entsprechenden Section in der <em>fetch()</em>-Methode:
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 200px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">

<p>boolean&nbsp; fetch()<br />
{<br />
&nbsp;&nbsp;&nbsp; ...
</p>

<p>&nbsp;&nbsp;&nbsp; if ( !salesFormLetterReport.isFooterPresentForCurrentPrintSetting())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; element.disableSection(FooterText);&nbsp;// FooterText ist der Name der Section<br />
&nbsp;&nbsp;&nbsp; }
</p>

<p>&nbsp;&nbsp;&nbsp; ...<br />
}
</p>

</div>

<p>Es gibt nat&uuml;rlich auch noch andere Wege. Beispielsweise k&ouml;nnte man die H&ouml;he der ganzen Section &uuml;ber
</p>

<div style="padding-bottom: 5px; background-color: rgb(255,255,204); padding-left: 5px; width: 460px; padding-right: 5px; font-family: courier new,helvetica; white-space: nowrap; height: 50px; color: rgb(0,0,0); font-size: 12px; overflow: scroll; padding-top: 5px">

<p>FooterText.height(0, units::mm);
</p>

</div>

<p>zur&uuml;cksetzen. Es kommt immer auf die jeweilige Anforderung und den Aufbau des Reports an, f&uuml;r welche Variante man sich entscheidet.
</p>

<p>Wichtig ist nur, immer <em>super() </em>in der <em>exceuteSection() </em>aufrufen!
</p>]]></content>
<published>2009-12-04T17:34:56Z</published>
<updated>2009-12-04T17:34:56Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=360"  rel="alternate" />
</entry>
<entry>
<id>tag:schweda.net,2010-02-25:id358</id><title type="text">startUpCmd=compileAll</title>
<author><name>Heinz Schweda</name></author>
<content type="html"><![CDATA[
<p>Mit Hilfe dieses Parameters von Dynamics AX ist es m&ouml;glich, eine vollst&auml;ndige Kompilierung der Applikation zu initieren. Dabei sind folgende drei Varainten verf&uuml;gbar:
</p>

<p>1.) Kompiliert die Applikation und aktualisiert - soferne dies in den Benutzeroptionen so festgelegt ist - auch die Querverweise
</p>

<blockquote>

<p>&quot;C:\Programme\Microsoft Dynamics AX\50\Client\Bin\Ax32.exe&quot;<br />
-startUpCmd=compileAll
</p>

</blockquote>

<p>2.) Kompilieren der Applikation inkl. Aktualisierung der Querverweise
</p>

<blockquote>

<p>&quot;C:\Programme\Microsoft Dynamics AX\50\Client\Bin\Ax32.exe&quot;<br />
-startUpCmd==compileAll_+
</p>

</blockquote>

<p>3.) Kompiliert die Applikation ohne die Querverweise zu aktualisieren
</p>

<blockquote>

<p>&quot;C:\Programme\Microsoft Dynamics AX\50\Client\Bin\Ax32.exe&quot;<br />
-startUpCmd==compileAll_-
</p>

</blockquote>

<p>In allen drei F&auml;llen wird &uuml;brigens - zumindest in AX 2009 - eine Level 4-Kompilierung initiert, d.h. die Applikation wird auch hinsichtlich Best-Practice-Abweichungen gepr&uuml;ft.
</p>

<p>Das Ergebnis der Kompilierung ist anschlie&szlig;end in der Datei <em>AxCompileAll.html </em>im Log-Verzeichnis des Clients zu finden.
</p>]]></content>
<published>2010-02-25T21:37:42Z</published>
<updated>2010-02-25T21:37:42Z</updated>
<link href="http://www.schweda.net/blog_atom.php" rel="self" />
<link href="http://www.schweda.net/blog.php?bid=358"  rel="alternate" />
</entry>

</feed>	


