<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Art Of Creation - Dynamics AX Blog &#187; Batch</title>
	<atom:link href="http://www.artofcreation.be/tag/batch/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.artofcreation.be</link>
	<description>The everyday life of a Dynamics AX developer</description>
	<lastBuildDate>Thu, 02 Feb 2012 12:20:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>AX2012: SysOperation part 3: SysOperationAutomaticUIBuilder</title>
		<link>http://www.artofcreation.be/2011/08/24/ax2012-sysoperation-part-3-sysoperationautomaticuibuilder/</link>
		<comments>http://www.artofcreation.be/2011/08/24/ax2012-sysoperation-part-3-sysoperationautomaticuibuilder/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 10:00:00 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[2012]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[SysOperation]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=1279</guid>
		<description><![CDATA[Hi everyone. This is the third and final part in my series of posts about SysOperation (at least for now). You can find part 1 here and part 2 here. I will demonstrate how to override methods on the dialog (in this case modified()), and how to read and set properties of controls. For the [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everyone. </p>
<p>This is the third and final part in my series of posts about SysOperation (at least for now). You can find part 1 <a href="http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/">here </a>and part 2 <a href="http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/">here</a>. </p>
<p>I will demonstrate how to override methods on the dialog (in this case modified()), and how to read and set properties of controls. </p>
<p>For the sake of this demo, we will add a checkbox to the dialog that will allow us to set the <strong>enabled </strong>property of the date control.<br />
It should look like this:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/CheckboxChecked.png" alt="" title="CheckboxChecked" width="620" height="320" class="aligncenter size-full wp-image-1370" /></p>
<h3>1. Modify the data contract</h3>
<p>We will need to modify the data contract so a checkbox is displayed on the dialog that we can use to enable or disable the date control. </p>
<p>Add this variable to the class declaration of the <strong>KlForCustTesterDataContract </strong>class:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; NoYesId &nbsp; &nbsp; allowModifyDate;</div></div>
<p>Then add this method to that same data contract</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataMemberAttribute<span style="color: #00007f;">,</span><br />
SysOperationLabelAttribute<span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Enable date control&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">public</span> NoYesId parmAllowModifyDate<span style="color: #000000;">&#40;</span>NoYesId _allowModifyDate <span style="color: #00007f;">=</span> allowModifyDate<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; allowModifyDate <span style="color: #00007f;">=</span> _allowModifyDate;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> allowModifyDate;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>There&#8217;s nothing new here, we already did all of this in <a href="http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/">part 1</a></p>
<h3>2. Extending SysOperationAutomaticUIBuilder</h3>
<p>We will extend the SysOperationAutomaticUIBuilder class so we can override methods and properties of controls on our dialog. </p>
<p>First, create a new class, KlForCustTesterUIBuilder:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">class</span> KlForCustTesterUIBuilder <span style="color: #0000ff;">extends</span> SysOperationAutomaticUIBuilder<br />
<span style="color: #000000;">&#123;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Things we will need in this class are:</p>
<ol>
<li>a variable for the date control</li>
<li>a variable for the new checkbox control</li>
<li>our data contract</li>
</ol>
<p>So we add these variables to the class declaration:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">class</span> KlForCustTesterUIBuilder <span style="color: #0000ff;">extends</span> SysOperationAutomaticUIBuilder<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; DialogField &nbsp; &nbsp; dialogFieldAllowModifyDate;<br />
&nbsp; &nbsp; DialogField &nbsp; &nbsp; dialogFieldTransDate;<br />
<br />
&nbsp; &nbsp; KlForCustTesterDataContract klForCustTesterDataContract;<br />
<span style="color: #000000;">&#125;</span></div></div>
<h3>2.1 Adding the override method</h3>
<p>We will first write the method that will override the modified of the checkbox control. Simply add a new method to the KlForCustTesterUIBuilder class:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span> allowModifyDateModified<span style="color: #000000;">&#40;</span>FormCheckBoxControl _checkBoxControl<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// set enabled or disabled based on checkbox</span><br />
&nbsp; &nbsp; dialogFieldTransDate.<span style="color: #000000;">enabled</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">any2enum</span><span style="color: #000000;">&#40;</span>dialogFieldAllowModifyDate.<span style="color: #000000;">value</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// or alternatively</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// dialogFieldTransDate.enabled(_checkBoxControl.checked());</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>The code above sets the enabled method on the dialogFieldTransDate object based on the value property of dialogFieldAllowModifyDate object, or alternatively, the _checkBoxControl variable.<br />
As you may remember, we declared the DialogField variables in the class declaration. Of course we will still have to initialize these variables , and that&#8217;s what we&#8217;ll do when overriding the postBuild method. </p>
<h3>2.2 Overwriting the postBuild method</h3>
<p>Next, we need to override the postBuild method on our KlForCustTesterUIBuilder class. This method will be called after the dialog is created, so it is a good place to put our logic. </p>
<p>Override the method:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> postBuild<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Next, let&#8217;s add some code to this method, starting with the code that retrieves the data contract object, which is pretty easy:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> postBuild<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> this.<span style="color: #000000;">dataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Next, we retrieve the DialogField objects:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> postBuild<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> this.<span style="color: #000000;">dataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get dialog fields</span><br />
&nbsp; &nbsp; dialogFieldTransDate &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmTransDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; dialogFieldAllowModifyDate &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmAllowModifyDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>In the code above, the <strong>bindInfo() </strong>method returns an object of type <strong>SysOperationUIBindInfo</strong>. This contains information about which dialog controls the data members are bound to. By providing a reference to the parmTransDate and parmAllowModifyDate member when calling the <strong>getDialogField()</strong> method, we get the dialog control that is associated with each member. </p>
<p>Next, we will register the method we want to override:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> postBuild<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> this.<span style="color: #000000;">dataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get dialog fields</span><br />
&nbsp; &nbsp; dialogFieldTransDate &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmTransDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; dialogFieldAllowModifyDate &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmAllowModifyDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// register override methods</span><br />
&nbsp; &nbsp; dialogFieldAllowModifyDate.<span style="color: #000000;">registerOverrideMethod</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>FormCheckBoxControl<span style="color: #00007f;">,</span> modified<span style="color: #000000;">&#41;</span><span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterUIBuilder<span style="color: #00007f;">,</span> allowModifyDateModified<span style="color: #000000;">&#41;</span><span style="color: #00007f;">,</span> this<span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>As you can see, we can use the registerOverrideMethod() method to override methods on dialog. This is a huge improvement over overriding methods on dialogs in 2009. We simply point to the method we want to override (FormCheckBoxControl.modified) and the method the needs to be executed (KlForCustTesterUIBuilder.allowModifyDateModified). </p>
<p>Finally, we initialize the value of the enabled property, and the complete method will look like this:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> postBuild<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> this.<span style="color: #000000;">dataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// get dialog fields</span><br />
&nbsp; &nbsp; dialogFieldTransDate &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmTransDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; dialogFieldAllowModifyDate &nbsp;<span style="color: #00007f;">=</span> this.<span style="color: #000000;">bindInfo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">getDialogField</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterDataContract<span style="color: #00007f;">,</span> parmAllowModifyDate<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// register override methods</span><br />
&nbsp; &nbsp; dialogFieldAllowModifyDate.<span style="color: #000000;">registerOverrideMethod</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>FormCheckBoxControl<span style="color: #00007f;">,</span> modified<span style="color: #000000;">&#41;</span><span style="color: #00007f;">,</span> <span style="color: #0000ff;">methodstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterUIBuilder<span style="color: #00007f;">,</span> allowModifyDateModified<span style="color: #000000;">&#41;</span><span style="color: #00007f;">,</span> this<span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// enable/disable transdate based on checkbox</span><br />
&nbsp; &nbsp; dialogFieldTransDate.<span style="color: #000000;">enabled</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">any2enum</span><span style="color: #000000;">&#40;</span>dialogFieldAllowModifyDate.<span style="color: #000000;">value</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<h3>3. One more attribute</h3>
<p>Now, we&#8217;ve created the UIBuilder class, but we still have to link it to our data contract. That&#8217;s what the <strong>SysOperationContractProcessingAttribute </strong>attribute is for. </p>
<p>To link the UIBuilder class to the data contract, open the <strong>classDeclaration</strong> method of the <strong>KlForCustTesterDataContract</strong> class, and add the <strong>SysOperationContractProcessingAttribute</strong>:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataContractAttribute<span style="color: #00007f;">,</span><br />
&nbsp; &nbsp; SysOperationContractProcessingAttribute<span style="color: #000000;">&#40;</span><span style="color: #0000ff;">classstr</span><span style="color: #000000;">&#40;</span>KlForCustTesterUIBuilder<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">class</span> KlForCustTesterDataContract<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; Name &nbsp; &nbsp; &nbsp; &nbsp;name;<br />
&nbsp; &nbsp; TransDate &nbsp; transDate;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">str</span> &nbsp; &nbsp; &nbsp; &nbsp; packedQuery;<br />
<br />
&nbsp; &nbsp; NoYesId &nbsp; &nbsp; allowModifyDate;<br />
<span style="color: #000000;">&#125;</span></div></div>
<h3>4. Testing!</h3>
<p>But wait (you already know what I&#8217;m going to say right), first click the Generate Incremental CIL button to generate CIL.<br />
<img src="http://www.artofcreation.be/wp-content/uploads/generateCIL.png" alt="" title="generateCIL" width="634" height="99" class="aligncenter size-full wp-image-1229" /></p>
<p>Right click the KlForCustTesterServiceController menu item we created on day 2, and choose open. You should see this dialog:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/CheckboxUnChecked.png" alt="" title="CheckboxUnChecked" width="620" height="320" class="aligncenter size-full wp-image-1371" /><br />
When you check the checkbox, you should see that the date field is enabled.<br />
<img src="http://www.artofcreation.be/wp-content/uploads/CheckboxChecked.png" alt="" title="CheckboxChecked" width="620" height="320" class="aligncenter size-full wp-image-1370" /></p>
<p><a href="http://www.artofcreation.be/wp-content/SharedProject_KlFor_SysOperation_Day3.xpo">Download the XPO for part 3 here</a>. </p>
<p>That concludes my blog posts about SysOperation, I hope you like it, and I&#8217;m looking forward to your feedback.<br />
Have fun making batches!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2011/08/24/ax2012-sysoperation-part-3-sysoperationautomaticuibuilder/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>AX2012: SysOperation part 2: SysOperationServiceController</title>
		<link>http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/</link>
		<comments>http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 10:20:31 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[2012]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[SysOperation]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=1258</guid>
		<description><![CDATA[Hi again. In part 1, we created a nice batch using data contracts, service operation and the SysOperationServiceController class. Today, we will place our menu item on the Customers form, so we can process the customer that is selected in the grid. It will look like this: A thing that is still missing though, is [...]]]></description>
			<content:encoded><![CDATA[<p>Hi again. </p>
<p>In <a href="http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/">part 1</a>, we created a nice batch using data contracts, service operation and the SysOperationServiceController class. </p>
<p>Today, we will place our menu item on the Customers form, so we can process the customer that is selected in the grid. It will look like this:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/Customers-form.png" alt="" title="Customers form" width="600" height="244" class="aligncenter size-full wp-image-1266" /><br />
A thing that is still missing though, is a way to work with the Args that are passed when a menu item is executed. We want to be able to set the query on our data contract before showing the batch dialog. We might also want to have a default value in some fields, for example, the date should be today&#8217;s date every time we launch the dialog.<br />
We can do all of that by extending the SysOperationServiceController class. </p>
<p>So let&#8217;s do that!</p>
<p>Create a new class that extends SysOperationServiceController</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">class</span> KlForCustTesterServiceController <span style="color: #0000ff;">extends</span> SysOperationServiceController<br />
<span style="color: #000000;">&#123;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Now let&#8217;s create a method that constructs an instance of this class based on the Args object</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> KlForCustTesterServiceController newFromArgs<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; KlForCustTesterServiceController &nbsp; &nbsp;klForCustTesterServiceController;<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// create a new instance of the controller</span><br />
&nbsp; &nbsp; klForCustTesterServiceController <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> KlForCustTesterServiceController<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// initialize from args</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// one of the things this will do is read the &quot;parameters&quot; property from the menu item </span><br />
&nbsp; &nbsp; klForCustTesterServiceController.<span style="color: #000000;">initializeFromArgs</span><span style="color: #000000;">&#40;</span>_args<span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// return a new instance of this controller</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> klForCustTesterServiceController;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Above is the basic code that should be in your construct method. However, this doesn&#8217;t do anything more than the SysOperationServiceController already does, so let&#8217;s add the logic that sets the date to today&#8217;s date.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> KlForCustTesterServiceController newFromArgs<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; KlForCustTesterServiceController &nbsp; &nbsp;klForCustTesterServiceController;<br />
&nbsp; &nbsp; klForCustTesterDataContract &nbsp; &nbsp; klForCustTesterDataContract<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// create a new instance of the controller</span><br />
&nbsp; &nbsp; klForCustTesterServiceController <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> KlForCustTesterServiceController<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// initialize from args</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// one of the things this will do is read the &quot;parameters&quot; property from the menu item </span><br />
&nbsp; &nbsp; klForCustTesterServiceController.<span style="color: #000000;">initializeFromArgs</span><span style="color: #000000;">&#40;</span>_args<span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// the string should be the same as the parameter name!</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> klForCustTesterServiceController.<span style="color: #000000;">getDataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">'_klForCustTesterDataContract'</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// default current date</span><br />
&nbsp; &nbsp; klForCustTesterDataContract.<span style="color: #000000;">parmTransDate</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">systemDateGet</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// return a new instance of this controller</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> klForCustTesterServiceController;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>As you can see, the Data Contract is fetched using the getDataContractObject() method. This will also unpack any values that were packed before, just like a normal RunBase would.<br />
Setting the date is a simple as setting the parm method on the data contract. </p>
<p>Now let&#8217;s add the logic that creates the correct query by adding a range based on the record in the Args variable.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> KlForCustTesterServiceController newFromArgs<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; KlForCustTesterServiceController &nbsp; &nbsp;klForCustTesterServiceController;<br />
&nbsp; &nbsp; klForCustTesterDataContract &nbsp; &nbsp; &nbsp; &nbsp; klForCustTesterDataContract;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; CustTable &nbsp; custTable;<br />
&nbsp; &nbsp; Query &nbsp; &nbsp; &nbsp; query;<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// create a new instance of the controller</span><br />
&nbsp; &nbsp; klForCustTesterServiceController <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> KlForCustTesterServiceController<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// initialize from args</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// one of the things this will do is read the &quot;parameters&quot; property from the menu item </span><br />
&nbsp; &nbsp; klForCustTesterServiceController.<span style="color: #000000;">initializeFromArgs</span><span style="color: #000000;">&#40;</span>_args<span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #007f00;">// get datacontract</span><br />
&nbsp; &nbsp; <span style="color: #007f00;">// the string should be the same as the parameter name!</span><br />
&nbsp; &nbsp; klForCustTesterDataContract <span style="color: #00007f;">=</span> klForCustTesterServiceController.<span style="color: #000000;">getDataContractObject</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">'_klForCustTesterDataContract'</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// default current date</span><br />
&nbsp; &nbsp; klForCustTesterDataContract.<span style="color: #000000;">parmTransDate</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">systemDateGet</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #007f00;">// check if the record is of type CustTable</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #000000;">&#40;</span>_args <span style="color: #00007f;">&amp;&amp;</span> _args.<span style="color: #000000;">dataset</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #00007f;">==</span> <span style="color: #0000ff;">tableNum</span><span style="color: #000000;">&#40;</span>CustTable<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// cast record</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; custTable <span style="color: #00007f;">=</span> _args.<span style="color: #000000;">record</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// create new query</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; query <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> query<span style="color: #000000;">&#40;</span><span style="color: #0000ff;">queryStr</span><span style="color: #000000;">&#40;</span>KlForCustomers<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// add range</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; query.<span style="color: #000000;">dataSourceTable</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">tableNum</span><span style="color: #000000;">&#40;</span>CustTable<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">addRange</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">fieldNum</span><span style="color: #000000;">&#40;</span>CustTable<span style="color: #00007f;">,</span> AccountNum<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">value</span><span style="color: #000000;">&#40;</span>queryValue<span style="color: #000000;">&#40;</span>custTable.<span style="color: #000000;">AccountNum</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// set query on datacontract</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; klForCustTesterDataContract.<span style="color: #000000;">setQuery</span><span style="color: #000000;">&#40;</span>query<span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// return a new instance of this controller</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> klForCustTesterServiceController;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>There you go. Now we need to make a main method that uses this construct method, and starts the operation:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; KlForCustTesterServiceController klForCustTesterServiceController;<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; klForCustTesterServiceController <span style="color: #00007f;">=</span> KlForCustTesterServiceController<span style="color: #00007f;">::</span><span style="color: #000000;">newFromArgs</span><span style="color: #000000;">&#40;</span>_args<span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; klForCustTesterServiceController.<span style="color: #000000;">startOperation</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>We also need to create a new menu item. Right click you project &#8211; New &#8211; Menu Item.<br />
Enter the following properties:</p>
<p><strong>ObjectType</strong>: Class<br />
<strong>Object</strong>: KlForCustTesterServiceController<br />
<strong>Parameters</strong>: KlForCustTesterDataService.testCustomer</p>
<p>Next, add the menu item to the CustTable form:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/custtablebutton.png" alt="" title="Custtable button" width="542" height="408" class="aligncenter size-full wp-image-1265" /></p>
<p>Finally before testing, click the Generate Incremental CIL button to generate CIL.<br />
<img src="http://www.artofcreation.be/wp-content/uploads/generateCIL.png" alt="" title="generateCIL" width="634" height="99" class="aligncenter size-full wp-image-1229" /></p>
<p>Right click the CustTable form and click Open. This will open the Customers form. Switch to the grid view (Ctrl + Shift + G), and select a record. Then click the button we just added.<br />
<a href="http://www.artofcreation.be/wp-content/uploads/Customers-form.png"><img src="http://www.artofcreation.be/wp-content/uploads/Customers-form.png" alt="" title="Customers form" width="600" height="244" class="aligncenter size-full wp-image-1266" /></a></p>
<blockquote><p>Note: a bug (or something I do wrong?) I found is that the query values that are displayed on the dialog seem to be &#8220;lagging&#8221;. The wrong values are shown, but when you click ok, the correct values are used, unless you click the select button.<br />
This can be fixed by adding this line before returning the controller object:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">KlForCustTesterServiceController.<span style="color: #000000;">queryChanged</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;_klForCustTesterDataContract.parmQuery&quot;</span><span style="color: #00007f;">,</span> query<span style="color: #000000;">&#41;</span>;</div></div>
<p>This is probably not a nice way to do this, so I&#8217;ll look into it, and let you know.
</p></blockquote>
<p>When you click Ok on the dialog, you should see that only the customer you&#8217;ve selected will be processed. You will also see that the date has been set to today&#8217;s date, just like we wanted. </p>
<p><a href="http://www.artofcreation.be/wp-content/SharedProject_KlFor_SysOperation_Day2.xpo">Download the XPO for part 2 here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AX2012: SysOperation part 1: Data Contracts and Service Operations</title>
		<link>http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/</link>
		<comments>http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 11:00:11 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[2012]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[SysOperation]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=1196</guid>
		<description><![CDATA[Hi All :-) This is part 1 of a series of 3 blog posts where I demonstrate how to create batch classes using the SysOperation classes (Read the introduction here) We are going to create a batch that looks like this: And we are going to do that without creating a RunBaseBatch class! Note: Just [...]]]></description>
			<content:encoded><![CDATA[<p>Hi All :-) </p>
<p>This is part 1 of a series of 3 blog posts where I demonstrate how to create batch classes using the SysOperation classes (Read the <a href="http://www.artofcreation.be/2011/08/21/ax2012-sysoperation-introduction/">introduction here</a>)</p>
<p>We are going to create a batch that looks like this:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/BOFBatch.png" alt="" title="Batch screenshot" width="625" height="347" class="aligncenter size-full wp-image-1232" /><br />
And we are going to do that without creating a RunBaseBatch class!</p>
<blockquote><p>Note: Just to be clear: the batch class won&#8217;t actually do anything useful, everything is just for demo purposes. </p></blockquote>
<p>Okay, let&#8217;s start!</p>
<h3>1. Data Contract</h3>
<p>First, we will create a data contract. The data contract contains data members that represent the fields that will be available on the dialog. </p>
<p>Let&#8217;s create a new class, KlForCustTesterDataContract:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataContractAttribute<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">class</span> KlForCustTesterDataContract<br />
<span style="color: #000000;">&#123;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>The string DataContractAttribute indicates that this class is a Data Contract. The square brackets [] indicate that this string is an attribute (You can read more about attributes on <a href="http://msdn.microsoft.com/en-us/library/gg846588.aspx">MSDN</a>). </p>
<p>Next, let&#8217;s add Data Members to this contract by first declaring them in the class declaration</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataContractAttribute<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">class</span> KlForCustTesterDataContract<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; Name &nbsp; &nbsp; &nbsp; &nbsp;name;<br />
&nbsp; &nbsp; TransDate &nbsp; transDate;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">str</span> &nbsp; &nbsp; &nbsp; &nbsp; packedQuery;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>We add a string field, a date field, and a query. We still need to create parm methods for these variables. </p>
<p>This is just a simple string field, nothing special here except for the DataMemberAttribute attribute that indicates that this method is da data member.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataMemberAttribute<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">public</span> Name parmName<span style="color: #000000;">&#40;</span>Name _name <span style="color: #00007f;">=</span> name<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; name <span style="color: #00007f;">=</span> _name;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> name;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>The date field is of type TransDate, so we&#8217;ll give it a nicer label by using the SysOperationLabelAttribute attribute to specify the label used.<br />
Also note that, when two attributes are specified, the are separated by a comma (,).</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataMemberAttribute<br />
<span style="color: #00007f;">,</span>SysOperationLabelAttribute<span style="color: #000000;">&#40;</span><span style="color: #0000ff;">literalStr</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;@SYS11284&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #007f00;">// today's date</span><br />
<span style="color: #0000ff;">public</span> TransDate parmTransDate<span style="color: #000000;">&#40;</span>TransDate _transDate <span style="color: #00007f;">=</span> transDate<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; transDate <span style="color: #00007f;">=</span> _transDate;<br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> transDate;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>We will also add a query, so we can loop all customers. As you can see, we can specify the query by using the AifQueryTypeAttribute. The query KlForCustomers is just a query in the AOT with CustTable as a datasource (see xpo file at the end).</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>DataMemberAttribute<span style="color: #00007f;">,</span><br />
&nbsp; &nbsp; AifQueryTypeAttribute<span style="color: #000000;">&#40;</span><span style="color: #ff0000;">'_packedQuery'</span><span style="color: #00007f;">,</span> <span style="color: #0000ff;">querystr</span><span style="color: #000000;">&#40;</span>KlForCustomers<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">str</span> parmQuery<span style="color: #000000;">&#40;</span><span style="color: #0000ff;">str</span> _packedQuery <span style="color: #00007f;">=</span> packedQuery<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; packedQuery <span style="color: #00007f;">=</span> _packedQuery;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> packedQuery;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Next, we add two helper methods that are not Data Members, so we can easily set and get the query variable. </p>
<p>To get the query:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> Query getQuery<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Query<span style="color: #000000;">&#40;</span>SysOperationHelper<span style="color: #00007f;">::</span><span style="color: #000000;">base64Decode</span><span style="color: #000000;">&#40;</span>packedQuery<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>To set the query:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> setQuery<span style="color: #000000;">&#40;</span>Query _query<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; packedQuery <span style="color: #00007f;">=</span> SysOperationHelper<span style="color: #00007f;">::</span><span style="color: #000000;">base64Encode</span><span style="color: #000000;">&#40;</span>_query.<span style="color: #000000;">pack</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<h3>2. Service class and operation</h3>
<p>Next, let&#8217;s create a service class called KlForCustTesterDataService.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">class</span> KlForCustTesterDataService<br />
<span style="color: #000000;">&#123;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Right click the class, click properties, and set the run on property to server. </p>
<p>Adding a service operation to this service class is as simple as adding a method. As you can see, the SysEntryPointAttribute attribute indicates that this is a service operation, and our data contract is used as an argument.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>SysEntryPointAttribute<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> testCustomer<span style="color: #000000;">&#40;</span>KlForCustomerTesterDataContract _klForCustomerTesterDataContract<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Of course, this method needs some demo functionality, so let&#8217;s add that:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000;">&#91;</span>SysEntryPointAttribute<span style="color: #000000;">&#93;</span><br />
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> testCustomer<span style="color: #000000;">&#40;</span>KlForCustTesterDataContract _klForCustTesterDataContract<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; QueryRun &nbsp; &nbsp;queryRun;<br />
&nbsp; &nbsp; CustTable &nbsp; custTable;<br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #007f00;">// info the name parameter</span><br />
&nbsp; &nbsp; info<span style="color: #000000;">&#40;</span>_klForCustTesterDataContract.<span style="color: #000000;">parmName</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// create a new queryrun object</span><br />
&nbsp; &nbsp; queryRun <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> queryRun<span style="color: #000000;">&#40;</span>_klForCustTesterDataContract.<span style="color: #000000;">getQuery</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// loop all results from the query</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #000000;">&#40;</span>queryRun.<span style="color: #0000ff;">next</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; custTable <span style="color: #00007f;">=</span> queryRun.<span style="color: #000000;">get</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">tableNum</span><span style="color: #000000;">&#40;</span>custTable<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// display the accountnum</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; info<span style="color: #000000;">&#40;</span>custTable.<span style="color: #000000;">AccountNum</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<h3>3. Service</h3>
<p>Right click your project, and choose <strong>New </strong>- <strong>Service</strong>. Give this service the same name as the service class, KlForCustTesterDataService.<br />
In the properties of this node, set the <strong>class </strong>property to KlForCustTesterDataService<br />
Expand the node of your service, then right click on the <strong>Operations</strong> node.<br />
Click <strong>Add operation</strong> and check the <strong>add</strong> checkbox next to the method we&#8217;ve created, and click <strong>OK</strong>.</p>
<h3>4. Menu item</h3>
<p>All we need to do now is create a menu item so we can start our dialog.<br />
Do this by right clicking your project &#8211; <strong>New </strong>- <strong>Menu item</strong>. Name it KlForCustTesterDataService. </p>
<p>Enter the following properties:<br />
<strong>ObjectType</strong>: Class<br />
<strong>Object</strong>: SysOperationServiceController<br />
<strong>Parameters</strong>: KlForCustTesterDataService.testCustomer</p>
<p>As you can see, we don&#8217;t link directly to our service class, in stead, the class SysOperationServiceController will be used, and will know what service operation to start because it is specified in the <strong>parameters</strong> property. More about these controller class in part 2 of this series. </p>
<h3>5. Run it!</h3>
<p>But wait, we still have to do one small thing: compile our X++ into the common intermediate language (CIL). Don&#8217;t worry, it&#8217;s easy. Just click the Generate Incremental CIL button in the toolbar (this might take a while).<br />
<img src="http://www.artofcreation.be/wp-content/uploads/generateCIL.png" alt="" title="generateCIL" width="634" height="99" class="aligncenter size-full wp-image-1229" /></p>
<p>After CIL was generated, right click the menu item and click <strong>Open</strong>. You should see your batch class. As you can see, all fields from the datacontract are displayed, and a select button was automatically generated so you can modify the query.<br />
<img src="http://www.artofcreation.be/wp-content/uploads/BOFBatchFinished.png" alt="" title="BOF Batch Example" width="613" height="337" class="aligncenter size-full wp-image-1236" /><br />
Output when run in batch:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/BatchOutput.png" alt="" title="Batch Output" width="631" height="334" class="aligncenter size-full wp-image-1238" /></p>
<p>In part 2, we will take a closer look at the SysOperationServiceController class. See you tomorrow. </p>
<p><a href="http://www.artofcreation.be/wp-content/SharedProject_KlFor_SysOperation_Day1.xpo">Download the XPO for part 1 here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AX2012: SysOperation introduction</title>
		<link>http://www.artofcreation.be/2011/08/21/ax2012-sysoperation-introduction/</link>
		<comments>http://www.artofcreation.be/2011/08/21/ax2012-sysoperation-introduction/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 16:28:01 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[2012]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[SysOperation]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=1188</guid>
		<description><![CDATA[Hi everyone! Dynamics AX 2012 introduces a new way for creating batches, without using the RunBaseBatch class. The SysOperation* classes are part of the Business Operation Framework, and can be used to create these batches. Some documentation is already available on MSDN about the BOF and the SysOpertation classes, but I was still confused when [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everyone!</p>
<p>Dynamics AX 2012 introduces a new way for creating batches, without using the RunBaseBatch class. The SysOperation* classes are part of the Business Operation Framework, and can be used to create these batches.<br />
<img src="http://www.artofcreation.be/wp-content/uploads/clickitax2012.png" alt="" title="What you would like to do now" width="146" height="169" class="aligncenter size-full wp-image-1246" /><br />
Some documentation is already available on MSDN about the BOF and the SysOpertation classes, but I was still confused when creating such a batch class. That is why in the next 3 days, I will cover the basics on how to create these batches, so you don&#8217;t have to figure it all out on your own. </p>
<p>I hope to get some feedback too, because not everything is crystal clear to me either :-). </p>
<p>But anyway, this is what you can expect in the next 3 days:</p>
<p><strong>Day 1</strong> <a href="http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/">(link)</a><br />
A demonstration on how to create <strong>Data Contract</strong> classes and <strong>Service Operations</strong>. You will also learn how to use <strong>attributes</strong> like DataContractAttribute and DataMemberAttribute, and at the end, we will already have a working batch class. </p>
<p><strong>Day 2</strong> <a href="http://www.artofcreation.be/2011/08/23/ax2012-sysoperation-part-2-sysoperationservicecontroller/">(link)</a><br />
We will take a closer look at the <strong>SysOperationServiceController</strong> class, and will be creating our own controller. This will allow us to set properties on our Data Contract based on Args. This is useful when you batch is started by a button on a form that is linked to a datasource. </p>
<p><strong>Day 3</strong> <a href="http://www.artofcreation.be/2011/08/24/ax2012-sysoperation-part-3-sysoperationautomaticuibuilder/">(link)</a><br />
To make a fully functional batch, we need to be able to overwrite methods on our dialog field like lookup and modified. We also want to be able to change the properties of these fields, like enabling or disabling them. That&#8217;s just what the <strong>SysOperationAutomaticUIBuilder </strong>class is for, and we&#8217;ll look into that. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2011/08/21/ax2012-sysoperation-introduction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Try Catch example code</title>
		<link>http://www.artofcreation.be/2011/08/09/try-catch-example-code/</link>
		<comments>http://www.artofcreation.be/2011/08/09/try-catch-example-code/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 18:04:50 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[2009]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[Error]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Try Catch]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=1140</guid>
		<description><![CDATA[Hi all! The code below contains a try/catch that I use a lot when developing batch jobs, especially multithreaded ones. It deals with frequently occurring exceptions that, in some cases, can be easily solved by retrying: Deadlocks Update conflicts Duplicate key conflicts Duplicate key conflicts are more rare than update conflicts, but I&#8217;ve seen them [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all!</p>
<p>The code below contains a try/catch that I use a lot when developing batch jobs, especially <a href="http://www.artofcreation.be/2010/10/03/batch-multithreading/">multithreaded ones</a>.<br />
It deals with frequently occurring exceptions that, in some cases, can be easily solved by retrying:</p>
<ul>
<li>Deadlocks</li>
<li>Update conflicts</li>
<li>Duplicate key conflicts</li>
</ul>
<p>Duplicate key conflicts are more rare than update conflicts, but I&#8217;ve seen them pop up under heavy load on InventDim records.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #0000ff;">try</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">ttsbegin</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// do stuff here</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">ttsCommit</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; catch <span style="color: #000000;">&#40;</span>Exception<span style="color: #00007f;">::</span><span style="color: #000000;">Deadlock</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// retry on deadlock</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">retry</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; catch <span style="color: #000000;">&#40;</span>Exception<span style="color: #00007f;">::</span><span style="color: #000000;">UpdateConflict</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// try to resolve update conflict</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #000000;">&#40;</span>appl.<span style="color: #000000;">ttsLevel</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #00007f;">==</span> <span style="color: #000000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #000000;">&#40;</span>xSession<span style="color: #00007f;">::</span><span style="color: #000000;">currentRetryCount</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #00007f;">&gt;=</span> #RetryNum<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">throw</span> Exception<span style="color: #00007f;">::</span><span style="color: #000000;">UpdateConflictNotRecovered</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">retry</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">throw</span> Exception<span style="color: #00007f;">::</span><span style="color: #000000;">UpdateConflict</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; catch<span style="color: #000000;">&#40;</span>Exception<span style="color: #00007f;">::</span><span style="color: #000000;">DuplicateKeyException</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// retry in case of an duplicate key conflict</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #000000;">&#40;</span>appl.<span style="color: #000000;">ttsLevel</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #00007f;">==</span> <span style="color: #000000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #000000;">&#40;</span>xSession<span style="color: #00007f;">::</span><span style="color: #000000;">currentRetryCount</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #00007f;">&gt;=</span> #RetryNum<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">throw</span> Exception<span style="color: #00007f;">::</span><span style="color: #000000;">DuplicateKeyExceptionNotRecovered</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">retry</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">throw</span> Exception<span style="color: #00007f;">::</span><span style="color: #000000;">DuplicateKeyException</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2011/08/09/try-catch-example-code/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Batch multithreading</title>
		<link>http://www.artofcreation.be/2010/10/03/batch-multithreading/</link>
		<comments>http://www.artofcreation.be/2010/10/03/batch-multithreading/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 11:57:32 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[Multithreading]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=899</guid>
		<description><![CDATA[Do you have batches that run for hours? After reading this post (and doing some coding), they might just run in minutes. How? By creating multiple tasks in your batch job at runtime. Read on :-). Introduction Normally, when you schedule your RunBaseBatch class as a batch job, it will create one task. You can [...]]]></description>
			<content:encoded><![CDATA[<p>Do you have batches that run for hours? After reading this post (and doing some coding), they might just run in minutes.<br />
How? By creating multiple tasks in your batch job at runtime. Read on :-).</p>
<h3>Introduction</h3>
<p>Normally, when you schedule your RunBaseBatch class as a batch job, it will create one task.<br />
You can check this under Basic &#8211; Periodic &#8211; Batch Job when you have scheduled a batch job.<br />
In a diagram, it looks like this:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/singlethread.png" alt="" title="singlethread" width="328" height="68" class="aligncenter size-full wp-image-901" /><br />
This batch task will execute everything on one batch session on one batch server. </p>
<p>But in AX 2009, your batch group can be added to multiple AOS server, and an AOS server can process multiple tasks simultaneously. So how can we use this to speed up our batch job?</p>
<p>We do it by splitting up our task in multiple smaller ones, which are then distributed over multiple batch sessions (threads) and over multiple AOS servers. </p>
<p>Like this:<br />
<img src="http://www.artofcreation.be/wp-content/uploads/multithread.png" alt="" title="multithread" width="326" height="189" class="aligncenter size-full wp-image-903" /></p>
<p><H3>Example</H3></p>
<p>In this example, I will loop all my customers, and simulate a process that runs for 3 seconds by using the sleep() function. </p>
<blockquote><p>Note: download the .xpo file below.</p></blockquote>
<p><H3>Single thread</H3><br />
First, let&#8217;s create a batch job like we normally would.<br />
For this, I create 2 classes:</p>
<ol>
<li><em><strong>KlForUpdateCustomers</strong></em>: A class that contains my business logic I want to execute</li>
<li><em><strong>KlForUpdateCustomersSingleTheadBatch</strong></em>: A class that extends RunBaseBatch and makes calls to <em><strong>KlForUpdateCustomers</strong></em></li>
</ol>
<p><strong>KlForUpdateCustomers</strong><br />
This class contains this in its run method (see xpo file for other methods):</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> run<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// simulate a process that takes 3 seconds</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">sleep</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">3000</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; info<span style="color: #000000;">&#40;</span><span style="color: #0000ff;">strfmt</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">'updated customer %1'</span><span style="color: #00007f;">,</span> this.<span style="color: #000000;">parmCustTable</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">AccountNum</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p><strong>KlForUpdateCustomersSingleTheadBatch</strong><br />
This class is our batch class so it extends RunBaseBatch. It has a queryRun, and has this run method:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> run<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; CustTable custTable;<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #000000;">&#40;</span>queryRun.<span style="color: #0000ff;">next</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; custTable <span style="color: #00007f;">=</span> queryRun.<span style="color: #000000;">get</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">tablenum</span><span style="color: #000000;">&#40;</span>CustTable<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; KlForUpdateCustomers<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>custTable<span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>It loops all customers, and makes a call to the class we created earlier for each customer. To keep it simple, I did not add exception handling to this example. </p>
<p>When we run this in batch, a single batch task is created in the batch job that runs for about 3 minutes (according to the batch job screen).<br />
<a href="http://www.artofcreation.be/wp-content/uploads/singletask.png"><img src="http://www.artofcreation.be/wp-content/uploads/singletask-300x232.png" alt="" title="Single thread batch job" width="300" height="232" class="aligncenter size-medium wp-image-920" /></a></p>
<p><H3>Multithread</H3><br />
To rewrite this batch job to use multiple tasks, we will need 3 classes:</p>
<ol>
<li><em><strong>KlForUpdateCustomers</strong></em>: the business logic class we created earlier and we can reuse</li>
<li><em><strong>KlForUpdateCustomersMultiThreadBatch</strong></em>: The class that represents the batch job and will create batch tasks</li>
<li><em><strong>KlForUpdateCustomersMultiThreadTask</strong></em>: The class that represents one batch task and makes calls to <em>KlForUpdateCustomers</em></li>
</ol>
<p><strong>KlForUpdateCustomers</strong><br />
This class is the same as before and processes one customer (CustTable record). </p>
<p><strong>KlForUpdateCustomersMultiThreadTask</strong><br />
This class extends RunBaseBatch and represents one of the many batch tasks we will be creating. In this example it processes one CustTable record, so a task will be created for each CustTable record. </p>
<p>The run method looks like this:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> run<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; KlForUpdateCustomers<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>this.<span style="color: #000000;">parmCustTable</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p><strong>KlForUpdateCustomersMultiThreadBatch</strong><br />
This is our batch job class, and this is where the real magic happens. This class will create multiple instances of KlForUpdateCustomersMultiThreadTask and add them as a task to our job at run time. </p>
<p>This is how the run method looks:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> run<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; BatchHeader &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; batchHeader;<br />
&nbsp; &nbsp; KlForUpdateCustomersMultiThreadTask klForUpdateCustomersMultiThreadTask;<br />
&nbsp; &nbsp; CustTable &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; custTable;<br />
&nbsp; &nbsp; ;<br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #000000;">&#40;</span>queryRun.<span style="color: #0000ff;">next</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; custTable <span style="color: #00007f;">=</span> queryRun.<span style="color: #000000;">get</span><span style="color: #000000;">&#40;</span><span style="color: #0000ff;">tablenum</span><span style="color: #000000;">&#40;</span>CustTable<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #000000;">&#40;</span>this.<span style="color: #000000;">isInBatch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// when in batch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// create multiple tasks</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #000000;">&#40;</span><span style="color: #00007f;">!</span>batchHeader<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; batchHeader <span style="color: #00007f;">=</span> BatchHeader<span style="color: #00007f;">::</span><span style="color: #000000;">construct</span><span style="color: #000000;">&#40;</span>this.<span style="color: #000000;">parmCurrentBatch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">BatchJobId</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// create a new instance of the batch task class</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; klForUpdateCustomersMultiThreadTask <span style="color: #00007f;">=</span> KlForUpdateCustomersMultiThreadTask<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>custTable.<span style="color: #000000;">data</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// add tasks to the batch header</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; batchHeader.<span style="color: #000000;">addRuntimeTask</span><span style="color: #000000;">&#40;</span>klForUpdateCustomersMultiThreadTask<span style="color: #00007f;">,</span> this.<span style="color: #000000;">parmCurrentBatch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">RecId</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// when not in batch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KlForUpdateCustomers<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>custTable<span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #000000;">&#40;</span>batchHeader<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// save the batchheader with added tasks</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; batchHeader.<span style="color: #000000;">save</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>As you can see, for each custTable record, we create a new task. When the batch job doesn&#8217;t run in batch, we process it as we otherwise would using one session. </p>
<p>In the batch tasks screen (Basic &#8211; Inquiries &#8211; Batch Job &#8211; (select you batch job) &#8211; View Tasks), you can clearly see what happens. </p>
<p>First, the status is waiting, and one task has been created.<br />
<a href="http://www.artofcreation.be/wp-content/uploads/multitask_waiting.png"><img src="http://www.artofcreation.be/wp-content/uploads/multitask_waiting-300x183.png" alt="" title="multitask_waiting" width="300" height="183" class="aligncenter size-medium wp-image-932" /></a><br />
Then, when the batch job is executing, we can see that multiple tasks have been added to our batch job.<br />
 <a href="http://www.artofcreation.be/wp-content/uploads/multitask_executing.png"><img src="http://www.artofcreation.be/wp-content/uploads/multitask_executing-300x183.png" alt="" title="multitask_executing" width="300" height="183" class="aligncenter size-medium wp-image-934" /></a><br />
We can also see that it processes 8 tasks at the same time! This is bacause the maximum number of batch threads is set to 8 on the batch server schedule tab of the Server configuration screen (Administration &#8211; Setup &#8211; Server configuration). </p>
<p>Finally, we can see that the job has ended, and that all runtime tasks have been moved to the batch job history:<br />
<a href="http://www.artofcreation.be/wp-content/uploads/multitask_ended.png"><img src="http://www.artofcreation.be/wp-content/uploads/multitask_ended-300x182.png" alt="" title="multitask_ended" width="300" height="182" class="aligncenter size-medium wp-image-938" /></a><br />
You can view the history and the log of this batch job:<br />
<a href="http://www.artofcreation.be/wp-content/uploads/multitask_log.png"><img src="http://www.artofcreation.be/wp-content/uploads/multitask_log-300x233.png" alt="" title="multitask_log" width="300" height="233" class="aligncenter size-medium wp-image-939" /></a></p>
<p>Notice how the executing time has gone from 3 minutes to 1 minute according to the batch job screen. </p>
<p>Alternatively, you could use a queryrun in you batch tasks class too. You could for example create a batch group per customer group if that makes more sense to you. The &#8216;per record&#8217; approach is just an example, just do what makes the most sense in your situation. Sometimes it is better if the runtime tasks have a bit more to do, to counter the overload of creating the tasks. </p>
<p><H3>Conclusion</H3><br />
This method has helped me a lot while dealing with performance issues. Be aware though, you could have problems with concurrency and heavy load (that I haven&#8217;t discussed here). But if you do it right, it will result in a <strong>huge</strong> performance boost. </p>
<p>Spread the word :-). </p>
<p><a href="http://www.artofcreation.be/wp-content/uploads/SharedProject_KlForMultiThreadedBatchExample.xpo"><strong>Download the XPO file by clicking here.</strong></a></p>
<p>Update 2011/02/11:<br />
There were two errors in the example:<br />
This line:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">batchHeader <span style="color: #00007f;">=</span> BatchHeader<span style="color: #00007f;">::</span><span style="color: #000000;">construct</span><span style="color: #000000;">&#40;</span>this.<span style="color: #000000;">parmCurrentBatch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">RecId</span><span style="color: #000000;">&#41;</span>;</div></div>
<p>Has been replaced with:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">batchHeader <span style="color: #00007f;">=</span> BatchHeader<span style="color: #00007f;">::</span><span style="color: #000000;">construct</span><span style="color: #000000;">&#40;</span>this.<span style="color: #000000;">parmCurrentBatch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">BatchJobId</span><span style="color: #000000;">&#41;</span>;</div></div>
<p>And this line:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">klForUpdateCustomersMultiThreadTask <span style="color: #00007f;">=</span> KlForUpdateCustomersMultiThreadTask<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>custTable<span style="color: #000000;">&#41;</span>;</div></div>
<p>Has been replaced with:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">klForUpdateCustomersMultiThreadTask <span style="color: #00007f;">=</span> KlForUpdateCustomersMultiThreadTask<span style="color: #00007f;">::</span><span style="color: #000000;">newcustTable</span><span style="color: #000000;">&#40;</span>custTable.<span style="color: #000000;">data</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;</div></div>
<p>Todo on my part: update the XPO. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2010/10/03/batch-multithreading/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Run AIF inbound and outbound manually</title>
		<link>http://www.artofcreation.be/2010/02/17/run-aif-inbound-and-outbound-manually/</link>
		<comments>http://www.artofcreation.be/2010/02/17/run-aif-inbound-and-outbound-manually/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 17:51:53 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[AIF]]></category>
		<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[Job]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=485</guid>
		<description><![CDATA[To have AIF import and export message, you have to have 4 batch tasks running (all about it here on TechNet). However, when developing, it is inefficient (and also tad tedious) to wait for those batches. Here are two jobs to run inbound and outbound messages manually, so you don&#8217;t have to wait for the [...]]]></description>
			<content:encoded><![CDATA[<p>To have AIF import and export message, you have to have 4 batch tasks running (<a href="http://technet.microsoft.com/en-us/library/aa570105.aspx">all about it here on TechNet</a>). However, when developing, it is inefficient (and also tad tedious) to wait for those batches.</p>
<p>Here are two jobs to run inbound and outbound messages manually, so you don&#8217;t have to wait for the batches to pick them up.</p>
<p>Inbound:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> KlForrunAIFInbound<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// read the messages</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">new</span> AifGateWayReceiveService<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// process the messages in queue</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">new</span> AifInboundProcessingService<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; info<span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;done&quot;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Outbound:</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> KlForrunAIFOutbound<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// process messages in queue</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">new</span> AifOutboundProcessingService<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// send messages</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">new</span> AifGateWaySendService<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #000000;">run</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; info<span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;done&quot;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Ofcourse, you can put this code in classes, or combine them so they are executed together. Because inbound messages can trigger outbound messages, it&#8217;s better to process the inbound messages before the outbound messages.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2010/02/17/run-aif-inbound-and-outbound-manually/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing in the event log from Dynamics AX</title>
		<link>http://www.artofcreation.be/2009/06/19/writing-in-the-event-log-from-dynamics-ax/</link>
		<comments>http://www.artofcreation.be/2009/06/19/writing-in-the-event-log-from-dynamics-ax/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 11:14:55 +0000</pubDate>
		<dc:creator>Klaas Deforche</dc:creator>
				<category><![CDATA[Dynamics AX]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[Event Log]]></category>
		<category><![CDATA[System.Diagnostics]]></category>

		<guid isPermaLink="false">http://www.artofcreation.be/?p=125</guid>
		<description><![CDATA[Writing to the event log in Windows using AX is very easy when you use the EventLog class from the System.Diagnostics namespace. The following job demonstrates how to use the EventLog class. static void EventViewer&#40;Args _args&#41; &#123; &#160; &#160; System.Diagnostics.EventLog eventlog; &#160; &#160; #Define.LogSource&#40;&#34;Dynamics AX&#34;&#41; &#160; &#160; #Define.LogName&#40;&#34;Dynamics AX Log&#34;&#41; &#160; &#160; &#160; &#160; ; [...]]]></description>
			<content:encoded><![CDATA[<p>Writing to the event log in Windows using AX is very easy when you use the EventLog class from the System.Diagnostics namespace. The following job demonstrates how to use the EventLog class.</p>
<div class="codecolorer-container xpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> EventViewer<span style="color: #000000;">&#40;</span>Args _args<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLog</span> eventlog;<br />
&nbsp; &nbsp; #Define.<span style="color: #000000;">LogSource</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Dynamics AX&quot;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; #Define.<span style="color: #000000;">LogName</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Dynamics AX Log&quot;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; ;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// check if the log already exists</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #000000;">&#40;</span><span style="color: #00007f;">!</span>System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLog</span><span style="color: #00007f;">::</span><span style="color: #000000;">SourceExists</span><span style="color: #000000;">&#40;</span>#LogSource<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #007f00;">// create new log</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLog</span><span style="color: #00007f;">::</span><span style="color: #000000;">CreateEventSource</span><span style="color: #000000;">&#40;</span>#LogSource<span style="color: #00007f;">,</span> #LogName<span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; eventlog <span style="color: #00007f;">=</span> <span style="color: #0000ff;">new</span> System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLog</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; eventlog.<span style="color: #000000;">set_Source</span><span style="color: #000000;">&#40;</span>#LogSource<span style="color: #000000;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #007f00;">// write info entry</span><br />
&nbsp; &nbsp; eventlog.<span style="color: #000000;">WriteEntry</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Just writing in the event viewer.&quot;</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// write error entry</span><br />
&nbsp; &nbsp; eventlog.<span style="color: #000000;">WriteEntry</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Error! Please check the stack trace below. <span style="color: #000000;">\n</span><span style="color: #000000;">\n</span>&quot;</span> <span style="color: #00007f;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; con2str<span style="color: #000000;">&#40;</span>xSession<span style="color: #00007f;">::</span><span style="color: #000000;">xppCallStack</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #00007f;">,</span> System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLogEntryType</span><span style="color: #00007f;">::</span><span style="color: #000000;">Error</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #007f00;">// write warning entry</span><br />
&nbsp; &nbsp; eventlog.<span style="color: #000000;">WriteEntry</span><span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Job finished.&quot;</span> <span style="color: #00007f;">,</span> System.<span style="color: #000000;">Diagnostics</span>.<span style="color: #000000;">EventLogEntryType</span><span style="color: #00007f;">::</span><span style="color: #000000;">Warning</span><span style="color: #000000;">&#41;</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; info<span style="color: #000000;">&#40;</span><span style="color: #ff0000;">&quot;Check the event viewer!&quot;</span><span style="color: #000000;">&#41;</span>;<br />
<span style="color: #000000;">&#125;</span></div></div>
<p>A possible use for this is when monitoring batch jobs.<br />
Tested using AX 2009, XP Pro. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.artofcreation.be/2009/06/19/writing-in-the-event-log-from-dynamics-ax/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

