<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Issues concerning X++</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/x/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/x/feed.xml</link>
    <description>This blog deals with issues about X++</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:34:41 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Dynamics Ax and the Internet of Things.</title>
      <link>https://docs.microsoft.com/archive/blogs/x/dynamics-ax-and-the-internet-of-things</link>
      <pubDate>Sat, 21 Feb 2015 13:38:21 GMT</pubDate>
      <dc:creator><![CDATA[Peter Villadsen]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2015/02/21/dynamics-ax-and-the-internet-of-things/</guid>
      <description><![CDATA[At the last technical conference, I ended by showing a little system that was designed to show the...]]></description>
      <content:encoded><![CDATA[<p>At the last technical conference, I ended by showing a little system that was designed to show the ease with which you can interface to modern IoT (Internet of Things) hardware directly from Dynamics Ax. I will go in a little more detail here than was possible in that short demo.</p>  <p>The demo featured a chip called the Spark Core (<a href="https://www.spark.io/">https://www.spark.io/</a>). This remarkable chip contains a micro controller like the one found in the Arduino, coupled with some very important extras: One is a WiFi chip directly built into the chip, and the other is infrastructure in the cloud that allows some very interesting scenarios. In addition, the chip has several digital input / output pins (that can be used to turn things on or off, or to sense things in the world surrounding it), and analog pins, that can measure a voltage.</p>  <p>In the demo I showed a thermometer implementation where a DHT11 (<a title="http://www.adafruit.com/products/386" href="http://www.adafruit.com/products/386">http://www.adafruit.com/products/386</a>) chip is used to measure temperature and relative humidity. This chip is a little tricky to interface to the spark, but there are several other sensors that are quite a bit easier to deal with (typically simply providing an analog voltage that can be measured with the spark's analog data pins: One example is the LM35 chip&#160; (http://www.ti.com/product/lm35)). I wired up the D4 data pin to the DHT11, and put in some code (in C++) that gets the data. The code is maintained (edited, compiled and stored) entirely in the cloud: No complicated tool chain is needed on your own box. When the code is compiled successfully, it may be flashed onto the chip over the air (i.e. through the wireless connection). From that point on, it will run this code from until it is switched off. Since the code is downloaded into ROM, it will start right up after being turned on again.</p>  <p>The driver part of the code I used is enclosed. In the true spirit of the maker movement, I downloaded the library that takes care of the details of talking to the DHT11 from the web from here: <a title="https://github.com/adafruit/DHT-sensor-library" href="https://github.com/adafruit/DHT-sensor-library">https://github.com/adafruit/DHT-sensor-library</a>. I show the main part of the code for reference below:</p> <span style="font-family: courier new,courier; color: #003300">// Use the D4 pin and use the DHT11 chip    <br />DHT dht(D4, DHT11);     <br />    <br />// Define variables to query from outside     <br />double humidity, temperature, heatIndex;     <br />    <br />void setup()     <br />{     <br />&#160;&#160;&#160; // Initialize serial output     <br />&#160;&#160;&#160; Serial.begin(9600);&#160; <br />    <br />&#160;&#160;&#160; // Set up the variables     <br />&#160;&#160;&#160; Spark.variable(&quot;temperature&quot;, &amp;temperature, DOUBLE);     <br />&#160;&#160;&#160; Spark.variable(&quot;humidity&quot;, &amp;humidity, DOUBLE);     <br />&#160;&#160;&#160; Spark.variable(&quot;heatindex&quot;, &amp;heatIndex, DOUBLE);     <br />    <br />&#160;&#160;&#160; // Initialize the chip     <br />&#160;&#160;&#160; dht.begin();     <br />}     <br />    <br />void loop()     <br />{     <br />&#160;&#160;&#160; // Wait a few seconds between measurements.     <br />&#160;&#160;&#160; delay(2000);     <br />    <br />&#160;&#160;&#160; // Reading temperature or humidity takes about 250 milliseconds!     <br />&#160;&#160;&#160; // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)     <br />&#160;&#160;&#160; float h = dht.readHumidity();     <br />    <br />&#160;&#160;&#160; // Read temperature as Celsius     <br />&#160;&#160;&#160; float t = dht.readTemperature();     <br />    <br />&#160;&#160;&#160; // Read temperature as Fahrenheit     <br />&#160;&#160;&#160; float f = dht.readTemperature(true);     <br />    <br />&#160;&#160;&#160; humidity = h;     <br />&#160;&#160;&#160; temperature = t;     <br />    <br />&#160;&#160;&#160; // Check if any reads failed and exit early (to try again).     <br />&#160;&#160;&#160; // Compute heat index     <br />&#160;&#160;&#160; // Must send in temp in Fahrenheit!     <br />&#160;&#160;&#160; float hi = dht.computeHeatIndex(f, h);     <br />&#160;&#160;&#160; heatIndex = hi;     <br />&#160;&#160;&#160; Serial.print(&quot;Humidity: &quot;);     <br />&#160;&#160;&#160; Serial.print(h);     <br />&#160;&#160;&#160; Serial.print(&quot; %\t&quot;);     <br />&#160;&#160;&#160; Serial.print(&quot;Temperature: &quot;);     <br />&#160;&#160;&#160; Serial.print(t);     <br />&#160;&#160;&#160; Serial.print(&quot; *C &quot;);     <br />&#160;&#160;&#160; Serial.print(f);     <br />&#160;&#160;&#160; Serial.print(&quot; *F\t&quot;);     <br />&#160;&#160;&#160; Serial.print(&quot;Heat index: &quot;);     <br />&#160;&#160;&#160; Serial.print(hi);     <br />&#160;&#160;&#160; Serial.println(&quot; *F&quot;);     <br />} </span>  <p>To aid debugging (which is otherwise difficult) I added a serial connection to my laptop and installed a USB to serial converted. I use putty (<a href="http://www.putty.org/">http://www.putty.org/</a>) to maintain the connection to the chip, and to show the debug output.</p>  <p>When it is running the chip communicates with a service that the chip manufacturer runs (and you can now run it locally if you wish). The communication is initiated by the chip. Whenever a consumer needs to access the data it does so by asking the service in the cloud – No consumer has any idea on which IP address the chip is located. This means that there are no problems with NATs, or using home networks where the IP address may change unpredictably etc. The experience is very smooth, and safe, since all communication is secured. This is the value of the infrastructure provided by more and more providers.</p>  <p>Let’s get back to the code: When the code is running, the values measured are available in some variables: temperature, humidity and heatIndex. Since these are set up as variables in the code below:</p>  <p>Spark.variable(&quot;temperature&quot;, &amp;temperature, DOUBLE);    <br />Spark.variable(&quot;humidity&quot;, &amp;humidity, DOUBLE);     <br />Spark.variable(&quot;heatindex&quot;, &amp;heatIndex, DOUBLE);</p>  <p>They are available to be read at any time from interested code from anywhere on the internet by making simple calls where the URL contains the name of the required variable. The resulting JSON payload will contain the value. It is that simple. There are other possibilities as well: You can ask to have a function executed, and you can ask for the values of all variables at once, but the results are invariantly returned as a JSON document:</p> <span style="font-family: courier new,courier; color: #003300">{    <br />&#160;&#160;&#160; &quot;cmd&quot;: &quot;VarReturn&quot;,     <br />&#160;&#160;&#160; &quot;name&quot;: &quot;temperature&quot;,     <br />&#160;&#160;&#160; &quot;result&quot;: 22,     <br />&#160;&#160;&#160; &quot;coreInfo&quot;: {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;last_app&quot;: &quot;&quot;,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;last_heard&quot;: &quot;2015-02-21T06:14:10.220Z&quot;,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;connected&quot;: true,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;deviceID&quot;: &quot;&lt;omitted&gt;&quot;     <br />&#160;&#160;&#160; }     <br />}     <br /></span>  <p>Let me show some code that does this in X++: </p>  <p><span style="font-family: courier new,courier; color: #003300">{      <br />&#160;&#160;&#160; str sparkCoreName = &quot;<omitted>&quot;;       <br />&#160;&#160;&#160; str accessToken = &quot;<omitted>&quot;;       <br />&#160;&#160;&#160; str variableName = &quot;temperature&quot;;       <br />&#160;&#160;&#160; TextBuffer tb = new TextBuffer();       <br />&#160;&#160;&#160; str values, temp;       <br />&#160;&#160;&#160; int digits;       <br />&#160;&#160;&#160; int ptr;       <br />&#160;&#160;&#160; real rr;       <br />&#160;&#160;&#160; System.Net.WebClient webclient;       <br />&#160;&#160;&#160; str uri;       <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; boolean IsDigit(str s1)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160; return s1 &gt;= &quot;0&quot; &amp;&amp; s1 &lt;= '9';       <br />&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; webclient = new System.Net.WebClient();       <br />&#160;&#160;&#160; uri = strfmt(“<a href="https://api.spark.io/v1/devices/%1/%2?access_token=%3">https://api.spark.io/v1/devices/%1/%2?access_token=%3</a>”,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="font-family: courier new,courier; color: #003300">sparkCoreName, variableName, accessToken);      <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; // Get the value from the server given the URL.       <br />&#160;&#160;&#160; values = webclient.DownloadString(uri);       <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; // Find the result value from the JSON       <br />&#160;&#160;&#160; ptr = strScan(values, '&quot;result&quot;: ', 1, strLen(values));       <br />&#160;&#160;&#160; ptr += strLen('&quot;result&quot;: ');       <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; // now read while we are looking at digits.       <br />&#160;&#160;&#160; digits = 0;       <br />&#160;&#160;&#160; while(IsDigit(subStr(values, ptr + digits, 1)))       <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; digits += 1;       <br />&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; rr = str2num(subStr(values, ptr, digits));&#160; <br />&#160;&#160;&#160; info( values);       <br />}       <br /></span></p>  <p>This code is not brilliant by any means, but it works. In production code I would use a JSON library to parse the JSON document, and access the payload data (the result field), but for this demo I did not bother. Note that I have omitted the values that identify your spark chip from the code above.</p>  <p>In the demo I wanted a little more pizzazz so I integrated it with a gauge control on a form. I will leave this as an exercise to the reader…</p>]]></content:encoded>
    </item>
    <item>
      <title>Using EDT array elements from Proxies or from the .NET Business Connector for AX</title>
      <link>https://docs.microsoft.com/archive/blogs/x/using-edt-array-elements-from-proxies-or-from-the-net-business-connector-for-ax</link>
      <pubDate>Fri, 06 Dec 2013 14:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Gene-FID]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2013/12/06/using-edt-array-elements-from-proxies-or-from-the-net-business-connector-for-ax/</guid>
      <description><![CDATA[by Peter VilladsenDecember 2013
&nbsp;
The Microsoft Dynamics AX 2012 system allows an individual...]]></description>
      <content:encoded><![CDATA[<p>by Peter Villadsen<br />December 2013</p>
<p>&nbsp;</p>
<p>The Microsoft Dynamics AX 2012 system allows an individual table field, in any one record, to contain multiple values. Typically this is done by creating an extended data type (EDT) that is an array type, and then using the EDT as the type for a field in a table. The most well-known case is the Dimension field of the EDT named Dimension. The Dimension type is shown in the AOT image, along with its array elements.</p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/7103.Dimension-EDT-ArrayElements-gm2.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/7103.Dimension_2D00_EDT_2D00_ArrayElements_2D00_gm2.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/7103.Dimension-EDT-ArrayElements-gm2.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/343x231/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/7103.Dimension_2D00_EDT_2D00_ArrayElements_2D00_gm2.PNG" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>This is a flexible and dynamic feature. As soon as the user adds a new element to the Dimension type&rsquo;s list of array elements, everything immediately lights up with the new dimension everywhere the type is used.</p>
<p>&nbsp;</p>
<p><span style="color: #339966;"><strong><span style="font-size: medium;">1.&nbsp;&nbsp;X++ Support</span></strong></span></p>
<p>The X++ language supports these array fields without problems. Let us imagine that the table called PVsTable has a field called DimensionField of type Dimension. The following are legal X++ code snippets:&nbsp;</p>
<table frame="border" cellpadding="4">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier; font-size: small;">// X++, code example 1.</span><br /><span style="color: #000080; font-family: courier new,courier; font-size: small;">PVsTable t;&nbsp; // PVsTable has one field, named DimensionField, of type Dimension.</span></p>
<p><span style="color: #000080; font-family: courier new,courier; font-size: small;">Select DimensionField&nbsp;&nbsp;&nbsp; from t;&nbsp; // Select all array elements in DimensionField.</span><br /><span style="color: #000080; font-family: courier new,courier; font-size: small;">Select DimensionField[2] from t;&nbsp; // Select the array element indicated by the index 2.</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;&nbsp;&nbsp;The first select statement selects all the array elements of the DimensionField, while the second fetches only the array element for index 2. In all code, values of type Dimension are indexable by an integer value.</p>
<p>&nbsp;</p>
<p><span style="color: #339966; font-size: medium;"><strong>2.&nbsp;&nbsp;Business Connector: Challenge and Trick</strong></span></p>
<p>There is no API that enables you to get the value of an individual array element from the DimensionField field through the .NET Business Connector of AX. Instead, you use a little trick to get individual elements. Let&rsquo;s set the stage with a little sample C# code:</p>
<table frame="box" cellpadding="3">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier;">Axapta ax = new Axapta();&nbsp; // C#, code example 2.</span><br />&nbsp;<br /><span style="color: #000080; font-family: courier new,courier;">ax.Logon("", "", "", "");</span><br />&nbsp;<br /><span style="color: #000080; font-family: courier new,courier;">using (AxaptaRecord rec = ax.CreateAxaptaRecord("PVsTable"))</span><br /><span style="color: #000080; font-family: courier new,courier;">{</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Execute the query on the table.</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; rec.ExecuteStmt("select firstonly * from %1"); // All indexes are fetched.</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // This call does not return an array! Returns first element only.</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; var f1 = rec.get_Field("DimensionField") as string;</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // This call returns the correct value for index 2</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; var f2 = rec.get_Field("DimensionField[2]") as string;</span><br /><span style="color: #000080; font-family: courier new,courier;">}</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">ax.Logoff();</span></p>
</td>
</tr>
</tbody>
</table>
<p>As you can see above, the get_Field method on the record does not actually get the array of values, but merely the first value in the array; which is at index 1. It can certainly be questioned whether this is a reasonable choice or not, but that is the behavior in place since the very first versions of the business connector.</p>
<p>&nbsp;</p>
<p><span style="color: #339966; font-size: medium;"><strong>3.&nbsp;&nbsp;Access any Individual Element</strong></span></p>
<p>If you want to access individual elements, you have to append the index you want by using a syntax borrowed from array indexing:</p>
<table frame="box" cellpadding="3">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier;">var f2 = rec.get_Field("DimensionField[2]") as string;&nbsp;&nbsp;&nbsp; // C#, code snippet 3.</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #339966; font-size: medium;"><strong>4.&nbsp;&nbsp;Proxies</strong></span></p>
<p>A proxy is a C# class which represents an AX object such as a class or table.&nbsp; The AX plug-in for Visual Studio generates the proxy code when you drag a class or table from the Application Explorer onto your project in the Solution Explorer. Your project must first be added in MorphX under AOT &gt; Visual Studio Projects. The proxies are updated whenever a change is detected in the AX object's schema.</p>
<p>A proxy enables your C# program to interact seamlessly with its corresponding AX object. Internally the proxy uses the .NET Business Connector for AX. You can see the code for a proxy by placing the cursor on an AX object and pressing F12 (or by selecting Go To Definition). You would see proxy code similar to the following:</p>
<table frame="box" cellpadding="3">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier;">public partial class PVsTable : Common {&nbsp; // C#, code example 4.</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; static string cTableName = "PVsTable";</span></p>
<p><span style="color: #808080;"><em><span style="font-family: courier new,courier;">// &hellip; code omitted for brevity &hellip;</span></em></span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// Dimension</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [ColumnAttribute()]</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; public virtual string DimensionField {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ((string)(this.get_Field("DimensionField")));</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField", value);</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.OnPropertyChanged("DimensionField");</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((DimensionFieldChanged != null)) {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.DimensionFieldChanged(this,</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new System.ComponentModel.PropertyChangedEventArgs</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ("DimensionField"));</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p>The proxy uses the business connector to talk to AX, by using the API that we investigated above. As you can see we are always relying on returning and setting the simple value, namely the first value. There are no provisions for getting the complete array, or even for explicitly identifying any individual array element of the DimensionField field. This is obviously unfortunate, since it hurts the C# interoperability story. However, all is not lost.</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong><span style="color: #339966;">5.&nbsp;&nbsp;Add Your Own Partial Class File to Extend the Proxy</span></strong></span></p>
<p>The proxy class is declared as partial. Therefore you can add extensions by using your own partial class in the same project. In your added partial class, you add your own properties that access the DimensionField elements. There are at least two ways to accomplish this:</p>
<ul>
<li>Add a property that returns the array</li>
<li>Add properties for the individual array elements</li>
</ul>
<p>Below we show examples for both of these approaches.</p>
<p>&nbsp;</p>
<p><strong><span style="color: #339966;"><em>5.1&nbsp;&nbsp;Fetch an Array of All Elements</em></span></strong></p>
<p>In the following C# code example, a string array of all the elements in the DimensionField field is fetched in one call:</p>
<p>&nbsp;</p>
<table frame="box" cellpadding="3">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier;">public partial class PVsTable : Common {&nbsp; // C#, code example 5.</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; static string cTableName = "PVsTable";</span></p>
<p><span style="color: #808080;"><em><span style="font-family: courier new,courier;">// &hellip; code omitted for brevity &hellip;</span></em></span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// Dimension</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [ColumnAttribute()]</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [SuppressMessage("Microsoft.Design",</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "CA1062:ValidateArgumentsOfPublicMethods")]</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; public virtual string[] DimensionFieldArray {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new string[] {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (string)(this.get_Field("DimensionField[2]")),</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (string)(this.get_Field("DimensionField[3]")),</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (string)(this.get_Field("DimensionField[4]")),</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (string)(this.get_Field("DimensionField[5]")) </span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set {</span><br /><em><span style="color: #808080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // error diagnosis omitted for clarity&hellip;<br /></span></em><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField[2]", value[0]);</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField[3]", value[1]);</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField[4]", value[2]);</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField[5]", value[3]);</span><br />&nbsp;<br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.OnPropertyChanged("DimensionField");</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((DimensionFieldChanged != null)) {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.DimensionFieldChanged(this,</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new System.ComponentModel.PropertyChangedEventArgs</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ("DimensionField"));</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><em><span style="color: #339966; font-size: small;"><strong>5.2&nbsp;&nbsp;Fetch an Individual Element&nbsp;</strong></span></em></p>
<p>The other option is to get the individual elements by using explicit index values:</p>
<p>&nbsp;</p>
<table frame="box" cellpadding="3">
<tbody>
<tr>
<td>
<p><span style="color: #000080; font-family: courier new,courier;">public partial class PVsTable : Common {&nbsp; // C#, code example 6.</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; static string cTableName = "PVsTable";</span></p>
<p><span style="color: #808080;"><em><span style="font-family: courier new,courier;">// &hellip; code omitted for brevity &hellip;</span></em></span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// Dimension</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [ColumnAttribute()]</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; [SuppressMessage("Microsoft.Design",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "CA1062:ValidateArgumentsOfPublicMethods")]<br />&nbsp;&nbsp;&nbsp; public virtual string[] CostCenter {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new string[] {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (string)(this.get_Field("DimensionField[2]")),</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set {</span><br /><span style="color: #808080;"><em><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &hellip; error diagnosis omitted for clarity&hellip;</span></em></span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.set_Field("DimensionField[2]", value[0]);</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.OnPropertyChanged("DimensionField");</span></p>
<p><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((DimensionFieldChanged != null)) {</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.DimensionFieldChanged(this,</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new System.ComponentModel.PropertyChangedEventArgs</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ("DimensionField"));</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="color: #000080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p><em><span style="color: #808080; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // &hellip; And so on for Purpose, Project Type, and Project Group &hellip;</span></em><br /><span style="color: #000080; font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;You could even add a little value by using the names of the array elements to reference them in the DimensionField field.</p>
<p>&nbsp;</p>
<p>&nbsp;<span style="color: #888888; font-size: x-small;"><em>//End.</em></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Mathematical modeling for powerful ERP</title>
      <link>https://docs.microsoft.com/archive/blogs/x/mathematical-modeling-for-powerful-erp</link>
      <pubDate>Tue, 12 Nov 2013 14:22:00 GMT</pubDate>
      <dc:creator><![CDATA[Gene-FID]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2013/11/12/mathematical-modeling-for-powerful-erp/</guid>
      <description><![CDATA[by Peter VilladsenNovember 2013
In an area known as Operational Research (O.R.), there are many...]]></description>
      <content:encoded><![CDATA[<p>by Peter Villadsen<br />November 2013</p>
<p>In an area known as Operational Research (O.R.), there are many problems and solutions that are applicable to enterprise resource planning (ERP). O.R. began at the end of World War II. Initially it was used to solve logistical problems, and it has expanded to address a broad spectrum of problems. One area of progress for O.R. concerns problems that involve so many possible combinations as potential answers that they cannot be solved by brute force calculation.</p>
<p>This essay helps you to:</p>
<ul>
<li>Recognize the types of problems that O.R. can solve; and</li>
<li>Understand the C# code that you can write to leverage O.R.</li>
</ul>
<p>The basic installation of Microsoft Dynamics AX 2012 includes a .NET managed library that is extremely well suited for solving the problems in the O.R. domain. Use of the library requires no extra expenses, no extra licenses to accept, and no extra installation steps. The library is called the Microsoft Solver Foundation (MSF). It is not too difficult to negotiate the learning curve, and the results it can provide will impress you.</p>
<p><span style="font-size: large;"><strong><span style="color: #000080;">1&nbsp;&nbsp;The simple transportation problem</span></strong></span></p>
<p>We start the discussion with a very simple problem called the transportation problem. There are a set of producers of beer, and there are a set of consumers of beer. The producers have a production capacity in units of crates per day. The consumers demand a certain amount of beer. There is a cost to transporting the beer from the producers to the consumers. The objective is to arrange the shipping such that the cost is minimized, while still satisfying the demands of consumers and not exceeding the capacity of the producers.</p>
<p>Let&rsquo;s take a minute to write these rules a little more formally:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/0741.Forumulas-a1.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/0741.Forumulas_2D00_a1.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/0741.Forumulas-a1.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/400x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/0741.Forumulas_2D00_a1.PNG" alt="" border="0" /></a></p>
<p>&nbsp;Where:</p>
<ul>
<li>cost<sub>i,j</sub> &mdash; is the (non-negative) cost of transporting one item from i to j; and</li>
<li>x<sub>i,j</sub> &mdash; is the number of items to move from i to j; and</li>
<li>demand<sub>j</sub> &mdash; is the demand at consuming site j; and</li>
<li>capacity<sub>i</sub> &mdash; is the capacity of producing site i.</li>
</ul>
<p>The result that we are looking for is the matrix x<sub>i,j</sub> , which is the number of crates to move from producer i to consumer j.</p>
<p><span style="color: #3366ff;"><strong><span style="font-size: medium;">1.1&nbsp;&nbsp;OML code model to describe the problem</span></strong></span></p>
<p>The MSF library allows you to express the problems you want to solve in a declarative language called Optimization Modeling Language (OML). I stress the point that scripts in this language do not tell the computer how to solve the problem. Instead, OML merely describes the problem to solve. Let&rsquo;s look at the preceding transportation problem as expressed in OML:</p>
<p><span style="color: #003300; font-family: courier new,courier;">Model[<br />&nbsp;&nbsp;&nbsp;&nbsp;Parameters[Sets,Producers,Consumers],<br />&nbsp;&nbsp;&nbsp;&nbsp;Parameters[Reals[0,Infinity],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Capacity[Producers],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Demand[Consumers],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cost[Producers,Consumers]],<br />&nbsp;&nbsp;&nbsp;&nbsp;Decisions[Reals[0,Infinity],x[Producers,Consumers],TotalCost],<br />&nbsp;&nbsp;&nbsp;&nbsp;Constraints[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TotalCost == Sum[{i,Producers},{j,Consumers},Cost[i,j]*x[i,j]],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foreach[{i,Producers}, Sum[{j,Consumers},x[i,j]]</span></p>
<p><span style="color: #003300; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foreach[{j,Consumers}, Sum[{i,Producers},x[i,j]]&gt;=Demand[j]]<br />&nbsp;&nbsp;&nbsp;&nbsp;],<br />&nbsp;&nbsp;&nbsp;&nbsp;Goals[Minimize[TotalCost]]<br />]<br /></span></p>
<p>If you compare the OML to the original problem formulation in mathematical notation, you will find many similarities. The results we are looking for are the decisions. The input parameters for the model are the costs, demands, and capacities. The constraints describe what the solution must satisfy. The goal states that we wish to minimize the total cost.</p>
<p><span style="color: #3366ff; font-size: medium;"><strong>1.2&nbsp;&nbsp;Paste the OML code as a string in C#</strong></span></p>
<p>A C# method to load this model would look something like:</p>
<p><span style="color: #003300; font-family: courier new,courier;"> public class TransportationModel&nbsp;&nbsp;&nbsp;// C#<br /> {<br /> &nbsp;&nbsp;&nbsp;&nbsp;/// <br /> &nbsp;&nbsp;&nbsp;&nbsp;/// Create model by adding decisions, constraints and goals. This version works by <br /> &nbsp;&nbsp;&nbsp;&nbsp;/// passing the OML model (as a string) to the LoadModel method that will then <br /> &nbsp;&nbsp;&nbsp;&nbsp;/// create the model. The data is bound to the model thereafter.<br /> &nbsp;&nbsp;&nbsp;&nbsp;/// <br /> &nbsp;&nbsp;&nbsp;&nbsp;///The solver context from which the model is created.<br /> &nbsp;&nbsp;&nbsp;&nbsp;/// The model, ready for solving after data binding.<br /> &nbsp;&nbsp;&nbsp;&nbsp;public Model CreateModelFromOML(SolverContext context)<br /> &nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string modelSource = @" <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Model[<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters[Sets,Plants,Markets],<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parameters[Reals,Capacity[Plants],Demand[Markets],Cost[Plants,Markets]],<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decisions[Reals[0,Infinity],x[Plants,Markets],TotalCost],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constraints[<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TotalCost == Sum[{i,Plants},{j,Markets},Cost[i,j]*x[i,j]],<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foreach[{i,Plants}, Sum[Foreach[{j,Markets},x[i,j]]],<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foreach[{j,Markets}, Sum[{i,Plants},x[i,j]]&gt;=Demand[j]] // Shorthand form.<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;Goals[Minimize[TotalTransportationCost -&gt; TotalCost]]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]";<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.LoadModel(FileFormat.OML, new StringReader(modelSource));<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return context.CurrentModel;<br /> &nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;...<br />}<br /> </span></p>
<p>You will need to add a reference to the <strong>Microsoft.Solver.Foundation.dll</strong>, typically found in the &hellip;\Client\bin directory.</p>
<p>Before we continue discussing the solver and its context parameter, let&rsquo;s mention data binding. You see no data binding in the CreateModelFromOML method. In other words, there is no declaration of the costs, demands, and capacities. We see that the OML model defines only the model of the problem, and that the OML does not define the data. We need another way to provide data.</p>
<p><span style="color: #3366ff;"><strong><span style="font-size: medium;">1.3&nbsp; Data binding for the OML model</span></strong></span></p>
<p>First, here is how we would call the preceding CreateModelFromOML method:</p>
<p><span style="color: #003300; font-family: courier new,courier;"> namespace TransportationDemoSupport<br /> {<br /> &nbsp;&nbsp;&nbsp;&nbsp;using Microsoft.SolverFoundation.Services;<br /> &nbsp;&nbsp;&nbsp;&nbsp;using Microsoft.SolverFoundation.Common;<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;class Program<br /> &nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var tp = new TransportationModel();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SolverContext context = new SolverContext();<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Model model = tp.CreateModelFromOML(context);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (model != null)<br /> &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;tp.DataBind(model);<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var solution = context.Solve();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var report = solution.GetReport(ReportVerbosity.All);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;}<br /> } </span></p>
<p><span style="line-height: 107%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;">Next we must write the DataBind method. We must provide values for the parameters, so let&rsquo;s start by retrieving the values from the model we defined in OML:</span></p>
<pre><span style="color: #003300; font-family: courier new,courier;">public Model DataBind(Model model)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;var demandParameter = model.Parameters.Where(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Demand")).First();<br />&nbsp;&nbsp;&nbsp;&nbsp;var capacityParameter = model.Parameters.Where(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Capacity")).First();<br />&nbsp;&nbsp;&nbsp;&nbsp;var costParameter = model.Parameters.Where(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Cost")).First();<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;... // Code inside this method continues below.<br /> }<br /> </span></pre>
<p>Obviously &ldquo;Demand&rdquo;, &ldquo;Capacity&rdquo;, and &ldquo;Cost&rdquo; are the names used in the model. But so far there is no data associated with these names.</p>
<p>Next in this DataBind method we must call the SetBinding method on the parameters to set their values. There are many overloads for this method, so there are many choices on how to provide the values. We start the discussion with a simple example using anonymous types:</p>
<p><span style="color: #003300; font-family: courier new,courier;">public Model DataBind(Model model)</span><br /><span style="color: #003300; font-family: courier new,courier;"> {</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;... // Code inside this method continues from above.</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;capacityParameter.SetBinding(new[] { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new { supply = 200.0, name = "Chicago" }, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new { supply = 30.0, name = "New York" } }, "supply", "name");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;demandParameter.SetBinding(new[] { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new { demand = 50.0, name = "Philadelphia" } }, "demand", "name");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;costParameter.SetBinding(new[] { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new {distance=200.0, producer="Chicago", consumer="Philadelphia"}, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new {distance=300.0, producer="New York", consumer="Philadelphia"},</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, "distance", "producer", "consumer");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;return model;</span><br /><span style="color: #003300; font-family: courier new,courier;"> }</span></p>
<p>In the calls to the SetBinding method for the capacity and demand parameters, we are using anonymous types to express sequences of objects which each contain two named values (&lsquo;supply, name&rsquo;, and &lsquo;demand, name&rsquo;). The framework will use reflection calls to these bi-value objects to get the values.&nbsp;</p>
<p>The costParameter is a little more complicated. It is a sequence of tri-value objects. Each object captures the locations for a producer and consumer, plus the distance between the two locations. The sample data are a little contrived for simplicity.</p>
<p><strong><span style="color: #3366ff; font-size: medium;">1.4&nbsp; Report the solution</span></strong></p>
<p>In the preceding Main method, the call to get a report is:</p>
<p><span style="color: #003300; font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;var report =&nbsp; solution.GetReport(ReportVerbosity.All);</span></p>
<p>The call produces a report in plain text which displays solution. A copy of the report is pasted in next (after I removed a few pieces of uninteresting data for clarity).</p>
<p><span style="color: #333300; font-family: courier new,courier;">===Solver Foundation Service Report===</span><br /><span style="color: #333300; font-family: courier new,courier;"> Version: Microsoft Solver Foundation 3.0.2.10919 Enterprise Edition</span><br /><span style="color: #333300; font-family: courier new,courier;"> Model Name: DefaultModel</span><br /><span style="color: #333300; font-family: courier new,courier;"> Capabilities Applied: LP</span><br /><span style="color: #333300; font-family: courier new,courier;"> Solve Time (ms): 169</span><br /><span style="color: #333300; font-family: courier new,courier;"> Total Time (ms): 353</span><br /><span style="color: #333300; font-family: courier new,courier;"> Solve Completion Status: Optimal</span><br /><span style="color: #333300; font-family: courier new,courier;"> Solver Selected: Microsoft.SolverFoundation.Solvers.SimplexSolver</span><br /><span style="color: #333300; font-family: courier new,courier;"> &hellip;</span><br /><span style="color: #333300; font-family: courier new,courier;"> ===Solution Details===</span><br /><span style="color: #333300; font-family: courier new,courier;"> Goals:</span><br /><span style="color: #333300; font-family: courier new,courier;"> TotalTransportationCost: 10000</span><br /><span style="color: #333300; font-family: courier new,courier;"> Decisions:</span><br /><span style="color: #333300; font-family: courier new,courier;"> x(Chicago, philadelphia): 50</span><br /><span style="color: #333300; font-family: courier new,courier;"> x(New York, philadelphia): 0</span><br /><span style="color: #333300; font-family: courier new,courier;"> TotalCost: 10000</span></p>
<p>The reports shows that it took less than two tenths of a second to calculate the optimal solution for this problem by using the simplex solver. The optimal solution, incurring a cost of 10000, is the transportation of 50 crates of beer from Chicago to Philadelphia, and zero crates from New York.</p>
<p><span style="font-size: large;"><strong><span style="color: #000080;">2&nbsp; LINQ for binding to AX data</span></strong></span></p>
<p>The preceding approach to data binding does not provide the power we need to use OML and the Microsoft Solver Foundation in our AX work. We do not want to write lots of tedious code to obtain and assign data from AX by using either the .NET Business Connector or AX services. A much better approach is to use LINQ for AX in our C# code. (For background information about LINQ for AX, see <a href="http://msdn.microsoft.com/library/jj677293.aspx">http://msdn.microsoft.com/library/jj677293.aspx</a>).</p>
<p>By using LINQ for AX we can reference table of data in AX with great ease and succinct code. Let&rsquo;s imagine there are tables that store the values we need. We need a table called Cities that defines the cities that produce and consume beer. The Cities table has the following fields:</p>
<p>CITYNAME, COUNTRY, LATITUDE, LONGITUDE, STATE</p>
<p>To keep the example unrealistically simple, let&rsquo;s say that the distances between the cities will serve as the only costing factor. The crates of beer will be shipped by trucks, each with a capacity. We would add criteria to make sure we filled the trucks to capacity. This spares our example the complexity of unit cost differences in scenarios where we might ship only one crate on a given truck, instead of filling the truck to capacity.</p>
<p><span style="font-size: medium;"><strong><span style="color: #3366ff;">2.1&nbsp; Rewrite the DataBind method</span></strong></span></p>
<p>Now that we have the cities data ready, we need a way to calculate the distances between the cities, based on their latitude and longitude. For this calculation we use the Haversine formula, as explained in <a href="http://mathforum.org/library/drmath/view/51879.html">http://mathforum.org/library/drmath/view/51879.html</a>. This algorithm is encoded into the static Distance method in the DistanceBetweenLocations class.</p>
<p>We will now present the new DataBind method. The few var declarations at the start of the method are identical to those in the earlier code example for the DataBind method. But now after the var declarations we use LINQ queries to access the data from AX:</p>
<p><span style="color: #003300; font-family: courier new,courier;">public Model DataBind(Model model)</span><br /><span style="color: #003300; font-family: courier new,courier;"> {</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var demandParameter = model.Parameters.Where(</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Demand")).First();</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var capacityParameter = model.Parameters.Where(</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Capacity")).First();</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var costParameter = model.Parameters.Where(</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p =&gt; p.Name.StartsWith("Cost")).First();</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;QueryProvider provider = new AXQueryProvider(null);</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;QueryCollection consumers = new QueryCollection(provider);</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;QueryCollection producers = new QueryCollection(provider);</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;QueryCollection cities = new QueryCollection(provider);</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;// Bind data to the parameters using LINQ to AX.</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var tempCities = (from city in cities</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RecId = city.RecId,</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CityName = city.CityName,</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Latitude = city.Latitude,</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Longitude = city.Longitude</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}).ToArray();</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var capacityQuery = from city in tempCities</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from p in producers</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where p.cityRecId == city.RecId</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; supply = Convert.ToDouble(p.Capacity), </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = city.CityName };</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;capacityParameter.SetBinding(capacityQuery, "supply", "name");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var demandQuery = from city in tempCities</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from c in consumers</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where c.cityRecId == city.RecId</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;demand = Convert.ToDouble(c.Demand), </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name = city.CityName };</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;demandParameter.SetBinding(demandQuery, "demand", "name");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var producerCityLocations = from city in tempCities</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from producer in producers</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where city.RecId == producer.cityRecId</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = city.CityName, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Latitude = city.Latitude, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Longitude = city.Longitude };</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var consumerCityLocations = from city in tempCities</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from consumer in consumers</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where city.RecId == consumer.cityRecId</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new { </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name = city.CityName, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Latitude = city.Latitude, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Longitude = city.Longitude };</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;// Cost.</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;var costQuery =</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from producer in producerCityLocations</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from consumer in consumerCityLocations</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select new</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;distance = DistanceBetweenLocations.Distance(</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; consumer.Latitude, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; consumer.Longitude, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; producer.Latitude, </span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; producer.Longitude),</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;producing = producer.Name,</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consuming = consumer.Name</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;costParameter.SetBinding(costQuery, "distance", "producing", "consuming");</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;return model;</span><br /><span style="color: #003300; font-family: courier new,courier;"> }</span></p>
<p>In the example above, we start by reading the whole Cities table into memory, into the tempCities array. Reading the whole table improves the speed of queries in the subsequent code. It also helps us in debugging. But if your table contains a lot of data, you might instead need to perform multiple smaller reads from the table, incurring a slight overhead. The point is that the LINQ solution does not rely on the optimization of reading the whole Cities table.</p>
<p><strong><span style="color: #3366ff; font-size: medium;">2.2&nbsp; WPF control to host a Bing map</span></strong></p>
<p>Now we have what we need to use the model from AX. To make things a little more interesting and easier to demo, I have used this code from a form which shows a Bing map with the cities, and which also shows the solution.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/1832.USA-Map-GreenRed-Dots-b2.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/1832.USA_2D00_Map_2D00_GreenRed_2D00_Dots_2D00_b2.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/1832.USA-Map-GreenRed-Dots-b2.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/1832.USA_2D00_Map_2D00_GreenRed_2D00_Dots_2D00_b2.PNG" alt="" border="0" /></a></p>
<p>This is all made very easy by using the managed control host to host a WPF control (the Bing maps control). This feature has always been a little under-appreciated and under hyped. It really is extremely useful whenever you want to present data in an interesting way in an AX form. You can download the Bing maps control from <a href="http://www.microsoft.com/en-us/download/details.aspx?id=27165">http://www.microsoft.com/en-us/download/details.aspx?id=27165</a>.</p>
<p><span style="font-size: large;"><strong><span style="color: #000080;">3 Network model</span></strong></span></p>
<p>The preceding example model is a simple case. You can easily expand it to the network model, where limits are placed on the amount of goods shipped, and equations maintain that nothing is ever lost in the grid. You can find interesting examples here:</p>
<p><a href="http://www.me.utexas.edu/~jensen/ORMM/models/unit/network/subunits/distribution/index.html">http://www.me.utexas.edu/~jensen/ORMM/models/unit/network/subunits/distribution/index.html</a></p>
<p>These problems are solved just as the simple example we have just shown.</p>
<p><span style="color: #3366ff;"><strong><span style="font-size: medium;">3.1&nbsp; Assignment problem</span></strong></span></p>
<p>One of the interesting special cases of the network problem is the assignment problem. The definition of this problem reads as follows:</p>
<p>There are a number of agents and a number of tasks. Each agent must be assigned exactly one task, and each task must be assigned exactly one agent. Any agent can be assigned to perform any task. The costs incurred may vary depending on particular attributes of the agent and task in each paring. The challenge is to choose the agent-task assignments that minimize the total cost.</p>
<p>The standard example used to illustrate this problem is that of a set of workers and a set of jobs performed by the workers. The cost of personi doing jobj is input to the algorithm. Some people are better at a particular job, so their cost is smaller than for someone who is not yet skilled at that particular job. The solution is a boolean matrix that maps each job onto a machine such that the minimal cost is incurred.</p>
<p>Another embodiment of this problem is the taxi company problem. There is a set of customers and a set of taxis to serve them. The cost of a trip is a function of the distance that an available taxi is from the customer. The objective is to minimize that cost.</p>
<p><span style="font-size: medium;"><strong><span style="color: #3366ff;">3.2&nbsp; Knapsack problem</span></strong></span></p>
<p>Another problem that often occurs is the knapsack problem. Imagine you have a knapsack of a certain maximum weight capacity. The challenge is to pack the knapsack with items having as much total monetary value as possible without exceeding the weight capacity of the knapsack.&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/6064.Knapsack-with-boxes-c3.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/6064.Knapsack_2D00_with_2D00_boxes_2D00_c3.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/6064.Knapsack-with-boxes-c3.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/250x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/6064.Knapsack_2D00_with_2D00_boxes_2D00_c3.PNG" alt="" border="0" /></a></p>
<p>&nbsp;The equations are:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/8880.Formulas-Knapsack-d4.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/8880.Formulas_2D00_Knapsack_2D00_d4.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/8880.Formulas-Knapsack-d4.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/308x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/8880.Formulas_2D00_Knapsack_2D00_d4.PNG" alt="" border="0" /></a></p>
<p>The first equation says that we should maximize the monetary value of the content in the knapsack (vi is the value of the ith item, and xi is the count of that item to bring). The second equation says that the cost of each item (or number of items) cannot exceed the constraint W, where W is the capacity of the knapsack. In our example, the cost is the weight that you have to carry, and W is the maximum weight that you are willing to accept.</p>
<p>There are three flavors of knapsack problems:&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/1207.Formulas-Knapsack-3bullets-d71.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/1207.Formulas_2D00_Knapsack_2D00_3bullets_2D00_d71.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/1207.Formulas-Knapsack-3bullets-d71.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/430x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/1207.Formulas_2D00_Knapsack_2D00_3bullets_2D00_d71.PNG" alt="" border="0" /></a></p>
<p>We illustrate the difference with an example shown in Wikipedia (<a href="http://en.wikipedia.org/wiki/Knapsack_problem">http://en.wikipedia.org/wiki/Knapsack_problem</a>). Here the limiting factor here is the weight capacity of the knapsack (W=15kg). There are five types of items: the green, gray, blue, yellow, and orange types. There are many items available of each type. The weight and monetary value is written on each item.</p>
<p>The solutions are as follows:</p>
<ul>
<li>0-1: yellow, blue, gray, orange.<br />(value 10$ + 2$ + 2$ + 1$ = 15$; weight = 4 + 2 + 1 + 1 = 8kg)</li>
<li>Unbounded: 3 yellow and 3 gray boxes.<br />(value 3*10$ + 3*2$ = 16$; weight = 3*4 + 3 * 1 = 15kg)</li>
</ul>
<p>Again, it is useful to look at what this looks like in OML:</p>
<p><span style="color: #003300; font-family: courier new,courier;">Model[</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Parameters[Sets, items],</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Parameters[Integers[0,Infinity],</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cost[items], Value[items], W</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;],</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Decisions[Integers[0,1], x[items]], // Either it is included, or it isn't.</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Decisions[Integers, TotalCost, TotalValue]</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Constraints[</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TotalCost == Sum[{i,items}, x[i]*Cost[i]],</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TotalValue == Sum[{i,items},x[i]*Value[i]],</span><br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TotalCost &lt;= W<br />&nbsp;&nbsp;&nbsp;&nbsp;],</span><br /> <br /><span style="color: #003300; font-family: courier new,courier;"> &nbsp;&nbsp;&nbsp;&nbsp;Goals[Maximize[TotalValue]]</span><br /><span style="color: #003300; font-family: courier new,courier;"> ]</span></p>
<p>You can convert the above OML model into the Bounded or Unbounded knapsack problem by changing the definition of the x decision variable. As with all of the examples in this area, the problem statement is an abstraction of the problems that you would apply this to in real life.</p>
<p>You would use the same procedure as described above to do the data binding.</p>
<p><span style="font-size: medium;"><strong><span style="color: #3366ff;">3.3&nbsp; Traveling salesman</span></strong></span></p>
<p>The traveling salesman problem is a classic that rears its head in many interesting places. The description is simple enough:</p>
<ul>
<li>A salesman has customers who are placed in different cities.</li>
<li>He must visit each of his customers exactly once.</li>
<li>Then he must return to where he started.</li>
</ul>
<p>The challenge is to devise the cheapest itinerary, given the cost of transportation between the cities.</p>
<p>Research into this area has been intensive because the cost of calculating the result for many cities is high. It is an interesting problem because it is not really possible to solve it using brute-force approaches. The number of possible itineraries is a function of the factorial of the cities to be visited, which very quickly gets out-of-hand. The bits accompanying this blog entry provide a solution expressed in OML, and a test-bed with a form to show the results on a map. I have adapted the solution from some excellent work by Nathan Brixus in <a href="http://nathanbrixius.wordpress.com/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation/">http://nathanbrixius.wordpress.com/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation/</a>.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/5344.USA-Map-Green-DotsLots-b53.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5344.USA_2D00_Map_2D00_Green_2D00_DotsLots_2D00_b53.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/5344.USA-Map-Green-DotsLots-b53.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5344.USA_2D00_Map_2D00_Green_2D00_DotsLots_2D00_b53.PNG" alt="" border="0" /></a></p>
<p><strong><span style="color: #000080; font-size: large;">Conclusion</span></strong></p>
<p>There are many more interesting examples of O.R. problems that can be solved by using the Microsoft Solver Foundation library. You can find some very interesting samples here: <a href="http://msdn.microsoft.com/en-us/library/ff524501(v=vs.93).aspx">http://msdn.microsoft.com/en-us/library/ff524501(v=vs.93).aspx</a>. The samples map to interesting business scenarios, all of which would be above and beyond most developers to solve using X++ code. The source code for the samples shown here can be found here: <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/5381.PrivateProject_TechnicalConference2012%20(1)%20-%20Copy.xpo" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5381.PrivateProject_5F00_TechnicalConference2012-_2800_1_2900_-_2D00_-Copy.xpo">http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5381.PrivateProject_5F00_TechnicalConference2012-_2800_1_2900_-_2D00_-Copy.xpo</a></p>
<p>I hope this has been a useful blog entry, one that shows you how to get started in this interesting field. There are many things to learn, but a lot of benefits to reap.</p>
<p>&nbsp;</p>
<p>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Announcing the “AxErd” Website for Dynamics AX 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/x/announcing-the-axerd-website-for-dynamics-ax-2012</link>
      <pubDate>Thu, 23 May 2013 10:29:00 GMT</pubDate>
      <dc:creator><![CDATA[Gene-FID]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2013/05/23/announcing-the-axerd-website-for-dynamics-ax-2012/</guid>
      <description><![CDATA[We have created about 30 database ERDs (entity relationship diagrams) for tables of Microsoft...]]></description>
      <content:encoded><![CDATA[<p>We have created about 30 database ERDs (entity relationship diagrams) for tables of Microsoft Dynamics AX 2012 R2.&nbsp; The ERDs are useful to AX developers when they need to customize a given application module (such as Accounts payable or General ledger).</p>
<p>The ERDs are part of our &ldquo;AxErd&rdquo; website, which can be reached at the following Http URL:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://go.microsoft.com/fwlink/p/?linkid=296623">AxErd website: &nbsp;&nbsp; http://go.microsoft.com/fwlink/p/?linkid=296623</a></p>
<p><br />&nbsp;</p>
<p><span style="color: #000080;"><strong><span style="font-size: medium;">Design Principle for ERDs</span></strong></span></p>
<p>Dynamics AX has several thousand tables. It is impossible to construct one ERD that contains every table. And it is impossible to construct enough specialized ERDs that foresee every precise need of every partner developer. So the many ERDs we provide&nbsp;were designed to capture the core tables of each module, and to include some major tables from other related modules.</p>
<p>Minor compromises were made so that each ERD can&nbsp;fit onto one side of a standard sheet of paper when printed.</p>
<p><br />&nbsp;</p>
<p><span style="color: #000080; font-size: medium;"><strong>Support Files for ERD Extension</strong></span></p>
<p>The AxErd website also contains hundreds of inter-linked support .htm files designed to assist the partner developer who needs to extend one of the ERDs that AxErd provides. In AX, the partner developer can easily look up all the parent tables of a given table, by navigating:</p>
<p><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008000;">AOT &gt; Data Dictionary &gt; Tables &gt; <em>MyTable</em> &gt; Relations &gt; <em>MyRelation</em></span></p>
<p>&nbsp;</p>
<p>However, it is much harder for the developer to look up all the child tables of that same given table. Cross-reference does technically provide this information, but laborious clicks and scrolls are required to perform the look ups. In contrast, the AxErd website performs this look up with one click.</p>
<p>For instructions on how you can semi-automate the task of extending or creating an ER diagram with Dynamics AX 2012, click the 'Help' link on the AxErd Home page.</p>
<p><br />&nbsp;</p>
<p><span style="color: #000080; font-size: medium;"><strong>Tables and ERDs are Categorized by Module</strong></span></p>
<p>For each table, the AxErd webpages indicate which module the table is categorized into. And in the reverse direction, for any one module there is a webpage that lists all the tables which are categorized into the module.</p>
<p><br />&nbsp;</p>
<p><span style="color: #000080; font-size: medium;"><strong>Example ERD</strong></span></p>
<p>Here is&nbsp;one ERD from the AxErd website.&nbsp;The&nbsp;image has been reduced in size for display here.</p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/4331.Erd-One-ProjectMangtAccounting-PJ1-PET-vsd.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/4331.Erd_2D00_One_2D00_ProjectMangtAccounting_2D00_PJ1_2D00_PET_2D00_vsd.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/4331.Erd-One-ProjectMangtAccounting-PJ1-PET-vsd.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/4331.Erd_2D00_One_2D00_ProjectMangtAccounting_2D00_PJ1_2D00_PET_2D00_vsd.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The next image shows an AxErd webpage that lists all the child tables of the InventTable table, meaning tables that have a foreign key column that references the values in the primary key of the InventTable table.</p>
<p>The portion that is circled in red shows that the AgreementLine table is a child of the InventTable table.&nbsp;The arrow always points from child to parent.</p>
<p>In the image, every word that is blue is a clickable link to related information.</p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/4403.AxErd-InventTable-itsChildTables-FkyFile-2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/4403.AxErd_2D00_InventTable_2D00_itsChildTables_2D00_FkyFile_2D00_2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/4403.AxErd-InventTable-itsChildTables-FkyFile-2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/4403.AxErd_2D00_InventTable_2D00_itsChildTables_2D00_FkyFile_2D00_2.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p><br />&nbsp;</p>
<p><span style="color: #333333;"><em>Gene Milener , 2013-May-23</em></span></p>]]></content:encoded>
    </item>
    <item>
      <title>X++ Arrays Behave Differently in .NET CIL, in Dynamics AX 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/x/x-arrays-behave-differently-in-net-cil-in-dynamics-ax-2012</link>
      <pubDate>Mon, 17 Sep 2012 11:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Gene-FID]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2012/09/17/x-arrays-behave-differently-in-net-cil-in-dynamics-ax-2012/</guid>
      <description><![CDATA[&nbsp;
1. Understanding the Difference
&nbsp;
There has been some confusion about the behavior of...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="color: #0000ff; font-size: large;"><b><span style="font-family: Calibri;" face="Calibri">1. Understanding the Difference</span></b></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"></span></span>&nbsp;</p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">There has been some confusion about the behavior of X++ arrays in Microsoft Dynamics AX 2012, because the behavior can differ from AX 2009. Let&rsquo;s clear up the confusion.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In X++, you can assign an array of primitive integers to another array. This is shown in line 3:</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"></span></span>&nbsp;<span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<table style="background-color: #ffeeee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="79">
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>1</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>2</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>3</i></span></p>
</td>
<td valign="top" width="312" cellpadding="4">
<p><span style="font-family: courier new,courier;">int myArray[3], yourArray[3];</span></p>
<p><span style="font-family: courier new,courier;">myArray[1] = 101;</span></p>
<p><span style="font-family: courier new,courier;">yourArray = myArray;</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In AX 2009 and earlier, when one whole array was assigned to another, the assignment mechanism for primitive types was always by <i>value</i>. However...</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Starting in AX 2012, for X++ arrays the assignment mechanism of primitive types is sometimes by <i>value</i>, and other times by <i>reference</i>. The assignment mechanism is determined by the X++ execution mode, which is either the interpreter or as CIL (new in AX 2012).</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The following table relates both X++ execution modes to both assignment mechanisms:</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<table style="background-color: #eeffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr style="background-color: #eeeeee;">
<td valign="top" width="187">
<p><span style="font-size: medium;"><b><i><span style="font-family: Calibri;" face="Calibri">X++ execution mode</span></i></b></span></p>
</td>
<td valign="top" width="222">
<p><span style="font-size: medium;"><b><i><span style="font-family: Calibri;" face="Calibri">Execution context</span></i></b></span></p>
</td>
<td valign="top" width="229">
<p><span style="font-size: medium;"><b><i><span style="font-family: Calibri;" face="Calibri">Array assignment mechanism</span></i></b></span></p>
</td>
</tr>
<tr>
<td valign="top" width="187">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Under the X++ <b><span style="text-decoration: underline;">interpreter</span></b></span></span></p>
</td>
<td valign="top" width="222">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Running on the AX client.</span></span></p>
</td>
<td valign="top" width="229">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Assigned by <b><span style="text-decoration: underline;">value</span></b>.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">An independent copy is made of the value, and the address of the copy is given to the assignee.</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="187">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">As .NET Framework <b><span style="text-decoration: underline;">CIL</span></b></span></span></p>
</td>
<td valign="top" width="222">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Running as AX batch, AX service, or by Global ::runClassMethodIL (or by the X++ runAs function).</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In CIL, X++ arrays are implemented as .NET managed arrays, which always pass by reference.</span></span></p>
</td>
<td valign="top" width="229">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Assigned by <b><span style="text-decoration: underline;">reference</span></b>.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">No copy of the value is made.</span></span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff; font-size: large;"><b><span style="font-family: Calibri;" face="Calibri">2. Terminology</span></b></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b><span style="text-decoration: underline;"></span></b></span></span>&nbsp;</p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b><span style="text-decoration: underline;">By Value:</span></b> In the by value case, the assignment creates a copy or second occurrence of the assigned primitive value. The assignee variable is given the address of the copy. Now the assigner&rsquo;s copy is unaffected when the assignee changes its value.</span></span></p>
<p><br /><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b><span style="text-decoration: underline;">By Reference:</span></b> In the by reference case, the assignment does not create any copy or second occurrence of the assigned primitive value. Instead, the assignee variable is given the same internal memory location of the value that the assigner has. Now both the assigner and assignee variables are reading from and writing to the same memory location. One of the two variables might be used to over-write the location with a new value, thereby affecting both variables (perhaps unintentionally).</span></span></p>
<p><br /><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b><span style="text-decoration: underline;">Primitive versus Object:</span></b> In X++ the primitive data types include int, str, and boolean. An instance of a class is an object.</span></span></p>
<p><br /><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">X++ arrays can store only primitives. They cannot store objects like those constructed from classes.</span></span></p>
<p><br />&nbsp;</p>
<p><span style="color: #0000ff; font-size: large;"><b><span style="font-family: Calibri;" face="Calibri">3. X++ Code Snippet for Explanation</span></b></span></p>
<p><br /><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In the following X++ code snippet, consider the array assignment at line 3. Merely reading the X++ code does not enable us to ascertain whether the array assignment mechanism is by value or by reference. We have to know the execution mode. Line 4 has different effects between the two execute modes:</span></span></p>
<p><br />&nbsp;</p>
<table style="background-color: #ffeeee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="43">
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>1</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>2</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>3</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>4</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>5</i></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier;"><i>6</i></span></p>
</td>
<td valign="top" width="595">
<p><span style="font-family: courier new,courier;">int arrayA[2], arrayB[2];</span></p>
<p><span style="font-family: courier new,courier;">arrayA[1] = 111;</span></p>
<p><span style="font-family: courier new,courier;"><b>arrayB = arrayA;</b>&nbsp; // By value, or by reference?&nbsp; It depends!</span></p>
<p><span style="font-family: courier new,courier;">arrayB[1] = 222;&nbsp; // Does this affect arrayA[1]? It depends!</span></p>
<p><em><span style="font-family: courier new,courier;">// If line 4 affected arrayA[1], then assignment is By REFERENCE.</span></em></p>
<p><span style="font-family: courier new,courier;">Global::info(strFmt("%1: changed to 222, or remains 111?<span face="Calibri"> </span>", arrayA[1]));</span></p>
</td>
</tr>
</tbody>
</table>
<p></p>
<p><span style="color: #0000ff; font-size: large;"><b>4. The Fix:&nbsp; Uniform Behavior is Achievable</b></span></p>
<p><br />The variation in array assignment mechanisms has caught some X++ developers by surprise, quite understandably. To avoid array bugs in your X++ code, you should design your code to behave the same in both execution modes.</p>
<p>In both modes, your code should consistently use only one of the assignment mechanisms between the two arrays:&nbsp;uniformly use&nbsp;either (a)&nbsp;by value assignments between individual elements of&nbsp;the two arrays, or (b) by reference assignments between the two arrays.</p>
<p>Either of these two assignment mechanisms (by value or reference)&nbsp;can be achieved in either of these modes (X++ interpreted or as CIL), with a pair of either X++ arrays or&nbsp;AX Array class objects.</p>
<p>The following table provides code snippets to illustrate the design options.</p>
<p>&nbsp;</p>
<table style="background-color: #eeffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr style="background-color: #eeeeee;">
<td valign="top" width="79">
<p><b><i>Behavior type</i></b></p>
</td>
<td valign="top" width="150">
<p><b><i>Design for uniform behavior</i></b></p>
</td>
<td valign="top" width="379">
<p><b><i>X++ Code snippet</i></b></p>
</td>
</tr>
<tr>
<td valign="top" width="79">
<p>all by</p>
<p><b>Value</b></p>
</td>
<td valign="top" width="150">
<p>Use a loop to assign one element at a time, from one X++ array to another.</p>
<p>Each element is assigned by value.</p>
</td>
<td style="background-color: #ffeeee;" valign="top" width="379">
<p><span style="font-family: courier new,courier;">int aa[2], bb[2];</span></p>
<p><span style="font-family: courier new,courier;">aa[1] = 101; aa[2] = 102;</span></p>
<p><span style="font-family: courier new,courier;">for (i=1; i &lt; dimof(aa); i++)</span></p>
<p><span style="font-family: courier new,courier;">&nbsp; { bb[i] = aa[i]; }</span></p>
<p><span style="font-family: courier new,courier;">bb[1] = 201; <b><span style="text-decoration: underline;">// Not affect aa[1]!</span></b></span></p>
</td>
</tr>
<tr>
<td valign="top" width="79">
<p><span style="font-family: courier new,courier;">a</span>ll by</p>
<p><b>Reference</b></p>
</td>
<td valign="top" width="150">
<p>Use the AX class named Array, instead of the array syntax that is built into the X++ language.</p>
<p>All assignments from one Array object to another are by reference.</p>
</td>
<td style="background-color: #ffeeee;" valign="top" width="379">
<p><span style="font-family: courier new,courier;">Array oarrayC = new Array(Types::Integer);</span></p>
<p><span style="font-family: courier new,courier;">Array oarrayD = oarrayC;</span></p>
<p><span style="font-family: courier new,courier;">oarrayC.value(1, 301);</span></p>
<p><span style="font-family: courier new,courier;">oarrayD.value(1, oarrayC.value(1));</span></p>
<p><span style="font-family: courier new,courier;">oarrayD.value(1, 401); <b><span style="text-decoration: underline;">// Affects oarrayC!</span></b></span></p>
<p><span style="font-family: courier new,courier;">//oarrayD = oarrayC; // Is by Reference.</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><br /><span style="color: #0000ff; font-size: large;"><b>5. Design Decision of the AX Product Team</b></span></p>
<p><br />During development of AX 2012, the product team strove to minimize any functional differences between interpreted X++ versus X++ as CIL. However, X++ arrays were one compromise we felt was necessary.</p>
<p>It would have been expensive to generate CIL that implements pass-by-value semantics for arrays. Also, the interoperability between AX and code written in other .NET languages would have become contorted, which would have been an unwise trade-off in the long run.</p>
<p>&nbsp;</p>
<p><br /><span style="color: #0000ff; font-size: large;"><b>6. Demo: ArrayTestClass</b></span></p>
<p><br />This optional section provides X++ code for a runnable demonstration. The demo does the following:</p>
<ol>
<li>Runs each test twice: once in the interpreter, and once as CIL.</li>
<li>Compares the behaviors of X++ arrays versus the AX Array class.</li>
<li>Compares the effects of assigning a whole array versus assigning each element one at a time.</li>
</ol>
<p>&nbsp;</p>
<p><b><span style="text-decoration: underline;">Steps:</span></b><br />To run the demo, you can perform the following steps:</p>
<ol>
<li>In AX, create a class named ArrayTestClass.</li>
<li>Add the following method names, and paste in the code from below.&nbsp;<br />
<ul>
<li>Main &ndash; Runs Test1 in interpreter, and again as CIL. Same for Test2.</li>
<li>Test1 &ndash; Assigns a whole array; uses X++ arrays.</li>
<li>Test2 &ndash; Assigns a whole array object; uses the AX Array class.</li>
<li>Test3 &ndash; Assigns one element at a time; uses X++ arrays.</li>
<li>Test4 &ndash; Assigns one element at a time; uses the AX Array class.</li>
</ul>
</li>
<li>Menu: Build &gt; Generate Incremental CIL.</li>
<li>In the X++ code editor, open the Main method, and then run it (by pressing F5, or clicking the green arrow to &ldquo;Go&rdquo;).</li>
</ol>
<p>&nbsp;</p>
<p><b><span style="text-decoration: underline;">Outputs:</span></b><br />The demo outputs for each Test method are in <span style="font-family: courier new,courier;">/**comment sections**/</span> at the end of each Test method&rsquo;s code.</p>
<p>&nbsp;</p>
<p><br /><i>Main</i></p>
<table style="background-color: #ffffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="638">
<p><span style="font-family: courier new,courier;">server static public void Main(Args _args)&nbsp; // Run this method.<br /></span><span style="font-family: courier new,courier;">{<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; new XppILExecutePermission().assert();<br /><br /></span><span style="font-family: courier new,courier;"></span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Using:&nbsp; Built-in X++ language array syntax.</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; ArrayTestClass::Test1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (["X++_in_Interpreter, X++ language array, by Value", 1]);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::runClassMethodIL("ArrayTestClass", "Test1",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: courier new,courier;">&nbsp;["As_CIL, X++ language array, by Reference", 2]);</span></p>
<p><span style="font-family: courier new,courier;"></span>&nbsp;</p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Using:&nbsp; AX Array class.</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(" ");</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; ArrayTestClass::Test2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (["X++_in_Interpreter, Array class, by Reference", 3]);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::runClassMethodIL("ArrayTestClass", "Test2",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: courier new,courier;">&nbsp;["As_CIL, Array class, by Reference", 4]);</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Using:&nbsp; Built-in X++ language array syntax, one element.</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(" ");</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; ArrayTestClass::Test3<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: courier new,courier;">(["X++_in_Interpreter, Element of X++ lang array, by Value", 5]);</span></p>
<p>&nbsp;<span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::runClassMethodIL("ArrayTestClass", "Test3",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: courier new,courier;">&nbsp;["As_CIL, Element of X++ lang array, by Value", 6]);</span></p>
<p>&nbsp;</p>
<p>&nbsp;<span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Using:&nbsp; AX Array class.</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(" ");</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; ArrayTestClass::Test4<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (["X++_in_Interpreter, Array class, by Value", 7]);</span></p>
<p>&nbsp;<span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::runClassMethodIL("ArrayTestClass", "Test4",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;["As_CIL, Array class, by Value", 8]);<br /></span><span style="font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p></p>
<p>&nbsp;<i>Test1</i></p>
<table style="background-color: #ffffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="638">
<p><span style="font-family: courier new,courier;">static public void Test<b>1</b>(container _conr) // Built-in X++ language array syntax.<br /></span><span style="font-family: courier new,courier;">{<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int arrayA[2];<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int arrayB[2];<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int nTrialNum = conPeek(_conr, 2);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; str sExecMode = conPeek(_conr, 1);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayA[1] = 101;<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayB = arrayA;&nbsp; // Whole array: By value or by reference?<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayB[1] = 201;</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(strFmt(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Test1(), Trial %1, whole array:&nbsp; arrayA[1] = %2 , arrayB[1] = %3&nbsp; :MODE of %4.",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: courier new,courier;">nTrialNum, arrayA[1], arrayB[1], sExecMode));<br /></span><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">/*** Output results:&nbsp; Notice arrayA[2] is changed only in CIL.</span></p>
<p><span style="font-family: courier new,courier;">Test1(), Trial 1, whole array:&nbsp; arrayA[1] = 101 , arrayB[1] = 201</span><br /><span style="font-family: courier new,courier;"> :MODE of X++_in_Interpreter, X++ language array, by Value.</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">Test1(), Trial 2, whole array:&nbsp; arrayA[1] = 201 , arrayB[1] = 201</span><br /><span style="font-family: courier new,courier;"> :MODE of As_CIL, X++ language array, by Reference.</span></p>
<p><span style="font-family: courier new,courier;">***/</span></p>
</td>
</tr>
</tbody>
</table>
<p><br />&nbsp;</p>
<p><i>Test2</i></p>
<table style="background-color: #ffffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="638">
<p><span style="font-family: courier new,courier;">static public void Test<b>2</b>(container _conr) // AX Array class.<br /></span><span style="font-family: courier new,courier;">{<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Array orrayC = new Array(Types::Integer);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Array orrayD = new Array(Types::Integer);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int nTrialNum = conPeek(_conr, 2);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; str sExecMode = conPeek(_conr, 1);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayC.value(1, 101);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayD = orrayC;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Whole array object is assigned.<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayD.value(1, 201);&nbsp; //By value, or by reference? Always by reference!</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(strFmt(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Test2(), Trial %1, whole array:&nbsp; orrayC.value(1) = %2 , orrayD.value(1) = %3&nbsp; :MODE of %4.",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: courier new,courier;">nTrialNum, orrayC.value(1), orrayD.value(1), sExecMode));<br /></span><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">/*** Output results:&nbsp; Notice oarrayC.value(1) is changed in interpreter and CIL.</span></p>
<p><span style="font-family: courier new,courier;">Test2(), Trial 3, whole array:&nbsp; orrayC.value(1) = 201 , orrayD.value(1) = 201</span><br /><span style="font-family: courier new,courier;"> :MODE of X++_in_Interpreter, Array class, by Reference.</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">Test2(), Trial 4, whole array:&nbsp; orrayC.value(1) = 201 , orrayD.value(1) = 201</span><br /><span style="font-family: courier new,courier;"> :MODE of As_CIL, Array class, by Reference.</span></p>
<p><span style="font-family: courier new,courier;">***/</span></p>
</td>
</tr>
</tbody>
</table>
<p></p>
<p>&nbsp;<i>Test3</i></p>
<table style="background-color: #ffffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="638">
<p><span style="font-family: courier new,courier;">static public void Test<b>3</b>(container _conr) // One element, of built-in X++ array.<br /></span><span style="font-family: courier new,courier;">{<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int arrayA[2];<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int arrayB[2];<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int nTrialNum = conPeek(_conr, 2);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; str sExecMode = conPeek(_conr, 1);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayA[2] = 102;<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayB[2] = arrayA[2];&nbsp; // One element: By value or by reference? By value!<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; arrayB[2] = 202;</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(strFmt(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Test3(), Trial %1, one element:&nbsp; arrayA[2] = %2 , arrayB[2] = %3&nbsp; :MODE of %4.",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: courier new,courier;">nTrialNum, arrayA[2], arrayB[2], sExecMode));<br /></span><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">/*** Output results:&nbsp; Notice arrayA[2] is unchanged even in CIL.</span></p>
<p><span style="font-family: courier new,courier;">Test3(), Trial 5, one element:&nbsp; arrayA[2] = 102 , arrayB[2] = 202</span><br /><span style="font-family: courier new,courier;"> :MODE of X++_in_Interpreter, Element of X++ lang array, by Value.</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">Test3(), Trial 6, one element:&nbsp; arrayA[2] = 102 , arrayB[2] = 202</span><br /><span style="font-family: courier new,courier;"> :MODE of As_CIL, Element of X++ lang array, by Value.</span></p>
<p><span style="font-family: courier new,courier;">***/</span></p>
</td>
</tr>
</tbody>
</table>
<p><br />&nbsp;</p>
<p><i>Test4</i></p>
<table style="background-color: #ffffdd;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="638">
<p><span style="font-family: courier new,courier;">static public void Test<b>4</b>(container _conr) // AX Array class, assign one element.<br /></span><span style="font-family: courier new,courier;">{<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Array orrayC = new Array(Types::Integer);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Array orrayD = new Array(Types::Integer);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; int nTrialNum = conPeek(_conr, 2);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; str sExecMode = conPeek(_conr, 1);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayC.value(1, 101);<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayD.value(1, orrayC.value(1));&nbsp; // One element: By value, or by reference?<br /></span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; orrayD.value(1, 201);</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; Global::info(strFmt(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Test4(), Trial %1, one element:&nbsp; orrayC.value(2) = %2 , orrayD.value(2) = %3&nbsp; :MODE of %4.",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: courier new,courier;">nTrialNum, orrayC.value(1), orrayD.value(1), sExecMode));<br /></span><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">/*** Output&nbsp;results:&nbsp; Notice arrayC.value(1) was&nbsp;never affected by arrayD. Thus by value.</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;Test4(), Trial 7, one&nbsp;element:&nbsp; orrayC.value(2) = 101 ,&nbsp;orrayD.value(2) = 201</span><br /><span style="font-family: courier new,courier;">:MODE of X++_in_Interpreter,&nbsp;Array class, by Value.</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">Test4(), Trial 8, one&nbsp;element:&nbsp; orrayC.value(2) = 101 ,&nbsp;orrayD.value(2) = 201</span><br /><span style="font-family: courier new,courier;">:MODE of As_CIL, Array class, by Value.</span></p>
<p><span style="font-family: courier new,courier;">***/</span></p>
</td>
</tr>
</tbody>
</table>
<p><br />&nbsp;<span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"></span></p>
<p><span style="color: #0000ff; font-size: large;"><b>7. Links to AX 2012 Help on MSDN</b></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"></span>&nbsp;</p>
<table style="background-color: #eeffee;" border="1" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td valign="top" width="319">
<p><a href="http://msdn.microsoft.com/library/69c2751b-418f-4683-bd31-f59652412545(v=ax.60).aspx">X++&nbsp;Arrays</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/array(v=ax.60).aspx">Array&nbsp;Class of Dynamics AX</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/global.runclassmethodil.aspx">Global&nbsp;::runClassMethodIL</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/aa893873(v=ax.60).aspx">runAs&nbsp;Function of X++</a></p>
</td>
<td valign="top" width="319">
<p><a href="http://msdn.microsoft.com/en-us/library/gg839855(v=ax.60).aspx">X++ Compiled&nbsp;to .NET CIL</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/hh397320(v=ax.60).aspx">X++&nbsp;Scenarios that are Not Supported in CIL</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/hh528509(v=ax.60).aspx">Debug&nbsp;in Interpreted Mode Your X++ Code that Runs as .NET CIL</a></p>
</td>
</tr>
</tbody>
</table>
<p></p>
<p><span style="font-size: x-small;"><em>This blog post refers primarily to product version Microsoft Dynamics AX<br />2012 (AX 2012, AX2012). </em></span></p>
<p><span style="font-size: x-small;"><em>"X++ Arrays Behave Differently in .NET CIL, in Dynamics AX 2012"</em></span></p>
<p><span style="font-size: x-small;"><em>Gene Milener &amp; Peter Villadsen, September 2012</em></span></p>
<p><span style="font-size: x-small;"><em>//eof</em></span></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>X++ Function num2Str: Difference in .NET CIL Mode</title>
      <link>https://docs.microsoft.com/archive/blogs/x/x-function-num2str-difference-in-net-cil-mode</link>
      <pubDate>Thu, 08 Mar 2012 13:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Gene-FID]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2012/03/08/x-function-num2str-difference-in-net-cil-mode/</guid>
      <description><![CDATA[SUMMARY: You cannot pass the value of -1 for the &lsquo;decimals&rsquo; parameter to the num2str X++...]]></description>
      <content:encoded><![CDATA[<p><i style="mso-bidi-font-style: normal;">SUMMARY:</i> You cannot pass the value of -1 for the &lsquo;decimals&rsquo; parameter to the num2str X++ function when the function is run in .NET CIL mode, in Microsoft Dynamics AX 2012.</p>
<div class="WordSection1">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;">Introduction</span><o:p></o:p></b></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">In Microsoft Dynamics AX 2012, some of your X++ code can run as either...</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: .5in; mso-add-space: auto; text-indent: -.25in; line-height: normal; mso-list: l1 level1 lfo2;" class="MsoListParagraphCxSpFirst"><![if supportlists=""><span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">A.<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>Traditional interpreted p-code, or now as </![if></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: .5in; mso-add-space: auto; text-indent: -.25in; line-height: normal; mso-list: l1 level1 lfo2;" class="MsoListParagraphCxSpLast"><![if supportlists=""><span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">B.<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>Microsoft .NET CIL (common intermediate language).</![if></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal">There are a small number of cases where the behavior of specific X++ code differs between these two modes. These differences have been described in earlier blog entries such as one <a href="http://blogs.msdn.com/b/x/archive/2011/09/07/changes-to-the-collection-classes-in-dynamics-ax-2012.aspx">here</a> about AX collections.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">One more difference concerns the X++ language built-in function named num2str.</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span class="GramE"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;">num2Str</span></b></span><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;"> function, parameters demonstration</span><o:p></o:p></b></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">The num2str function inputs a primitive &lsquo;real&rsquo; type such as 1234.58, and it outputs a &lsquo;<span class="SpellE">str</span>&rsquo; type such as &ldquo;1,234.6&rdquo;. The function also inputs two <span class="SpellE">int</span> parameters and two <span class="SpellE">enum</span> parameters to choose the output string format details.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">&nbsp;</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">On MSDN the documentation for the num2str function is <a href="http://msdn.microsoft.com/en-us/library/aa866120(v=ax.60).aspx">here</a>. <span style="mso-spacerun: yes;">&nbsp;</span>The following table gives the names and descriptions of the parameters for num2str:</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<table style="border: currentColor; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 1184; mso-padding-alt: 0in 5.4pt 0in 5.4pt;" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; background: #D9D9D9; mso-background-themecolor: background1; mso-background-themeshade: 217; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">Parameter Name<o:p></o:p></span></b></p>
</td>
<td style="width: 292.5pt; border: solid windowtext 1.0pt; border-left: none; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; background: #D9D9D9; mso-background-themecolor: background1; mso-background-themeshade: 217; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">Description<o:p></o:p></span></b></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">number<o:p></o:p></span></p>
</td>
<td style="width: 292.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">The real number to convert to a string.<o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">character<o:p></o:p></span></p>
</td>
<td style="width: 292.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">The minimum number of characters required in the text.<o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 3; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">decimals<o:p></o:p></span></p>
</td>
<td style="width: 292.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">The required number of decimal places.<o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">separator1<o:p></o:p></span></p>
</td>
<td style="width: 292.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">A <span class="SpellE">DecimalSeparator</span> enumeration value.<o:p></o:p></span></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">(<i style="mso-bidi-font-style: normal;">Documentation </i></span><a href="http://msdn.microsoft.com/en-us/library/decimalseparator(v=ax.60).aspx"><i style="mso-bidi-font-style: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">here</span></i></a><i style="mso-bidi-font-style: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">.</span></i><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">)<o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 5; mso-yfti-lastrow: yes; page-break-inside: avoid;">
<td style="width: 131.4pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="175">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">separator2<o:p></o:p></span></p>
</td>
<td style="width: 292.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="390">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">A <span class="SpellE">ThousandSeparator</span> enumeration value.<o:p></o:p></span></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">(<i style="mso-bidi-font-style: normal;">Documentation </i></span><a href="http://msdn.microsoft.com/en-us/library/thousandseparator(v=ax.60).aspx"><i style="mso-bidi-font-style: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">here</span></i></a><i style="mso-bidi-font-style: normal;"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">.</span></i><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt;">)<o:p></o:p></span></p>
</td>
</tr>
</tbody>
</table>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">Next below is tiny job (in AOT &gt; Jobs) that demonstrates the num2Str parameters:</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 4.0pt 1.0pt 4.0pt;">
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span class="GramE"><b><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: darkblue;">static</span></b></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"> <b><span style="color: darkblue;">void</span></b> Job7(<span class="SpellE">Args</span> _<span class="SpellE">args</span>) <i><span style="color: green;">// X++ Job in the AOT, interpreted p-code.<br /></span></i></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">{<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE"><b><span style="color: darkblue;">str</span></b></span></span><span class="GramE"><span style="mso-spacerun: yes;">&nbsp; </span><span class="SpellE">moneyString</span></span>;<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE"><b><span style="color: darkblue;">real</span></b></span> <span class="SpellE">moneyReal</span> = <b><span style="color: red;">12345.68</span></b>;<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;"><br />&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">moneyString</span></span> = <b><span style="color: darkblue;">num2str<br /></span></b></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">moneyReal</span></span>,<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>-<b><span style="color: red;">1</span></b>, <i><span style="color: green;">// Minimum number of characters to output into the string.<br /></span></i></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>-<b><span style="color: red;">1</span></b>, <i><span style="color: green;">// Required number of digits to the right of the decimal.<br /></span></i></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE">DecimalSeparator</span>::Dot,<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><i><span style="color: green;">// 1<br /></span></i></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE">ThousandSeparator</span>::<span class="GramE">Comma<span style="mso-spacerun: yes;">&nbsp; </span><i><span style="color: green;">/</span></i></span><i><span style="color: green;">/ 2<br /></span></i></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>);<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span><span class="SpellE">moneyString</span>);<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">}<br /><br /></span><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">/**** <span class="SpellE">InfoLog</span> window, when parameters are -1 and -1<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">Message (11:44:17 am)<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">12,345.68<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">****/<o:p></o:p></span></i></p>
</div>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">In the preceding X++ job, consider the two parameters that have -1 as their value. This is an informal value that asks the function to choose a plausible default output format.<span style="mso-spacerun: yes;">&nbsp; </span>If instead of -1, the values for the two parameters were 22 and 1, the output string value would be:</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none;" class="MsoNormal"><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">/**** <span class="SpellE">InfoLog</span> window, when parameters are 22 and 1<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">Message (11:47:24 am)<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>12,345.7<br /></span></i><i><span style="font-size: 9.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas; color: green;">****/</span></i></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><span class="GramE"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;">num2Str</span></b></span><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;"> differences in CIL</span><o:p></o:p></b></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">For num2str the CIL difference is that the <b style="mso-bidi-font-weight: normal;">-1 value is invalid for the third parameter, the parameter that is named &lsquo;decimals&rsquo;</b>. Attempts to use -1 for the decimals parameter result in a <span class="SpellE">System.ArgumentOutOfRangeException</span>.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 18.0pt; mso-bidi-font-size: 11.0pt; color: #0070c0;">How to test in .NET CIL</span><o:p></o:p></b></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">If you are curious and want to run the num2str function in CIL mode, you can do so by using the Global::<span class="SpellE">runClassMethodIL</span> method, which is documented <a href="http://msdn.microsoft.com/en-us/library/global.runclassmethodil.aspx">here</a>.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">&nbsp;</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">The following code is the text of an .XPO file for a small test class. You could paste the code into your own .XPO file, and then import the .XPO into your test system. Then by running its Main method in the <span class="SpellE">MorphX</span> code editor, you can run num2str in CIL mode.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">&nbsp;</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">However, after import, and after each time you make any code change to this class, you must incrementally recompile the CIL.<span style="mso-spacerun: yes;">&nbsp; </span>You do this by opening an AOT window, right-clicking the root &ldquo;AOT&rdquo; node, and then clicking Add-Ins &gt; Incremental CIL generation from X++.</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt;">Class_GmClass3Num2str.XPO</span><o:p></o:p></b></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 1.0pt 1.0pt 1.0pt;">
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; mso-add-space: auto; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 1.0pt 1.0pt 1.0pt;" class="MsoNormalCxSpMiddle"><span class="SpellE"><span style="font-size: 9.0pt; font-family: 'Courier New';">Exportfile</span></span><span style="font-size: 9.0pt; font-family: 'Courier New';"> for AOT version 1.0 or later<br /></span><span class="SpellE"><span style="font-size: 9.0pt; font-family: 'Courier New';">Formatversion</span></span><span style="font-size: 9.0pt; font-family: 'Courier New';">: 1<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><o:p><br /></o:p></span><span style="font-size: 9.0pt; font-family: 'Courier New';">***Element: CLS<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><br />; Microsoft Dynamics AX Class: GmClass3Num2str unloaded<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';">; --------------------------------------------------------------------------------<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp; </span>CLSVERSION 1<br /><br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp; </span>CLASS #GmClass3Num2str<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>PROPERTIES<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Name<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#GmClass3Num2str<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Origin<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="GramE">#{</span>3FC77E58-CE3A-4B5C-8595-7EB9E12446CD}<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>ENDPROPERTIES<br /><br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>METHODS<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SOURCE #Method_Test_num2Str_as_CIL<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#public static server container Method_Test_num2Str_as_CIL<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(container _<span class="SpellE">conInputParam</span>)<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#{<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">container</span> <span class="SpellE">conStringReturn</span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">str</span></span><span class="GramE"><span style="mso-spacerun: yes;">&nbsp; </span><span class="SpellE">moneyString</span></span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">real</span> <span class="SpellE">moneyReal</span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">moneyReal</span></span> = <span class="SpellE">conPeek</span>(_<span class="SpellE">conInputParam</span>, 1);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">moneyString</span></span> = num2str<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">moneyReal</span></span>,<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>-1, // 'character': <span class="SpellE">Minimun</span> number of characters to output into the string.<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>1, // 'decimals': Required number of digits to the right of the decimal.<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE">DecimalSeparator</span>::Dot,<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>// 1<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE">ThousandSeparator</span>::<span class="GramE">Comma<span style="mso-spacerun: yes;">&nbsp; </span>/</span>/ 2<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">conStringReturn</span></span> = [<span class="SpellE">moneyString</span>];<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">return</span> <span class="SpellE">conStringReturn</span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#}<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="mso-spacerun: yes;">&nbsp;&nbsp;</span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ENDSOURCE<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SOURCE #Main<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#static public server void <span class="GramE">Main(</span><span class="SpellE">Args</span> _<span class="SpellE">args</span>)<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#{<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">str</span></span> <span class="SpellE">retStr_Interp</span> = "(Initial value.)";<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">str</span></span> <span class="SpellE">retStr_CIL</span> = "<span class="SpellE">retStr_CIL</span>";<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">container</span> <span class="SpellE">containerOfInputParam</span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;</span><span class="GramE">container</span> <span class="SpellE">containerOfOutputReturnValue</span>;<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span>"In Main, num2Str() run in X++ p-code Interpreted mode.");<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">containerOfInputParam</span></span> = [12345.67];<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">containerOfOutputReturnValue</span></span> = GmClass3Num2str<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>:<span class="GramE">:Method</span>_Test_num2Str_as_CIL(<span class="SpellE">containerOfInputParam</span>);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE">retStr_Interp</span> = <span class="SpellE"><span class="GramE">conPeek</span></span><span class="GramE">(</span><span class="SpellE">containerOfOutputReturnValue</span>, 1);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span> <span class="SpellE">retStr_Interp</span> );<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span>"------------------------");<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span>"In Main, num2Str() run in .NET CIL mode.");<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">new</span> <span class="SpellE">XppILExecutePermission</span>().assert();<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">containerOfInputParam</span></span> = [32345.67];<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">containerOfOutputReturnValue</span></span> =<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Global::<span class="SpellE">runClassMethodIL<br /></span></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"GmClass3Num2str",<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>"Method_Test_num2Str_as_CIL",<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="SpellE"><span class="GramE">containerOfInputParam<br /></span></span></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="SpellE">retStr_CIL</span> = <span class="SpellE"><span class="GramE">conPeek</span></span><span class="GramE">(</span><span class="SpellE">containerOfOutputReturnValue</span>, 1);<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span class="GramE">info(</span> <span class="SpellE">retStr_CIL</span> );<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#}<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ENDSOURCE<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SOURCE #<span class="SpellE">classDeclaration<br /></span></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#public class <span class="GramE">GmClass3Num2str</span><br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#{<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>#}<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ENDSOURCE<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>ENDMETHODS<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><span style="mso-spacerun: yes;">&nbsp; </span>ENDCLASS<br /></span><span style="font-size: 9.0pt; font-family: 'Courier New';"><br />***Element: END<o:p></o:p></span></p>
</div>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal">And here is the <span class="SpellE">InfoLog</span> content at the end of the run:</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 0in; mso-add-space: auto; line-height: normal;" class="MsoNormalCxSpMiddle"><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">/**** <span class="SpellE">InfoLog</span> window, from run of .XPO<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">Message (12:41:31 pm)<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">In Main, <span class="GramE">num2Str(</span>) run in X++ p-code Interpreted mode.<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">12,345.7<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">------------------------<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">In Main, <span class="GramE">num2Str(</span>) run in .NET CIL mode.<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">32,345.7<br /></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; color: #00b050;">****/<br /><br /></span><i style="mso-bidi-font-style: normal;">NOTE:</i> This blog post refers to Microsoft Dynamics AX 2012, which was made generally available in 2011/August. The CIL difference described herein might be eliminated in a future release, and -1 might become valid for the &lsquo;decimals&rsquo; parameter in CIL mode.</p>
</div>]]></content:encoded>
    </item>
    <item>
      <title>X++ Deterministic Garbage Collection</title>
      <link>https://docs.microsoft.com/archive/blogs/x/x-deterministic-garbage-collection</link>
      <pubDate>Fri, 13 Jan 2012 16:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Peter Villadsen]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2012/01/13/x-deterministic-garbage-collection/</guid>
      <description><![CDATA[Garbage Collection in Microsoft Dynamics AX 2012
&nbsp;
This blog entry investigates issues...]]></description>
      <content:encoded><![CDATA[<h1><span style="color: #365f91;" color="#365f91"><span style="font-family: Cambria;" face="Cambria">Garbage Collection in Microsoft Dynamics AX 2012</span></span></h1>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">This blog entry investigates issues concerning the deterministic garbage collection strategy that is employed in Microsoft Dynamics AX 2012.&nbsp; The AX garbage collector (GC) is compared to the Microsoft .NET Framework GC, in both strategy and performance.</span></span><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<h2><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Background of the AX GC</span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The basic strategy of the AX 2012 GC is the same as it was even before AX 4.&nbsp; AX uses a deterministic GC to manage the lifetime of X++ objects and table buffers. The GC is deterministic in the sense that objects are guaranteed to be disposed from the C++ memory space at the earliest possible moment after they are no longer needed.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The GC employs a reference counting algorithm that is enforced by the X++ interpreter. Whenever a reference is made to an object, the reference count is increased. Whenever a reference is removed the reference count is decreased. A reference can be removed when either (a) another value is assigned to a variable that had been holding the reference or (b) the variable that holds the reference drops out of scope.</span></span></p>
<p><b><span style="font-family: Calibri;" face="Calibri">Diagrammed Examples</span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Below is a diagrammed example of the reference count functionality in the AX GC.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The first line of X++ job code constructs an instance of </span><b>MyClass</b><span style="font-family: Calibri;" face="Calibri"> and assigns the object reference to the stack frame variable </span><b>mc</b><span style="font-family: Calibri;" face="Calibri">. In heap memory on the right, the blue circle represents the </span><b>MyClass</b><span style="font-family: Calibri;" face="Calibri"> object. The first blue circle has one incoming arrow which represents the reference to the object. The first blue circle is labeled &lsquo;1&rsquo; to show the count of references to the object so far.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Next, the assignment </span><b>mc1=mc</b><span style="font-family: Calibri;" face="Calibri"> creates a second reference to the blue circle object.&nbsp; Now the blue circle labeled &lsquo;2&rsquo; shows the new total of two references to the object. (Note the arrow labeled &lsquo;mc2&rsquo; should say &lsquo;mc1&rsquo;.)</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Next, the assignment </span><b>mc1 =null</b><span style="font-family: Calibri;" face="Calibri"> removes one of the references, making the state again like the blue circle labeled &lsquo;1&rsquo;.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Finally the job ends and the stack frame holding the variable </span><b>mc</b><span style="font-family: Calibri;" face="Calibri"> goes out of scope.&nbsp; The blue circle labeled &lsquo;0&rsquo; is marked with a symbol to indicate the AX GC removes the object from the heap at this moment.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/5736.GC%20figure%201.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5736.GC-figure-1.jpg"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/5736.GC%20figure%201.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/5736.GC-figure-1.jpg" /></a></span></p>
<p align="center"><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p align="center"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 1 Object deletion through reference counting.</span></span></strong></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Unfortunately there are more complex scenarios that reveal the weakness of the reference count strategy. Scenarios that involve reference loops require more operations by the GC. Consider the following case of two objects that refer to each other:</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p align="center"><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/0574.GC%20Figure%202.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/0574.GC-Figure-2.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/0574.GC%20Figure%202.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/0574.GC-Figure-2.png" /></a></span></p>
<p align="center"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 2 Mutually dependent objects, requiring loopcount</span></span></strong></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this case the objects should be removed because there are no external references to either object. To handle reference loops, the GC also maintains a loop count. The loop count indicates the number of loops in which the object currently takes part. When the difference of the reference count and the loop count is 0, the memory occupied by the object is removed.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The algorithm works across the client/server boundary as illustrated below: </span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p align="center"></p>
<p align="center"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 3 Object graph spanning the client server boundaries.</span></span></strong></p>
<p align="center"><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The algorithm guarantees that storage is reclaimed as soon as it is possible to do so, and the application programmer has no hooks into this. It is not possible to implement a method that is called when the object is reclaimed (akin to implementing the </span><b>IDisposable</b><span style="font-family: Calibri;" face="Calibri"> interface in .NET). It is a common misconception that in AX the </span><b>finalize</b><span style="font-family: Calibri;" face="Calibri"> method can be used for this purpose, yet this method has no special meaning to the AX system.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this distributed scenario the loop/ref information is maintained though the exchange of suitable messages over the network, causing considerable network traffic and performance degradation.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The AX GC uses a similar algorithm for table buffers. However, this algorithm is simpler for the GC because table buffers cannot hold references to each other, and there is no loop count to maintain.</span></span></p>
<p><b><span style="font-family: Calibri;" face="Calibri">Microsoft .NET Framework GC</span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The garbage collection strategy used in .NET is very different from what we just described. It relies on a mark-and-sweep algorithm where the set of objects are examined periodically to check if references are held to them. When no references are found to a given object, the object is removed. This strategy emphasizes that no guarantees are made about whether or when an unreferenced object might be removed. A complex set of criteria are considered before the .NET GC is invoked, and the GC itself has discretions. This is why the .NET garbage collection strategy is said to be non-deterministic.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">As an interesting aside, the .NET garbage collection comes in two different flavors. One GC is used on the server side, and the other is used for client side applications. The server GC is optimized for throughput on multiprocessor machines, and the client workstation flavor is optimized for machines with one processor. If you are interested in the differences between the two flavors, the following webpage is a good place to get educated: </span><a href="http://msdn.microsoft.com/en-us/library/s973858.aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://msdn.microsoft.com/en-us/library/s973858.aspx</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">.</span></span></p>
<h2><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">The Garbage Collection Problems in AX</span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The basic problem with the AX GC algorithm described above is that sometimes it scales poorly. The GC performs poorly in the face of an increasing number of object having loops in the object graph. The reason is that any assignment to an object may require extensive analysis to update the loop counts for all the objects in the structure. Plus this can cause significant network traffic when the objects are distributed.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Customers and internal Microsoft developers have seen a few issues that have been caused by the weakness of the AX GC strategy. The scenarios always involve structures that are self-referential containing many objects. Typically a programmer writes code that generates structures in which the objects are a monotonously increasing function of the number of records in a database table. This may work fine for test purposes, but might fail in production cases.</span></span></p>
<p><b><span style="font-family: Calibri;" face="Calibri">Workarounds</span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">There are workarounds that can be applied to reduce the problem. One workaround is to manage the reference loops through lookups in suitable structures. For example, instead of a standard direct reference, the code could store a GUID, and have an auxiliary structure to map the GUIDs onto references.</span></span></p>
<p><b><span style="font-family: Calibri;" face="Calibri">Performance Graph of Experimental Results</span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">To illustrate the problems with the AX GC, we have provided the contents of an X++ .XPO file at the end of this blog. You can import the .XPO into your test AX system. This code sample was deliberately designed to demonstrate the worst case behavior, and it does not represent code that is likely to be used in real-life applications.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The X++ sample builds a <i>circular</i> linked list of elements. After the list is built it is dismantled by taking each element out of the loop one at a time. Each time a link is removed from the list, the AX GC must rescan the whole remaining list. In this case all objects are created and destroyed on the same tier, namely the client tier.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The following graph reports the wall clock time that the AX GC consumed as we varied the number of elements our circular linked list. The test was run on a standard laptop computer. The run consumed one core 100%. </span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p align="center"><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/8883.GC%20Figure%204.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/8883.GC-Figure-4.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/86/72/8883.GC%20Figure%204.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-86-72/8883.GC-Figure-4.png" /></a></span></span></p>
<p align="center"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 4 Performance of Deterministic GC relative to .NET GC</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The x-axis is the number of elements in the circular list. The y-axis is the time spent in milliseconds on the algorithm in Appendix A.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The steeply curved green line is the performance of the deterministic AX GC. The performance degraded exponentially as the number of link nodes increased linearly.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The completely horizontal blue line is the performance achieved when the X++ code is translated into MSIL using the AX 2012 feature. For technical reasons it was not possible to sample the data with resolution of more than 1 second. The execution never managed to register a reading of more than 1 second, even when the number of nodes exceeded 350,000. Note that the x-axis extends only to 30,500.</span></span></p>
<p><b><span style="font-family: Calibri;" face="Calibri">AX GC Problems Stack Up</span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The AX deterministic GC has one other flaw. Its traversal of the object graph is recursive. This means that it (in very rare situations) can run out of C++ stack space, which invariably results in a crash on the tier doing the garbage collection (either the client or the server). We have not seen this in production code, but it is a potential problem, even for graphs that do not contain loops.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The weakness of the AX GC is serious enough that the exponential performance degradation shown by our experiment can occur even in less severe X++ samples. &nbsp;The example used in this test was chosen to show the problems in the AX 2012 GC. The example consists of object allocation and de-allocation </span><b>for</b><span style="font-family: Calibri;" face="Calibri"> loops, plus some glue to make it run. Our X++ sample can be seen as pathological in that it will produce an extreme performance benefit from being converted into MSIL. Use of the MSIL feature can be a workaround in a few cases. However, most realistic X++ code in production AX applications includes frequent reads and writes of data with the database, and those parts of your X++ code do not run any faster in MSIL mode. </span></span></p>
<p><b>&nbsp;</b></p>
<h1><span style="color: #365f91;" color="#365f91"><span style="font-family: Cambria;" face="Cambria">Appendix A: The X++ Source Code Used in the Example</span></span></h1>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">The following X++ source code contains two classes:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3">&middot;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">ListElement - the type used for the each node in the linked list.</span></span></li>
<li><span style="font-size: small;" size="3">&middot;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">GCPerformanceTest - has the static Main method to run the test.</span></span>
<ul>
<li><span style="font-size: small;" size="3">o</span>&nbsp;&nbsp; <span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Main calls ::SetupGraph, the ::TearDownGraph.</span></span></li>
</ul>
</li>
</ul>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">Please find the&nbsp;</span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">X++ source code attached.</span></span></p>
<p>&nbsp;</p>
<p></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/25/66/92/GCPerformance.xpo" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-25-66-92/GCPerformance.xpo">GCPerformance.xpo</a></p>]]></content:encoded>
    </item>
    <item>
      <title>When to use Managed Code in Dynamics AX</title>
      <link>https://docs.microsoft.com/archive/blogs/x/when-to-use-managed-code-in-dynamics-ax</link>
      <pubDate>Wed, 07 Dec 2011 16:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Peter Villadsen]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2011/12/07/when-to-use-managed-code-in-dynamics-ax/</guid>
      <description><![CDATA[&nbsp;At a Dynamics AX conference in summer 2011, I was asked for guidance on when to use C#...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">At a Dynamics AX conference in summer 2011, I was asked for guidance on when to use C# compiled to .NET Framework CIL, instead of traditional interpreted X++ compiled to p-code, in my Dynamics AX application. I will describe some deciding factors for you to consider. Some material presented herein is applies only to AX 2012, but most of it also applies to AX 2009.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">If you employ developer talent that knows managed code and Visual Studio well, it makes sense to leverage that asset. Despite its benefits, this managed (C#, VB.NET etc.) alternative does not change the fact that the main problem people have when they ramp up on business logic development projects in AX is understanding the huge code base and its many complex interactions.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In general we do not try to compete with .NET functionality: Rather we leverage .NET and implement complimentary features for X++.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The following table describes some scenarios where the C# alternative tends to be a good choice.</span></span></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr background="gray">
<td valign="top" width="217">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Scenario favoring C#</span></span></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Explanation</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Integration with 3<sup>rd</sup> party tools.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In a heterogeneous environment, it might make good sense to use C# instead of interpreted X++.&nbsp; The .NET environment is likely to have better support for emerging technologies than the X++ stack has. For instance, consider managed code if you interact with message queues or WCF.</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Web services or messaging.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">This is a common scenario for having X++ call managed code. It is easy to create a web reference to a project in Visual Studio. Visual Studio creates all the proxies and other plumbing that are needed to call the web service, which can then be consumed from X++.</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Complex algorithms.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Processes that burden the computer&rsquo;s CPU with intensive calculations may run more efficiently as managed code than as interpreted X++. The performance improvement by using managed code is sometimes dramatic.</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Deep class hierarchies.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">C# achieves major performance improvements when the logic involves many calls to virtual methods, or involves numerous assignment statements.</span></span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The following table describes some scenarios where traditional interpreted X++ tends to be a good choice.</span></span></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="217">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Scenario favoring interpreted X++</span></span></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Explanation</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Database access.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The X++ language shines with the ease of use it provides for accessing data from AX tables.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Further, applications that frequently access data do not run much faster as .NET CIL than they do as interpreted X++.</span></span></p>
</td>
</tr>
<tr>
<td valign="top" width="217">
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Many transitions across boundaries.</span></span></b></p>
</td>
<td valign="top" width="421">
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">C# might not be the best choice when using C# would result in frequent crossing of the managed / unmanaged boundary. The calls made across this boundary into managed assemblies use .NET reflection, which is orders of magnitude slower than direct managed calls.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In other words, scenarios that are chatty across the managed / unmanaged boundary are not the best candidates for C#.</span></span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">To demonstrate the faster performance offered by C# compiled to .NET CIL, X++ code for the &ldquo;towers of Hanoi&rdquo; is provided below. This algorithm features lots of recursive calls. The number of calls is an exponential function of the number of &ldquo;discs&rdquo; that is passed to the method. If there are n discs, the number of calls required is 2<sup>n</sup> -1, the so-called Mersenne numbers.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In AX 2012 we have the new luxury of being able to execute X++ as CIL code directly, which makes it easier to prove the performance benefit of CIL. However, the conclusions are the same regardless of whether the CIL is derived from X++ or C#.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Below is the contents of an .XPO file that you can import into Microsoft Dynamics AX 2012 (not into AX 2009). The .XPO contains the following two methods:</span></span></p>
<p><span style="font-family: courier new,courier;">RunInCIL</span></p>
<p><span style="font-family: courier new,courier;">RunInXppInterpreter</span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Create a simple AX job (under AOT &gt; Jobs) where you call the two methods with the same parameter value. Feel free to experiment by passing in values from 17 to 22<span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">.</span></span> After each run you should compare the time spent evaluating in p-code and in CIL. You will see that the speed advantage of CIL over p-code can grow to any order of magnitude as you increase the number of discs to move.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Note that you may see an overhead from the JIT&rsquo;ing and from loading the assembly containing the code into the current app domain the first time the code is called. Just call it again to get more meaningful numbers.</span></span></p>
<p>&nbsp;</p>
<div>
<p>Exportfile for AOT version 1.0 or later<br />Formatversion: 1</p>
<p>***Element: CLS</p>
<p>; Microsoft Dynamics AX Class: TowersOfHanoi unloaded<br />; --------------------------------------------------------------------------------<br />&nbsp; CLSVERSION 1<br />&nbsp; <br />&nbsp; CLASS #TowersOfHanoi<br />&nbsp;&nbsp;&nbsp; PROPERTIES<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #TowersOfHanoi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Origin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{A4154B6B-C58B-42AC-8335-5BCED29FF8E3}<br />&nbsp;&nbsp;&nbsp; ENDPROPERTIES<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; METHODS<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #classDeclaration<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #class TowersOfHanoi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #Hanoi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #public server static int Hanoi(int n, int fromPole, int toPole, int intermediatePole)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; if (n == 0)<br />&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; return 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; else<br />&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; return 1 + TowersOfHanoi::Hanoi(n-1, intermediatePole, fromPole, toPole) +<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TowersOfHanoi::Hanoi(n-1, toPole, intermediatePole, fromPole);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #HanoiContainer<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #private server static container HanoiContainer(container args)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; int discs, f,t,i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; [discs, f,t,i] = args;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; return [TowersOfHanoi::Hanoi(discs, f,t,i)];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #Main<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #public static void Main(Args a)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; int discs = 21;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; int endXpp, startXpp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; int endCIL, startCIL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; int result1, result2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; startXpp = WinAPIServer::getTickCount();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; result1 = TowersOfHanoi::RunInXppInterpreter(discs);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; endXpp = WinAPIServer::getTickCount();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; startCIL = WinAPIServer::getTickCount();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; result2 = TowersOfHanoi::RunInCIL(discs);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; endCIL = WinAPIServer::getTickCount();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; info (strFmt('%1 in (Ax: %2, CIL:%3)', result1, endXpp-startXpp, endCIL-startCIL));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; pause;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #RunInCIL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #public static server int RunInCIL(int i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; container c;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; new XppILExecutePermission().assert();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; c = runClassMethodIL(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classStr(TowersOfHanoi), staticMethodStr(TowersOfHanoi, HanoiContainer),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [i, 1,2,3]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; return conPeek(c, 1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE #RunInXppInterpreter<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #public server static int RunInXppInterpreter(int i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; return TowersOfHanoi::Hanoi(i, 1,2,3);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDSOURCE<br />&nbsp;&nbsp;&nbsp; ENDMETHODS<br />&nbsp; ENDCLASS</p>
<p>***Element: END</p>
<p>&nbsp;</p>
</div>
<p><span style="font-family: Calibri;" face="Calibri">&nbsp;</span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>X++ Compiler Changes in Dynamics AX 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/x/x-compiler-changes-in-dynamics-ax-2012</link>
      <pubDate>Fri, 04 Nov 2011 18:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Stella Chen]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2011/11/04/x-compiler-changes-in-dynamics-ax-2012/</guid>
      <description><![CDATA[In Microsoft Dynamics AX 2012, we made compiler changes to make the X++ language more reliable and...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: arial,helvetica,sans-serif;">In Microsoft Dynamics AX 2012, we made compiler changes to make the X++ language more reliable and to prevent problems that may cause runtime errors.</span></p>
<h2><strong><span style="font-family: %value; color: #389cc7; font-size: large;">&nbsp;1.&nbsp;&nbsp;Super() cannot Call an Abstract Method</span></strong></h2>
<p><span style="font-family: arial,helvetica,sans-serif;">Suppose an abstract method is implemented by a derived class.&nbsp; If the method in the derived class tries to call super() to reach the abstract method in the base class, the X++ compiler will report an error.&nbsp; For example:</span></p>
<div style="padding-bottom: 1pt; padding-left: 4pt; padding-right: 4pt; background: #f2dbdb; padding-top: 1pt; mso-element: para-border-div; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: accent2; mso-background-themetint: 51; border: windowtext 1pt solid;"><span style="font-family: courier new,courier;">// X++ </span>
<div>
<p><span style="font-family: courier new,courier;">class BaseClass</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;public abstract int method1()</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;{ }</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">class DerivedClass extends BaseClass</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;public int method1()</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return super();&nbsp; // Invalid call.</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;}</span><br /><span style="font-family: courier new,courier;">}</span></p>
</div>
</div>
<p><b></b>&nbsp;</p>
<p><span style="font-family: arial,helvetica,sans-serif;">&nbsp;<span style="font-size: medium;"><b>Reason for the Change</b></span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;">Abstract methods have no code body. Therefore any call to an abstract method is meaningless.</span></p>
<p><span style="font-family: arial,helvetica,sans-serif;"></span>&nbsp;</p>
<h2><span style="color: #4f81bd;" color="#4f81bd">2.&nbsp;&nbsp;All Default Parameters are required to follow the Last Non-default</span></h2>
<p><span style="font-family: arial,helvetica,sans-serif;" size="3"><span face="Calibri">The X++ compiler rejects any method parameter signature which lists a default parameter before the last regular non-default parameter.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;" size="3"><span face="Calibri">In the following X++ method signatures, parameter &lsquo;i&rsquo; is a default parameter that causes both methods to fail to compile.</span></span></p>
<p></p>
<div style="padding-bottom: 1pt; padding-left: 4pt; padding-right: 4pt; background: #f2dbdb; padding-top: 1pt; mso-element: para-border-div; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: accent2; mso-background-themetint: 51; border: windowtext 1pt solid;">
<div>
<p><span style="font-family: courier new,courier;">public void myInvalidMethod1(int i=1, int q) { }&nbsp; // Invalid signature</span></p>
<p><span style="font-family: courier new,courier;">public void myInvalidMethod2(int i=1, int q, int r=8) { }&nbsp; // Invalid signature</span></p>
</div>
</div>
<p><span style="font-family: arial,helvetica,sans-serif;"><b><span face="Calibri"></span></b></span>&nbsp;</p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: medium;"><b><span face="Calibri">Reason for the Change</span></b></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3" face="Calibri">It does not make sense to have non-default parameters follow default parameters. In such cases all calls to the method must provide an explicit value for the default parameter, and the parameter could never take its default. Therefore it understandable that .NET CIL does not support such cases. Starting in AX 2012 the X++ compiler no longer supports such cases either, to be compatible with CIL.</span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>
<h2><span style="color: #4f81bd;" color="#4f81bd">3.&nbsp;&nbsp;Methods that Override Should Match the Parent Signature</span></h2>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">When a method in a derived class has the same name as a method in its base class, the X++ compiler requires the exact same parameter signature for the two methods. Also, both methods must have the exact same return type. Otherwise the derived class will fail to compile.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;"><span style="font-size: small;" size="3" face="Calibri">For example, in AX 2012 under AOT &gt; Classes, the X++ abstract class </span>SysAttribute<span style="font-size: small;" size="3" face="Calibri"> is extended by the class </span>SrsReportNameAttribute<span style="font-size: small;" size="3" face="Calibri">. Therefore an instance of </span>SrsReportNameAttribute<span style="font-size: small;" size="3" face="Calibri"> can be passed to a method that takes a parameter of type </span>SysAttribute<span style="font-size: small;" size="3"><span face="Calibri">. But for overriding a method, these two types would not be considered an exact match, and the X++ compiler would not consider these two types to be the exact same kind of parameter or return type.</span></span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;"><span style="font-size: small;" size="3" face="Calibri">In the following X++ code example, the </span>MyDerivedClass<span style="font-size: small;" size="3"><span face="Calibri">would fail to compile:</span></span></span><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>
<div style="padding-bottom: 1pt; padding-left: 4pt; padding-right: 4pt; background: #f2dbdb; padding-top: 1pt; mso-element: para-border-div; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: accent2; mso-background-themetint: 51; border: windowtext 1pt solid;">
<p><span style="font-family: courier new,courier;">// X++</span></p>
<p><span style="font-family: courier new,courier;">class MyBaseClass</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;protected void getAttribute(SysAttribute _sysAttrib) { }</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p></p>
<p><span style="font-family: courier new,courier;">class MyDerivedClass extends MyBaseClass</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;protected void getAttribute(SrsReportNameAttribute _srsReportNameAttrib) <br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: courier new,courier;">{&nbsp;&nbsp; </span><span style="font-family: courier new,courier;">}</span><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; //will not compile</span><br /><span style="font-family: courier new,courier;">}</span></p>
</div>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">&nbsp;</span><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">Further, no default parameter can exactly match a non-default parameter, or vice verse. The number of parameters must also match. X++ supports method overriding, but not method overloading.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">These rules also apply when a class implements an interface.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: medium;"><b><span face="Calibri">Reason for the Change</span></b></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">Without this new restriction enforced by the X++ compiler, these incompatibility errors would be detected only during run time. The above X++ code example would compile in AX 2009, but in AX 2012 the X++ compiler will reject this example.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>
<h2><span style="color: #4f81bd;" color="#4f81bd">4.&nbsp;&nbsp;Interface Implementation Must be Complete</span></h2>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">An X++ class that implements an interface must provide code for all the methods of the interface. This includes any methods the interface inherits from another interface.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;"><span style="font-size: small;" size="3" face="Calibri">In the following X++ code example, </span>BadClass<span style="font-size: small;" size="3"><span face="Calibri"> fails to compile in AX 2012:</span></span></span></p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 4.0pt 1.0pt 4.0pt; background: #F2DBDB; mso-background-themecolor: accent2; mso-background-themetint: 51;">
<p><span style="font-family: courier new,courier;">// X++</span></p>
<p><span style="font-family: courier new,courier;">interface IF1</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;void method3();</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">interface IF2 extends IF1</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;void method4();</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">class BadClass implements IF2&nbsp;&nbsp;&nbsp;// Fails to compile, is missing method3.</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;public void method4()</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;{ }</span><br /><span style="font-family: courier new,courier;">}</span></p>
</div>
<p><span style="font-size: medium;"><span style="font-family: arial,helvetica,sans-serif;"><b><span face="Calibri"></span></b></span></span>&nbsp;</p>
<p><span style="font-size: medium;"><span style="font-family: arial,helvetica,sans-serif;"><b><span face="Calibri">Reason for the Change</span></b></span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">Same as for item 3 above.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri"></span></span>&nbsp;</p>
<h2><span style="color: #4f81bd;" color="#4f81bd">5.&nbsp;&nbsp;The Same Method Name cannot be Inherited from both Base Class and Interface</span></h2>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">Suppose a derived class both extends a base class and implements an interface.&nbsp; And suppose that the base class and the interface specify the same method name. The X++ compiler no longer tolerates this situation.</span></span></p>
<p><span style="font-family: arial,helvetica,sans-serif;"><span style="font-size: small;" size="3" face="Calibri">In the following X++ code example, the </span>SadClass<span style="font-size: small;" size="3"><span face="Calibri"> class fails to compile in AX 2012:</span></span></span></p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 4.0pt 1.0pt 4.0pt; background: #F2DBDB; mso-background-themecolor: accent2; mso-background-themetint: 51;">
<p><span style="font-family: courier new,courier;">// X++</span></p>
<p><span style="font-family: courier new,courier;">abstract class YourClass</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;void method5() { }</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">interface YourIF</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;void method5() { }</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">// SadClass fails to compile, because the name 'method5' is inherited twice.</span></p>
<p><span style="font-family: courier new,courier;">class SadClass extends YourClass implements YourIF</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;public void method5()</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info("Hello World.";)</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;}</span><br /><span style="font-family: courier new,courier;">}</span></p>
</div>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: medium;"><b><span face="Calibri">Reason for the Change</span></b></span></p>
<p><span style="font-family: arial,helvetica,sans-serif; font-size: small;" size="3"><span face="Calibri">Same as for item 3 above.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>New Option to Log X++ Max-Length String Truncation</title>
      <link>https://docs.microsoft.com/archive/blogs/x/new-option-to-log-x-max-length-string-truncation</link>
      <pubDate>Thu, 06 Oct 2011 15:13:00 GMT</pubDate>
      <dc:creator><![CDATA[Karl Simonsen]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/x/2011/10/06/new-option-to-log-x-max-length-string-truncation/</guid>
      <description><![CDATA[In X++ you can optionally declare a string to have a specified maximum length:
&nbsp;
str 5...]]></description>
      <content:encoded><![CDATA[<p><meta name="ProgId" content="Word.Document" /><meta name="Generator" content="Microsoft Word 14" /><meta name="Originator" content="Microsoft Word 14" /><link rel="File-List" href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/LogStrTruncBlog-KarlSimonsen-20110930_files/filelist.xml" /><link rel="themeData" href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/LogStrTruncBlog-KarlSimonsen-20110930_files/themedata.thmx" /><link rel="colorSchemeMapping" href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/LogStrTruncBlog-KarlSimonsen-20110930_files/colorschememapping.xml" /></p>
<p class="MsoNormal">In X++ you can optionally declare a string to have a specified maximum length:</p>
<p class="MsoNormal">&nbsp;</p>
<p style="padding-left: 30px;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; font-family: Consolas;">str <span style="color: #ff0000;">5</span> maxLen5String;</span></p>
<p style="padding-left: 30px;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; font-family: Consolas;"><o:p><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; font-family: Consolas;"></span></o:p></span>&nbsp;</p>
<p class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;">Semantically, if you try to store more than 5 characters to this string, it will be truncated.</span></p>
<p class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><o:p><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"></span></o:p></span>&nbsp;</p>
<p class="MsoNormal">In March 2010 we blogged <a href="http://blogs.msdn.com/b/x/archive/2010/03/16/more-help-needed-from-community-do-you-rely-on-string-truncation.aspx">here</a> about the X++ max-length string type, and asked how we should handle it in Microsoft Dynamics AX 2012. This became an issue when we began to compile X++ into .NET Framework CIL (Common Intermediate Language). X++ has the concept of a max-length string, but CIL does not. Thus an inconsistency in behavior was to be introduced. X++ max-length strings are truncated as necessary when the X++ runs in interpreted mode, but they are <i style="mso-bidi-font-style: normal;">not</i> truncated when the X++ runs as CIL.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Respondents to our earlier blog were generally indifferent to whether we truncated strings in interpreted X++ or not. But we were also concerned about backward compatibility. After much discussion we decided that interpreted X++ should continue string truncation in AX 2012, just as it has done in earlier versions of AX. In other words, we were willing to live with the inconsistency with CIL.</p>
<p class="MsoNormal"><o:p></o:p>&nbsp;</p>
<p class="MsoNormal">However, as part of this discussion we wanted to be able to easily analyze this to better understand what this inconsistency would mean in real-world code. To that end, we added an option to log where string truncation was actually happening in the interpreter (and, by extension, where it would <i style="mso-bidi-font-style: normal;">not</i> be happening in CIL).</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">We found this option to be so beneficial that we decided to productize it so that everyone could benefit.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal"><br />&nbsp;</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;">New Option to Log String Truncations</span></b></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b></o:p></span>&nbsp;</p>
<p class="MsoNormal">The name of the new switch that activates the logging of string truncations is <b style="mso-bidi-font-weight: normal;">logstrtrunc</b>. The switch is honored by both the AX client and the AX server. <b style="mso-bidi-font-weight: normal;">Logstrtrunc </b>is off by default since there is some performance cost associated with it.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">As with most AX option switches, <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> can be specified on either the command line or in the Windows Registry. Whenever the command line and the Registry conflict, the command line value takes precedence.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;">Command Line Syntax<o:p></o:p></span></b></p>
<ul>
<ul>
<li>
<div style="text-indent: -.25in; mso-list: l2 level1 lfo2;" class="MsoListParagraphCxSpFirst"><span style="font-size: 10.0pt; line-height: 115%; font-family: Consolas;">Ax32.exe<span style="mso-spacerun: yes;">&nbsp; </span>-logstrtrunc<o:p></o:p></span></div>
</li>
<li>
<div style="text-indent: -.25in; mso-list: l2 level1 lfo2;" class="MsoListParagraphCxSpLast"><span style="font-size: 10.0pt; line-height: 115%; font-family: Consolas;">Ax32serv.exe<span style="mso-spacerun: yes;">&nbsp; </span>-logstrtrunc</span></div>
</li>
</ul>
</ul>
<p style="text-indent: -0.25in; padding-left: 30px; mso-list: l2 level1 lfo2;" class="MsoListParagraphCxSpLast"><span style="font-size: 10.0pt; line-height: 115%; font-family: Consolas;"></span><span style="font-size: 9.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;">Note:<span style="mso-spacerun: yes;">&nbsp; </span><b style="mso-bidi-font-weight: normal;">/logstrtrunc</b><span style="mso-spacerun: yes;">&nbsp; </span>is invalid syntax.<span style="mso-spacerun: yes;">&nbsp; </span>The option name must be preceded by a dash (-).</span><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;"><o:p></o:p></span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;">Registry Keys</span></b></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%;"></span></b></o:p></span></b>&nbsp;</p>
<p class="MsoNormal">Alternatively, an optional Windows Registry key for the <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> option can added, either manually using regedit.exe, or by double-clicking on a .REG file containing the following data:</p>
<p class="MsoNormal">&nbsp;</p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 4.0pt 1.0pt 4.0pt; margin-left: .5in; margin-right: 0in;" class="WordSection1">
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt;">REGEDIT4<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt;"><o:p>&nbsp;</o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt;"><span style="mso-spacerun: yes;">&nbsp;</span>[HKEY_CURRENT_USER\SOFTWARE\Microsoft<b style="mso-bidi-font-weight: normal;">\Dynamics\</b>6.0\Configuration\Original (installed configuration)]<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 8.0pt;">"logstrtrunc"=dword:00000001<o:p></o:p></span></b></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt;"><o:p>&nbsp;</o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt;">[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services<b style="mso-bidi-font-weight: normal;">\Dynamics Server\</b>6.0\01\Original (installed configuration)]<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 8.0pt;">"logstrtrunc"=dword:00000001<o:p></o:p></span></b></p>
</div>
<p style="margin-top: 0in; margin-right: 0in; margin-bottom: .0001pt; margin-left: .5in; line-height: normal;" class="MsoNormal"><span style="font-size: 8.0pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The first key contains the path node of <b style="mso-bidi-font-weight: normal;">\Dynamics\</b>, indicating that it applies to the Ax32.exe client. The second key contains the path node of <b style="mso-bidi-font-weight: normal;">\Dynamics Server\</b>, indicating that it applies to the Ax32serv.exe server. Either or both may be specified. The registry key option is especially useful for the Server (AOS), which is usually run as a service and not from the command line directly.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">After these keys are in the Registry, you can turn this <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> option off and on by toggling the dword value between 0 and 1 respectively. Remember to disable the key after you are done testing to avoid any performance impact.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The client and server read these Registry keys only when they start running, so you will need to restart the session before your change will take effect.</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="text-decoration: underline;"><o:p><span style="text-decoration: none;"></span></o:p></span></b>&nbsp;</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;">Effect of logstrtrunc Option</span></b></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b></o:p></span>&nbsp;</p>
<p class="MsoNormal">When the logstrtrunc option is on, every time an X++ max-length string gets truncated, the system writes an entry to the Application section of the Windows Event Log. You can view these entries by using the Windows Event Viewer. In each entry the Source and Event ID values are as follows:</p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: .0001pt; margin-left: .5in; text-indent: -.25in; line-height: normal; mso-list: l1 level1 lfo3;" class="MsoListParagraph"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&middot;<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Consolas;">Source:<o:p></o:p></span></p>
<p style="margin-top: 0in; margin-right: 0in; margin-bottom: .0001pt; margin-left: 1.0in; text-indent: -.25in; line-height: normal; mso-list: l1 level2 lfo3;" class="MsoListParagraph"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; mso-fareast-font-family: 'Courier New';"><span style="mso-list: Ignore;">o<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp; </span></span></span><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Consolas;">Client:&nbsp;&nbsp;&nbsp;"Microsoft Dynamics AX"<o:p></o:p></span></p>
<p style="margin-top: 0in; margin-right: 0in; margin-bottom: 6.0pt; margin-left: 1.0in; text-indent: -.25in; line-height: normal; mso-list: l1 level2 lfo3;" class="MsoListParagraph"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: 'Courier New'; mso-fareast-font-family: 'Courier New';"><span style="mso-list: Ignore;">o<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp; </span></span></span><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Consolas;">Server:&nbsp;&nbsp;&nbsp;"Dynamics Server 01"<o:p></o:p></span></p>
<p style="margin-top: 6.0pt; margin-right: 0in; margin-bottom: .0001pt; margin-left: .5in; text-indent: -.25in; line-height: normal; mso-list: l1 level1 lfo3;" class="MsoListParagraph"><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;">&middot;<span style="font: 7.0pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 10.0pt; mso-bidi-font-size: 11.0pt; font-family: Consolas;">Event ID:&nbsp;&nbsp;191<o:p></o:p></span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal">These values are very useful for filtering and sorting when you want to locate the relevant log entries in the event log. Of course, if your X++ code contains no max-length strings or if none of the assignments to your max-length strings exceed the length boundaries, nothing will be written to the log. We will now focus on what to do if log entries do show up.</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><o:p></o:p>&nbsp;</p>
<p style="page-break-after: avoid;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;">Code Example and Sample Log Entries</span></b></p>
<p style="page-break-after: avoid;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b></o:p></span>&nbsp;</p>
<p class="MsoNormal">Here is a simple X++ job which assigns excessively long values to a max-length string. Assume you run this job in interpreted mode with logstrtrunc on:</p>
<p class="MsoNormal">&nbsp;</p>
<div style="mso-element: para-border-div; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 1.0pt 4.0pt 1.0pt 4.0pt;" class="WordSection1">
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas; color: #006600;">1<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><i style="mso-bidi-font-style: normal;">// Compile and run this X++ job to see two different forms of string truncation.</i><o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">2<b><span style="color: darkblue;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>static</span></b> <b><span style="color: darkblue;">void</span></b> Job1(Args _args)<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">3<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">4<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><b><span style="color: darkblue;">str</span></b> <b><span style="color: red;">5</span></b> maxStringBuffer;<span style="mso-spacerun: yes;">&nbsp; </span><i style="mso-bidi-font-style: normal;"><span style="color: #006600;">// Maximum length is 5.</span></i><o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">5<o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">6<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>maxStringBuffer = <span style="color: darkred;">'Hello world'</span>; <span style="mso-spacerun: yes;">&nbsp;&nbsp;</span><i style="mso-bidi-font-style: normal;"><span style="color: #006600;">// Assignment leaves maxStringBuffer == 'Hello'.</span></i><o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">7<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>maxStringBuffer += <span style="color: darkred;">' there world'</span>; <i style="mso-bidi-font-style: normal;"><span style="color: #006600;">// Append attempt leaves maxStringBuffer == 'Hello'.</span></i><o:p></o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none; border: none; mso-border-alt: solid windowtext .5pt; padding: 0in; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt;" class="MsoNormal"><span style="font-size: 8.0pt; font-family: Consolas;">8<span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
</div>
<p style="margin-bottom: .0001pt; line-height: normal; mso-layout-grid-align: none; text-autospace: none;" class="MsoNormal"></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Code line 6 attempts the <i style="mso-bidi-font-style: normal;">assignment</i> of an excessively long string which will be truncated. The body of the event log entry message displays the whole value that the X++ code attempted to assign so that you can see what was truncated:</p>
<p class="MsoNormal">&nbsp;</p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">X++ str 5 buffer truncated during <b style="mso-bidi-font-weight: normal;">assignment</b>:<o:p></o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">Hello world<o:p></o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><o:p>&nbsp;</o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">Stack trace</span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"></span>&nbsp;</p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">(C)\Jobs\Job1 - line 6</span></p>
<p></p>
<p></p>
<p class="MsoNormal">Code line 7 attempts to make the <i style="mso-bidi-font-style: normal;">concatenation</i> of two strings be the new value of a maxStringBuffer. In this case the message displays both strings that were involved in the concatenation so that you can figure out what got truncated:</p>
<p class="MsoNormal">&nbsp;</p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">X++ str 5 buffer truncated during <b style="mso-bidi-font-weight: normal;">concatenation</b>:<o:p></o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">Hello<o:p></o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><span style="mso-spacerun: yes;">&nbsp;</span>there world<o:p></o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"><o:p>&nbsp;</o:p></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">Stack trace</span></p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;"></span>&nbsp;</p>
<p style="line-height: normal; margin: 0in 0in 0pt 0.5in; padding-left: 30px; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-size: 10.0pt; mso-bidi-font-size: 8.0pt; font-family: Consolas;">(C)\Jobs\Job1 - line 7<o:p></o:p></span></p>
<p style="line-height: normal; margin-bottom: 0pt;" class="MsoNormal"><span style="font-size: 9.0pt; font-family: 'Segoe UI','sans-serif';"><o:p>&nbsp;</o:p></span></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Notice that a stack trace is included, which is very helpful in more complicated examples.</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><o:p></o:p>&nbsp;</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;">Analysis Considerations</span></b></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; mso-bidi-font-size: 11.0pt; line-height: 115%; color: #0070c0;"></span></b></o:p></span>&nbsp;</p>
<p class="MsoNormal">Assume your system has several log entries from <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> being on. These entries could result for a number of different reasons.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">The following table categorizes some possible causes of those log entries and in each case a possible approach that can eliminate the automatic truncation of strings (and eliminate future log entries). In many cases, this will allow you to fix real &ldquo;bugs&rdquo; and also eliminate any discrepancies when run interpreted versus run as CIL:</p>
<p class="MsoNormal">&nbsp;</p>
<div class="WordSection1">
<table style="border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; background: #D9D9D9; mso-background-themecolor: background1; mso-background-themeshade: 217; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt;">Case <o:p></o:p></span></b></p>
</td>
<td style="width: 153.0pt; border: solid windowtext 1.0pt; border-left: none; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; background: #D9D9D9; mso-background-themecolor: background1; mso-background-themeshade: 217; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt;">Reason for using maximum-length string<o:p></o:p></span></b></p>
</td>
<td style="width: 288.9pt; border: solid windowtext 1.0pt; border-left: none; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; background: #D9D9D9; mso-background-themecolor: background1; mso-background-themeshade: 217; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt;">Suggested solution<o:p></o:p></span></b></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 12.0pt; mso-bidi-font-size: 11.0pt;"><o:p>&nbsp;</o:p></span></b></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">A</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Testing automatic truncation.</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Remove the X++ logic before deploying to production.</p>
</td>
</tr>
<tr style="mso-yfti-irow: 2; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">B</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">No good reason.</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Perhaps erase the max-length specifier from the declaration of the X++ string variable.</p>
</td>
</tr>
<tr style="mso-yfti-irow: 3; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">C</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Purposely relying on automatic (implicit) truncation.</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Add logic to your X++ code to explicitly truncate the max-length string as needed.</p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Then eliminate the max-length specifier from the declaration of the X++ string variable.</p>
</td>
</tr>
<tr style="mso-yfti-irow: 4; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">D</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Max-length intended to match table or form field length.</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Consider whether the table field is actually long enough. You might lengthen the field so that no more truncations are needed. Or, you might have to shorten the length of the content your code assigns to the string or field.</p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">EDTs are a common example of max-length strings of that exhibit this behavior.</p>
</td>
</tr>
<tr style="mso-yfti-irow: 5; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">E</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">String content is longer after translation from into a foreign language (localization or globalization)</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">A string in your native tongue that easily fits into an 80 character buffer might need a buffer of 100 characters or more in another language.</p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Truncations in this situation suggest a bug in your X++ code, regardless of CIL. Running scenarios with localized versions of the product is a great way to benefit from the <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> option.</p>
</td>
</tr>
<tr style="mso-yfti-irow: 6; mso-yfti-lastrow: yes; page-break-inside: avoid;">
<td style="width: 36.9pt; border: solid windowtext 1.0pt; border-top: none; mso-border-top-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="62">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">F</p>
</td>
<td style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="255">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">Pretty truncation.</p>
</td>
<td style="width: 288.9pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top" width="482">
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">In a few cases, such as displaying long path names, it can be appropriate to provide a &ldquo;pretty&rdquo; truncation. For example, the following shortened representation of a full path conveniently conveys the information that the reader needs most:</p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">&ldquo;c:\users\MyName\...\MyBlog.doc&rdquo;</p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p style="margin-bottom: .0001pt; line-height: normal;" class="MsoNormal">In such cases you should substitute your own truncation logic instead of letting the interpreter perform automatic truncation.</p>
</td>
</tr>
</tbody>
</table>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 115%; color: #0070c0;"></span></b>&nbsp;</p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 115%; color: #0070c0;">Try Various Scenarios</span></b></p>
<p class="MsoNormal"><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 115%; color: #0070c0;"></span></b><span style="font-size: 16.0pt; line-height: 115%; color: #0070c0;"><o:p><b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 115%; color: #0070c0;"></span></b></o:p></span>&nbsp;</p>
<p class="MsoNormal">With <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> on in your test environment, run several different scenarios to give all possible string truncation code the greatest likelihood of truncating and thus being logged. Scenarios that involve localization can be very important to test. The resulting log information should enable you to understand and eliminate any unwanted automatic truncations that can occur when X++ runs in interpreted mode.</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">In summary, the <b style="mso-bidi-font-weight: normal;">logstrtrunc</b> option makes it easy for X++ developers to track down any potential string truncation discrepancies associated with compiling X++ to .NET CIL.</p>]]></content:encoded>
    </item>
  </channel>
</rss>