<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Vjeko.com</title>
	
	<link>http://vjeko.com</link>
	<description>Opinions, thoughts, ideas, and more, about Microsoft Dynamics NAV</description>
	<lastBuildDate>Sat, 18 May 2013 21:14:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/NavigateIntoSuccess" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="navigateintosuccess" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">NavigateIntoSuccess</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Retiring NavigateIntoSuccess.com</title>
		<link>http://vjeko.com/blog/retiring-navigateintosuccess-com</link>
		<comments>http://vjeko.com/blog/retiring-navigateintosuccess-com#comments</comments>
		<pubDate>Sat, 18 May 2013 21:02:53 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[NavigateIntoSuccess.com]]></category>

		<guid isPermaLink="false">http://vjeko.com/?p=1312</guid>
		<description><![CDATA[A couple of months ago, when I asked my friends on Facebook and Twitter if anybody knows how to move a WordPress blog to another domain, everybody said that I was crazy. You don’t do these things, they said. And yet, when they heard the reason why I was about to leave my old domain, everybody agreed. NavigateIntoSucess.com has served me well. I moved my public WordPress website to this custom domain very early on. It has become a kind of a brand. But it is a pretty long name. You can easily mistype it. It’s difficult to remember it if you only occasionally stumble upon it. It doesn’t at all relate to me as a living person behind it. So I decided to move it all to a fresh new domain: vjeko.com. NAV community is a live and vibrant one, and through my blog, a book, and other activities, I’ve met a lot of great people who all simply know me as “Vjeko”. It’s short. It was unusual enough that I managed to snitch the .com domain fairly early. And even though for most people I met, at first my Slavic name proved to be scary, unmemorable, and utterly unpronounceable (especially for my American friends who all still twist their tongues around pronouncing the hard “j” instead of simply “y” as it should be done), I’m pretty sure that strongly coupling my blog with my personal moniker will prove to be a smart thing in the long run. So – I welcome you to vjeko.com, my new domain, and I hope that I find enough time to transform the to-do list I accumulated while working on the new blog into actual posts soon. Stay [...]]]></description>
				<content:encoded><![CDATA[<p>A couple of months ago, when I asked my friends on Facebook and Twitter if anybody knows how to move a WordPress blog to another domain, everybody said that I was crazy. You don’t do these things, they said. And yet, when they heard the reason why I was about to leave my old domain, everybody agreed.</p>
<p>NavigateIntoSucess.com has served me well. I moved my public WordPress website to this custom domain very early on. It has become a kind of a brand. But it is a pretty long name. You can easily mistype it. It’s difficult to remember it if you only occasionally stumble upon it. It doesn’t at all relate to me as a living person behind it. So I decided to move it all to a fresh new domain: <strong>vjeko.com</strong>.</p>
<p><span id="more-1312"></span>
<p>NAV community is a live and vibrant one, and through my blog, a book, and other activities, I’ve met a lot of great people who all simply know me as “Vjeko”. It’s short. It was unusual enough that I managed to snitch the .com domain fairly early. And even though for most people I met, at first my Slavic name proved to be scary, unmemorable, and utterly unpronounceable (especially for my American friends who all still twist their tongues around pronouncing the hard “j” instead of simply “y” as it should be done), I’m pretty sure that strongly coupling my blog with my personal moniker will prove to be a smart thing in the long run.</p>
<p>So – I welcome you to vjeko.com, my new domain, and I hope that I find enough time to transform the to-do list I accumulated while working on the new blog into actual posts soon. Stay tuned, and hey – tell me what you think about this move!</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/retiring-navigateintosuccess-com">http://vjeko.com/blog/retiring-navigateintosuccess-com</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=RKU9oFgrf2s:r6ccWNO4wRY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=RKU9oFgrf2s:r6ccWNO4wRY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/retiring-navigateintosuccess-com/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How Do I… Videos on MSDN</title>
		<link>http://vjeko.com/blog/how-do-i-videos-on-msdn</link>
		<comments>http://vjeko.com/blog/how-do-i-videos-on-msdn#comments</comments>
		<pubDate>Sat, 16 Mar 2013 14:01:00 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Dynamics NAV]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[How do I]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[Plataan]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1264</guid>
		<description><![CDATA[MSDN has started running a series of the How do I… videos for Microsoft Dynamics NAV 2013 (feed here). The idea is to showcase a technical feature in 5-15 minutes. The project is still ongoing, but a number of videos have just been released and announced on the Microsoft Dynamics NAV Team Blog. The project is a joint effort by Plataan and Microsoft, and I participated as a technical expert in charge of seven videos. I’ve already recorded five of them, out of which three are online. You can find the links below, and please come back to this page as I’ll update it as more videos are published. Deploying Microsoft Dynamics NAV 2013 with System Center 2012 Support How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part I How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part II How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part III Queries, Reports, and Charts in Microsoft Dynamics NAV 2013 How Do I: Consume a Query in Microsoft Dynamics NAV How Do I: Create a Document Report How Do I: Consume Query data in Windows 8 How Do I: Build a Chart Based upon a Query How Do I: Build a Fact Box based on a Query Microsoft Dynamics NAV and Social Media How Do I: Integrate Microsoft Dynamics NAV 2013 with Yammer Getting Up and Running with Microsoft Dynamics NAV 2013 How Do I: Implement a Microsoft Dynamics NAV Solution using RapidStart Services I hope you like the videos, and learn something from them. Read this post at its original location at http://vjeko.com/blog/how-do-i-videos-on-msdn, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2013/03/image1.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 8px 8px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2013/03/image_thumb.png" width="202" height="114" /></a>MSDN has started running a series of the <a href="http://msdn.microsoft.com/en-us/bb629407.aspx" target="_blank">How do I… videos</a> for Microsoft Dynamics NAV 2013 (<a href="http://www.microsoft.com/feeds/msdn/en-us/videos/microsoft_dynamics_NAV_2013.xml" target="_blank">feed here</a>). The idea is to showcase a technical feature in 5-15 minutes. The project is still ongoing, but a number of videos have just been released and announced on the <a href="http://blogs.msdn.com/b/nav/archive/2013/03/15/new-how-do-i-videos-for-microsoft-dynamics-nav-2013-on-microsoft-dynamics-nav-dev-center.aspx" target="_blank">Microsoft Dynamics NAV Team Blog</a>.</p>
<p>The project is a joint effort by <a href="http://www.plataan.be/EN/Default.aspx" target="_blank">Plataan</a> and Microsoft, and I participated as a technical expert in charge of seven videos. I’ve already recorded five of them, out of which three are online.</p>
<p>You can find the links below, and please come back to this page as I’ll update it as more videos are published.</p>
<p><span id="more-1266"></span><br />
<h6><strong>Deploying Microsoft Dynamics NAV 2013 with System Center 2012 Support</strong></h6>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/jj945399">How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part I</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/jj945400">How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part II</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/jj945401">How Do I: Microsoft Dynamics NAV 2013 Management Pack for System Center, Part III</a></li>
</ul>
<h6><strong>Queries, Reports, and Charts in Microsoft Dynamics NAV 2013</strong></h6>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130609">How Do I: Consume a Query in Microsoft Dynamics NAV</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130610">How Do I: Create a Document Report</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130604">How Do I: Consume Query data in Windows 8</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130605">How Do I: Build a Chart Based upon a Query</a></li>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130607">How Do I: Build a Fact Box based on a Query</a></li>
</ul>
<h6><strong>Microsoft Dynamics NAV and Social Media</strong></h6>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130606">How Do I: Integrate Microsoft Dynamics NAV 2013 with Yammer</a></li>
</ul>
<h6><strong>Getting Up and Running with Microsoft Dynamics NAV 2013</strong></h6>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/dynamics/nav/xx130611">How Do I: Implement a Microsoft Dynamics NAV Solution using RapidStart Services</a></li>
</ul>
<p>I hope you like the videos, and learn something from them.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/how-do-i-videos-on-msdn">http://vjeko.com/blog/how-do-i-videos-on-msdn</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=dOuweNCwlyQ:yjHJe5q_gJ8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=dOuweNCwlyQ:yjHJe5q_gJ8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/how-do-i-videos-on-msdn/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Transaction Integrity with Connected Systems</title>
		<link>http://vjeko.com/blog/transaction-integrity-with-connected-systems</link>
		<comments>http://vjeko.com/blog/transaction-integrity-with-connected-systems#comments</comments>
		<pubDate>Tue, 05 Mar 2013 11:30:50 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[Transaction integrity]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1260</guid>
		<description><![CDATA[With .NET Interoperability around, it’s very likely you’ll be synchronously calling external web services from C/AL, to exchange data. I won’t go into discussing whether or not this kind of architecture is good (my own position is that it isn’t), you may end up having situations where your C/AL code simply makes a synchronous call to external systems, such as web services. Any external call is an expected point of failure. An important question you must always have in mind when calling external functions is transaction integrity. When writing code that targets only NAV, the structure of code is largely irrelevant, as long as you are not using COMMITs (which is another thing you should avoid at all costs). However, as soon as you introduce external calls, the structure becomes critically relevant. Critically relevant. I’ve talked about this during my 2012 NAV TechDays session, and I promised I’d blog about it – so, here it goes. Let me start with the rule first: whenever making external calls from C/AL, make sure they are the last thing that’s called in the transaction. Remember this whenever calling external systems synchronously from C/AL. Imagine you have another system, let’s call it Bongo, that keeps track of customers. When a customer is created in NAV, it must be created in Bongo. When it’s deleted in NAV, it must be deleted in Bongo. Now you have this code: OnCreate() IF &#34;No.&#34; = &#8221; THEN BEGIN &#160; SalesSetup.GET; &#160; SalesSetup.TESTFIELD(&#34;Customer Nos.&#34;); &#160; NoSeriesMgt.InitSeries(SalesSetup.&#34;Customer Nos.&#34;,xRec.&#34;No. Series&#34;,0D,&#34;No.&#34;,&#34;No. Series&#34;); END; IF &#34;Invoice Disc. Code&#34; = &#8221; THEN &#160; &#34;Invoice Disc. Code&#34; := &#34;No.&#34;; IF NOT InsertFromContact THEN &#160; UpdateContFromCust.OnInsert(Rec); DimMgt.UpdateDefaultDim( &#160; DATABASE::Customer,&#34;No.&#34;, &#160; &#34;Global Dimension 1 Code&#34;,&#34;Global Dimension 2 Code&#34;); &#160; All red marked [...]]]></description>
				<content:encoded><![CDATA[<p><img title="Broken pencil" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 8px 8px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Broken pencil" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2013/03/image.png" width="202" height="153" />With .NET Interoperability around, it’s very likely you’ll be synchronously calling external web services from C/AL, to exchange data. I won’t go into discussing whether or not this kind of architecture is good (my own position is that it isn’t), you may end up having situations where your C/AL code simply makes a synchronous call to external systems, such as web services.</p>
<p>Any external call is an expected point of failure. An important question you must always have in mind when calling external functions is transaction integrity. When writing code that targets only NAV, the structure of code is largely irrelevant, as long as you are not using COMMITs (which is another thing you should avoid at all costs). However, as soon as you introduce external calls, the structure becomes critically relevant. Critically relevant.</p>
<p>I’ve talked about this during my 2012 NAV TechDays session, and I promised I’d blog about it – so, here it goes.</p>
<p><span id="more-1260"></span>
<p>Let me start with the rule first: <strong><u>whenever making external calls from C/AL, make sure they are the last thing that’s called in the transaction.</u></strong></p>
<p>Remember this whenever calling external systems synchronously from C/AL.</p>
<p>Imagine you have another system, let’s call it Bongo, that keeps track of customers. When a customer is created in NAV, it must be created in Bongo. When it’s deleted in NAV, it must be deleted in Bongo.</p>
<p>Now you have this code:</p>
<p><font style="background-color: #a5a5a5" face="Courier New"><strong>OnCreate()</strong></font></p>
<p><font face="Courier New">IF &quot;No.&quot; = &#8221; THEN BEGIN      <br />&#160; <font color="#ff0000">SalesSetup.GET;        <br />&#160; SalesSetup.TESTFIELD(&quot;Customer Nos.&quot;);         <br />&#160; NoSeriesMgt.InitSeries(SalesSetup.&quot;Customer Nos.&quot;,xRec.&quot;No. Series&quot;,0D,&quot;No.&quot;,&quot;No. Series&quot;);         <br /></font>END;       <br />IF &quot;Invoice Disc. Code&quot; = &#8221; THEN       <br />&#160; &quot;Invoice Disc. Code&quot; := &quot;No.&quot;;</font></p>
<p><font face="Courier New">IF NOT InsertFromContact THEN      <br /><font color="#ff0000">&#160; UpdateContFromCust.OnInsert(Rec);</font></font></p>
<p><font color="#ff0000" face="Courier New">DimMgt.UpdateDefaultDim(      <br />&#160; DATABASE::Customer,&quot;No.&quot;,       <br />&#160; &quot;Global Dimension 1 Code&quot;,&quot;Global Dimension 2 Code&quot;);</font></p>
<p>&#160;</p>
<p>All red marked lines above are possible failure points – at any of those, a runtime error can stop the execution, and the customer would not get inserted in NAV. The structure really doesn’t matter from the transactional integrity point of view, as all of this is a single transaction, and if any line fails, no data is written to the database.</p>
<p>Imagine that you add this Bongo synchronization now. You can do it like this:</p>
<p><font style="background-color: #a5a5a5" face="Courier New"><strong>OnCreate()</strong></font></p>
<p><font color="#000000" face="Courier New">IF &quot;No.&quot; = &#8221; THEN BEGIN      <br />&#160; SalesSetup.GET;       <br />&#160; SalesSetup.TESTFIELD(&quot;Customer Nos.&quot;);       <br />&#160; NoSeriesMgt.InitSeries(SalesSetup.&quot;Customer Nos.&quot;,xRec.&quot;No. Series&quot;,0D,&quot;No.&quot;,&quot;No. Series&quot;);       <br />END;</font></p>
<p><font color="#000000" face="Courier New">// Bongo &gt;      <br /></font><font color="#ff0000" face="Courier New">CreateInBongo(Rec);      <br /></font><font color="#000000" face="Courier New">// Bongo &lt;</font></p>
<p><font color="#000000" face="Courier New">IF &quot;Invoice Disc. Code&quot; = &#8221; THEN      <br />&#160; &quot;Invoice Disc. Code&quot; := &quot;No.&quot;;</font></p>
<p><font color="#000000" face="Courier New">IF NOT InsertFromContact THEN      <br />&#160; <font color="#9b00d3">UpdateContFromCust.OnInsert(Rec);</font></font></p>
<p><font color="#000000" face="Courier New">DimMgt.UpdateDefaultDim(      <br />&#160; DATABASE::Customer,&quot;No.&quot;,       <br />&#160; &quot;Global Dimension 1 Code&quot;,&quot;Global Dimension 2 Code&quot;);</font></p>
<p>&#160;</p>
<p>This new line of code is a new failure point, however, this one is a separate transaction, which has no integration with the transaction in NAV. If this line fails, no problem, as it is just another failure point for NAV. However, if this line succeeds, and it fails at the violet colored line above then you have a problem: the customer, that does not exist in NAV, has just been created in Bongo.</p>
<p>The code should look like this:</p>
<p><font style="background-color: #a5a5a5" face="Courier New"><strong>OnCreate()</strong></font></p>
<p><font color="#000000" face="Courier New">IF &quot;No.&quot; = &#8221; THEN BEGIN      <br />&#160; SalesSetup.GET;       <br />&#160; SalesSetup.TESTFIELD(&quot;Customer Nos.&quot;);       <br />&#160; NoSeriesMgt.InitSeries(SalesSetup.&quot;Customer Nos.&quot;,xRec.&quot;No. Series&quot;,0D,&quot;No.&quot;,&quot;No. Series&quot;);       <br />END;</font></p>
<p><font color="#000000" face="Courier New">IF &quot;Invoice Disc. Code&quot; = &#8221; THEN      <br />&#160; &quot;Invoice Disc. Code&quot; := &quot;No.&quot;;</font></p>
<p><font color="#000000" face="Courier New">IF NOT InsertFromContact THEN      <br />&#160; <font color="#9b00d3">UpdateContFromCust.OnInsert(Rec);</font></font></p>
<p><font color="#000000" face="Courier New">DimMgt.UpdateDefaultDim(      <br />&#160; DATABASE::Customer,&quot;No.&quot;,       <br />&#160; &quot;Global Dimension 1 Code&quot;,&quot;Global Dimension 2 Code&quot;);</font></p>
<p><font color="#000000" face="Courier New">// Bongo &gt;      <br /></font><font color="#ff0000" face="Courier New">CreateInBongo(Rec);      <br /></font><font color="#000000" face="Courier New">// Bongo &lt;</font></p>
<p>&#160;</p>
<p>The principle is very simple – you first execute everything in the local transaction. If something fails, Bongo is not even called. If all works locally, the transaction is still waiting for Bongo to complete. If Bongo fails, then the local transaction fails because an error occurred. If Bongo succeeds, the local transaction commits.</p>
<p>Always put the code that targets external systems at the end, never at the beginning or in the middle.</p>
<p>And yes – of course – there is no way to absolutely guarantee the transaction integrity between NAV and Bongo, or whatever it is on the other end. Technically, a web service call can fail on the transport layer, after the transaction has been committed to Bongo, and then your C/AL code structure will not help. Without a transaction coordinator layer somewhere between the systems, you are toast. That’s why I said that synchronous calls to external web services (at least for data replication or exchange goes) are not architecturally good.</p>
<p>However, from time to time, you’ll have to do this for whatever reasons. When you do it, remember these five words: external calls at the end.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/transaction-integrity-with-connected-systems">http://vjeko.com/blog/transaction-integrity-with-connected-systems</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=lidyWfl7OKE:ejNzKZxPvvo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=lidyWfl7OKE:ejNzKZxPvvo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/transaction-integrity-with-connected-systems/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cross-Call State Sharing in Web Services</title>
		<link>http://vjeko.com/blog/cross-call-state-sharing-in-web-services</link>
		<comments>http://vjeko.com/blog/cross-call-state-sharing-in-web-services#comments</comments>
		<pubDate>Thu, 21 Feb 2013 00:11:52 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[NAV 2009 R2]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[State]]></category>
		<category><![CDATA[Static]]></category>
		<category><![CDATA[Thread safety]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1257</guid>
		<description><![CDATA[Web services in NAV have an interesting feature: they are stateless. For a system which is pretty stateful otherwise, this feature can be outright annoying. You must get used to it, and then make sure you never ever write code as if there was any state preserved on the other end. The reason for this is simple – there is no actual protocol that you use to communicate with NAV through SOAP. Calls are ad-hoc, essentially atomic, each one can accomplish a great deal of things in a single go, and it makes programming a whole lot simpler. The price you pay is the state. Once you close the connection, the session ends and the transaction commits (or rolls back). Next call starts from scratch. If you need to preserve any state between the calls, whatever that state might be, you are toast. NAV simply doesn’t support it out of the box. A common misconception is that single-instance codeunits help. They don’t. The single instance is always single per session, and since each call is an isolated session, it means that each single instance codeunit dies at the end of the call. Pretty annoying, isn’t it? Well, it is, and it isn’t. I won’t argue about validity of situations where you need to preserve state across multiple web services calls – I am going to show you how to do it when you need it. And what I’m going to show you works in both NAV 2009 R2 and 2013. There are a hundred ways to skin a cat (no animals were harmed during writing of this post) and there are possibly as many ways to store state between calls. They mostly depend on non-volatile [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2013/02/image.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 8px 8px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2013/02/image_thumb.png" width="202" height="136" /></a>Web services in NAV have an interesting feature: they are stateless. For a system which is pretty stateful otherwise, this feature can be outright annoying. You must get used to it, and then make sure you never ever write code as if there was any state preserved on the other end.</p>
<p>The reason for this is simple – there is no actual <em>protocol</em> that you use to communicate with NAV through SOAP. Calls are ad-hoc, essentially atomic, each one can accomplish a great deal of things in a single go, and it makes programming a whole lot simpler. The price you pay is the state. Once you close the connection, the session ends and the transaction commits (or rolls back). Next call starts from scratch.</p>
<p>If you need to preserve any state between the calls, whatever that state might be, you are toast. NAV simply doesn’t support it out of the box. A common misconception is that single-instance codeunits help. They don’t. The single instance is always single per session, and since each call is an isolated session, it means that each single instance codeunit dies at the end of the call.</p>
<p>Pretty annoying, isn’t it?</p>
<p>Well, it is, and it isn’t. I won’t argue about validity of situations where you need to preserve state across multiple web services calls – I am going to show you how to do it when you need it.</p>
<p>And what I’m going to show you works in both NAV 2009 R2 and 2013.</p>
<p><span id="more-1265"></span>
<p>There are a hundred ways to skin a cat (no animals were harmed during writing of this post) and there are possibly as many ways to store state between calls. They mostly depend on non-volatile approaches, such as database, file system or similar. If you ask me, state should be volatile, so how do we accomplish this?</p>
<p>The concept I like to apply here is the one I explained and demonstrated in my Web Services Black Belt session at NAV TechDays 2012 in Antwerp: it’s the static classes in .NET. Static classes, or static members of dynamic classes in .NET are isolated for an application domain and they remain in memory as long as the application is running. Pretty volatile if you ask me. Since NST is a .NET application, keeping a static class in its domain achieves my goal.</p>
<p><strong>Step 1: The Class</strong></p>
<p>I’ll first create a new class in .NET. It must be classic and must have some methods to store and retrieve objects from it. In my example, I’ll use a Dictionary object to store key-value pairs of strings and objects. This allows you to store any simple data type into the State. Here’s the code:</p>
<p><font size="2" face="Courier New">namespace Demo      <br />{       <br />&#160;&#160;&#160; public static class StateManager       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private static Dictionary&lt;String, Object&gt; _state =       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </font><font size="2" face="Courier New">new Dictionary&lt;String, Object&gt;();</font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static void Set(string key, object value)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Clear(key);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _state.Add(key, value);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static Object Get(string key)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (_state.ContainsKey(key))       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return _state[key];       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return null;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static void Clear(string key)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (_state.ContainsKey(key))       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _state.Remove(key);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static void Clear()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _state.Clear();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br /></font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static bool Exists(string key)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return _state.ContainsKey(key);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>
<p><font size="2" face="Courier New">&#160;&#160;&#160; }      <br />}       <br /></font></p>
<p>&#160;</p>
<p>Should be pretty self explanatory. If it isn’t, there is a static private dictionary member that is instantiated on the first access. There are Set and Get methods to store and retrieve anything to and from the state. There is a Clear method which can either remove a single object from the state, or clear all objects. Finally, there is a method to check if an object exists in the state.</p>
<p>Now compile this and deploy it to either Add-ins or GAC. Your choice entirely.</p>
<p>Yeah, yeah, I know, all you .NET ninjas out there – this is not thread safe. Scroll down, it’s our last step. I don’t want to confuse all non-DotNet folks here with unnecessary stuff. First things first.</p>
<p><strong>Step 2: Consuming the Class</strong></p>
<p>Now that we have the class, let’s consume it. I’ll create a new codeunit that provides access to this state. It is nothing but a C/AL wrapper around the C# class above. Here it goes:</p>
<p><font style="background-color: #a5a5a5" size="2" face="Courier New">Documentation()</font></p>
<p><font style="background-color: #a5a5a5" size="2" face="Courier New">OnRun()</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">SetString(Key : Text;Value : Text)        <br /></font>State.Set(Key,Value);</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">GetString(Key : Text) : Text        <br /></font>EXIT(State.Get(Key));</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">SetDate(Key : Text;Value : Date)        <br /></font>State.Set(Key,Value);</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">GetDate(Key : Text) : Date        <br /></font>EXIT(DT2DATE(State.Get(Key)));</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">Exists(Key : Text) : Boolean        <br /></font>EXIT(State.Exists(Key));</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">Clear(Key : Text)</font>       <br />State.Clear(Key);</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">ClearAll()</font>       <br />State.Clear;</font></p>
<p>I’m pretty sure that I don’t need to explain what the State variable in the above piece of code is. I’ll say one thing: it’s global (even though it should be pretty obvious, too). I also hope that I don’t need to explain why I have GetString, SetString, GetDate, SetDate functions here. C/AL doesn’t understand the concept of <a href="http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx" target="_blank">boxing</a> and that’s why you’ll need to create as many Get/Set function pairs as there are data types you want to store. You cannot use variants because they make the codeunit unavailable to web services, and you can’t return a variant from a function.</p>
<p>A funky thing here is that when you box a C/AL Date type into Object, it gets automatically translated into DateTime, but when you unbox it, you cannot directly unbox it into the C/AL Date type. Probably a bug in .NET interoperability, but the workaround is extremely simple, as you can see above.</p>
<p>Save this codeunit, publish it as a web service, and off you go.</p>
<p><strong>Step 3: Implement the State</strong></p>
<p>Let’s take a real-life scenario: work date. In Web services, work date always defaults to current system date. Sometimes, especially in page web services, in relation to, for example, number series, this can be pretty annoying. Let’s use our state manager to make web services use a different work date for page calls.</p>
<p>I’ll first add the SetWorkDate and ApplyStateWorkDate functions to the state manager codeunit:</p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">SetWorkDate(Date : Date)       <br /></font>SetDate(Text_STATE_WORKDATE,Date);</font></p>
<p><font size="2" face="Courier New"><font style="background-color: #a5a5a5">ApplyStateWorkDate()       <br /></font>IF Exists(Text_STATE_WORKDATE) THEN      <br />&#160; WORKDATE := GetDate(Text_STATE_WORKDATE);</font></p>
<p>Here, you only need to declare a text constant with a unique value that you use as a key to store the date in the state manager.</p>
<p>Then, in the page you want to make use the work date from the state, modify the OnInit trigger to include this piece of code:</p>
<p><font size="2" face="Courier New">StateMgt.ApplyStateWorkDate;</font></p>
<p>&#160;</p>
<p>I’ll use the SalesOrder page (42).</p>
<p><strong>Step 4: Verifying the State</strong></p>
<p>Next step is to verify that this works. So, publish the page 42 (or whichever one you wanted to use) as a web service, and from your consumer application, call the state manager codeunit web service first to set a work date to some value, and then call the sales order page web service to create a new sales order. This is my demo code, you might need to tweak it left or right:</p>
<p><font size="2" face="Courier New">var state =     <br />&#160;&#160;&#160; new StateManagement      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UseDefaultCredentials = true,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Url =&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;</font><font size="2" face="Courier New">http://localhost:7147/DynamicsNAV70/WS/CRONUS</font><font size="2" face="Courier New"> International Ltd./Codeunit/StateManagement&quot;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />state.SetWorkDate(new DateTime(2011, 10, 10));</font></p>
<p><font size="2" face="Courier New">var salesOrderSvc =     <br />&#160;&#160;&#160; new SalesOrder.SalesOrder_Service      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UseDefaultCredentials = true,      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Url =      <br />&quot;</font><font size="2" face="Courier New">http://localhost:7147/DynamicsNAV70/WS/CRONUS</font><font size="2" face="Courier New"> International Ltd./Page/SalesOrder&quot;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; };</font></p>
<p><font size="2" face="Courier New">var salesOrder = new SalesOrder.SalesOrder();     <br />salesOrderSvc.Create(ref salesOrder);</font></p>
<p><font size="2" face="Courier New">MessageBox.Show(salesOrder.Document_Date.ToString());</font></p>
<p><font size="2" face="Courier New"></font></p>
<p>Now, run it and admire it. It first stores October 10, 2011 as your work date, and then creates a sales order on this date. Pretty fly for a web service call.</p>
<p><strong>Step 5: Thread safety, and other ninja stuff</strong></p>
<p>If you’ve made it this far, you must speak both C/AL and C# fluently and you have been keeping that “yes, but…” for quite a while. As I mentioned earlier – this stuff is not thread safe.</p>
<p>Thread safety is something that, before .NET Interoperability, you never had to worry about in C/AL. Now, you must worry about it whenever writing your own classes intended for consumption from C/AL. You also must worry about it when consuming thread-unsafe third-party assemblies, which is a story for another post.</p>
<p>In short – <a href="http://en.wikipedia.org/wiki/Thread_safety" target="_blank">thread safety</a> is a concept that applies to situations when multiple threads are accessing the shared piece of data. Since NAV Service Tier is a heavily multi-threaded application, and since static classes are shared data, you must make all of your static classes thread-safe.</p>
<p>There are many different approaches to achieving thread safety. The simplest is to synchronize access to shared data through locks. Simply lock the _state variable before each access, and you are good. For example, instead of the code above for Set and Get methods, write this:</p>
<p><font size="2" face="Courier New">public static void Set(string key, object value)     <br />{      <br />&#160;&#160;&#160; lock (_state)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Clear(key);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _state.Add(key, value);      <br />&#160;&#160;&#160; }      <br />}</font></p>
<p><font size="2" face="Courier New">public static Object Get(string key)     <br />{      <br />&#160;&#160;&#160; lock (_state)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (_state.ContainsKey(key))      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return _state[key];      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return null;      <br />&#160;&#160;&#160; }      <br />}</font></p>
<p>Of course, do this for all methods that access the _state variable.</p>
<p>Another possibility you have here is to use the ConcurrentDictionary class of .NET Framework 4.0 and above, but this is applicable only to NAV 2013.</p>
<p>Just remember – your static classes, and classic members of your dynamic classes, must be thread safe. If they are not, see for yourself what happens. Hint: it doesn’t work.</p>
<p><strong>And in the end…</strong></p>
<p>And now that you reached this far, let me say that yes – I am still alive, and no – I didn’t stop blogging or have any intentions of stopping blogging. Over last year I was pretty busy writing content for NAV 2013 courseware, and this year I started doing some very similar stuff, which I’ll soon also blog about. The point is – I’m here, I’m glad that you are here, too, and I’ll blog whenever I get a chance about stuff that I believe is relevant. Stay tuned, and see you around.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/cross-call-state-sharing-in-web-services">http://vjeko.com/blog/cross-call-state-sharing-in-web-services</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Vzdh5IowUIw:HzvRXyMitC8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Vzdh5IowUIw:HzvRXyMitC8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/cross-call-state-sharing-in-web-services/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Some tips and hints about temporary tables</title>
		<link>http://vjeko.com/blog/some-tips-and-hints-about-temporary-tables</link>
		<comments>http://vjeko.com/blog/some-tips-and-hints-about-temporary-tables#comments</comments>
		<pubDate>Thu, 01 Nov 2012 10:26:53 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[By reference]]></category>
		<category><![CDATA[By value]]></category>
		<category><![CDATA[C/AL]]></category>
		<category><![CDATA[Temporary tables]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1253</guid>
		<description><![CDATA[Temporary tables in NAV are a great thing, and are frequently used, but there are some misconceptions about them. I see developers do the same mistakes time after time and again. In this post I’ll address some common misconceptions and give some tips and hints that you can use in practice. There may be a lot of basics for you here, in which case just skip to the end: there I give you a nice tip about how to prevent accidental changes to physical tables when you expect that a table is temporary, and in fact it is not. A temporary table is a record variable on which you have set the Temporary property to Yes. When you do this, the record variable has the same structure as the physical table, but it is only stored in memory. When you create a temporary record variable, the temporary table is empty at first, and then you can insert, modify, or delete data in it at will, and it does not affect the physical table. I’m quite sure you knew this much, but I repeated it here just to show you how smart I am Temporary Tables in Function Parameters One thing that is frequently done is passing around temporary tables to functions as parameters. What often goes wrong here is that people tend to think that inside the function the table is temporary because the variable passed to it is temporary. In fact – it’s not. Or at least not always. First thing to know about record variables is that a record variable does not represent the whole table. It only represents as much as it says on the tin: the record – or to be [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/MP9004330711.jpg"><img title="MP900433071[1]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="MP900433071[1]" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/MP9004330711_thumb.jpg" width="240" height="160" /></a>Temporary tables in NAV are a great thing, and are frequently used, but there are some misconceptions about them. I see developers do the same mistakes time after time and again. In this post I’ll address some common misconceptions and give some tips and hints that you can use in practice.</p>
<p>There may be a lot of basics for you here, in which case just skip to the end: there I give you a nice tip about how to prevent accidental changes to physical tables when you expect that a table is temporary, and in fact it is not.</p>
<p><span id="more-1264"></span>
<p>A temporary table is a record variable on which you have set the <strong>Temporary</strong> property to Yes. When you do this, the record variable has the same structure as the physical table, but it is only stored in memory. When you create a temporary record variable, the temporary table is empty at first, and then you can insert, modify, or delete data in it at will, and it does not affect the physical table. I’m quite sure you knew this much, but I repeated it here just to show you how smart I am <img class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Smile with tongue out" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/wlEmoticon-smilewithtongueout.png" /></p>
<p><strong>Temporary Tables in Function Parameters</strong></p>
<p>One thing that is frequently done is passing around temporary tables to functions as parameters. What often goes wrong here is that people tend to think that inside the function the table is temporary because the variable passed to it is temporary. In fact – it’s not. Or at least not always.</p>
<p>First thing to know about record variables is that a record variable does not represent the whole table. It only represents as much as it says on the tin: the record – or to be as precise as it gets – a single record (row) in a table. The <strong>Temporary</strong> property is simply telling you where the runtime will store the changes you make if you call any of the data modification functions, or where it will look for more records if you iterate through data or run any of the <strong>FIND </strong>functions.</p>
<p>Another piece of theory is about function parameters. A parameter can be <em>by value </em>or <em>by reference</em>. By value means that the runtime establishes a new in-memory space for the parameter and when you call the function the value of the variable (or constant, or expression) passed to the function is copied into this freshly allocated memory space – literally you get a copy of the original value. By reference means that the runtime literally takes the variable into the function and the parameter is merely another name tag attached to the same variable that was passed to the function.</p>
<p>Last piece of theory here is about record type as a function parameter. When declaring a parameter of type record, you can set its <strong>Temporary </strong>property to Yes or No, as with any other record variable.</p>
<p>If you combine the last two theory bits, about parameters, and about record type, you may believe that you have these four combinations:</p>
<ul>
<li>Record, by value </li>
<li>Temporary record, by value </li>
<li>Record, by reference </li>
<li>Temporary record, by reference </li>
</ul>
<p>In fact, you don’t. There are only three combinations:</p>
<ul>
<li>Record by value</li>
<li>Temporary record by value</li>
<li>By reference</li>
</ul>
<p>The first two are simple: if the parameter is by value, then the <strong>Temporary</strong> property on the parameter determines whether within the function the table will be temporary, or physical.</p>
<p>Check this out:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb.png" width="411" height="190" /></a></p>
<p>Within the first two functions, the actual state of the Cust record is determined by the <strong>Temporary </strong>property set on the parameter. If you pass a physical record variable to DoSomething_Temporary, the field values of that physical record will get copied to the Cust record, but the Cust will continue to be temporary.</p>
<p>Just as if you did this: Cust := Customer_Physical;</p>
<p>The same applies if you call DoSomething_Physical and pass the Customer_Temporary to it. The field values are copied, but Cust refers to the physical table.</p>
<p>Furthermore, when you have <strong>Temporary</strong> set to Yes on a by-value parameter, that temporary table is always empty when the function is called. Just as if you declared a local temporary record variable. That’s because the runtime first establishes a new memory space for the by-value parameter.</p>
<p>So, this covers the first two cases. Now for the third case.</p>
<p>If the record parameter is by reference, then the <strong>Temporary</strong> property makes absolutely no difference. These two are essentially equal:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image1.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb1.png" width="405" height="81" /></a></p>
<p>When you pass a variable by reference, you don’t allocate new memory space: you simply pass the whole variable. The <strong>Temporary </strong>property is then taken from the variable, regardless of what you set as the <strong>Temporary </strong>property on the parameter itself. If you pass a physical table to a temporary by-reference parameter, the parameter record within the function is physical. Also, if you pass a temporary table to a non-temporary by-reference parameter, the parameter record within the function is temporary.</p>
<p>Not understanding this may have devastating effects on your data. Imagine this:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb2.png" width="403" height="89" /></a></p>
<p>This deletes all of your customers from the physical table (those in the filter, at least). The <strong>Temporary</strong> property had no effect – you have passed the whole variable including all of its properties, including <strong>Temporary</strong>.</p>
<p>Therefore, setting <strong>Temporary </strong>on a by-reference parameter makes absolutely no difference. Never forget this.</p>
<p><strong>Temporary Records and Transactions</strong></p>
<p>Another misconception about temporary records is that they are managed as transactions. They are not. When you call COMMIT, it does not affect your temporary tables. Also, if you call ERROR, it won’t rollback any inserts, changes, or deletions from your temporary tables.</p>
<p>There is not much rocket science around this, really. </p>
<p><strong>SourceTableTemporary</strong></p>
<p>The <strong>SourceTableTemporary </strong>property on pages (or forms in 5.0 and 2009) allows you to run pages that only work over temporary data. When you run them, they are empty, and then you need to populate them with data. You do that by simply filling in the data in the Rec variable.</p>
<p>One typical problem I’ve frequently seen with pages (or forms) over temporary data, is that the Rec variable is passed by reference, and then iterated over. That’s not the smartest thing in the world. In certain versions of clients, this may cause phantom inserts – if you are positioned on the new row, and then call a function which iterates over a range of rows to do something, and then leaves the row positioned on an actual row.</p>
<p>For example:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image3.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb3.png" width="298" height="128" /></a></p>
<p>Let’s set the phantom inserts aside for a while, and just apply a simple trick here that works – and should always be done anyway – with physical tables as well: when entering a function where a record variable is passed by reference, store the position of the current record, and when exiting the function, restore the record to its original position:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb4.png" width="308" height="185" /></a></p>
<p><strong>By Reference – How to Know Temporary from Physical?</strong></p>
<p>And finally, for the tip: when in a function that receives a record variable by reference, how do you know if the record is temporary or physical? You may “know” that your function will always be called with temporary record (or you may set its <strong>Temporary </strong>property to Yes to “ensure” it) but in fact for by-reference whether it’s temporary or not is determined by the actual variable. So, don’t do something crazy like this and delete your G/L:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image5.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb5.png" width="414" height="121" /></a></p>
<p>You know by now that the GLEntryTemp record may – <em>or may not!!</em> – be temporary. Instead of populating the physical G/L Entries into a temporary table, you may end up deleting all of the entries from the actual, physical G/L Entry table. Probably not something you’d want to do on your regular Thursday.</p>
<p>To avoid headache, just do a simple sanity check:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/11/image_thumb6.png" width="495" height="196" /></a></p>
<p>You simply create a record reference over the parameter, and then check its ISTEMPORARY property before you do anything crazy with those physical tables.</p>
<p>So – I hope this was useful and helpful. If not, just feel free to boo me publicly here.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/some-tips-and-hints-about-temporary-tables">http://vjeko.com/blog/some-tips-and-hints-about-temporary-tables</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=oqryvXw9r4I:y8LqvuiQqys:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=oqryvXw9r4I:y8LqvuiQqys:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/some-tips-and-hints-about-temporary-tables/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Web Services Black Belt: consuming NAV web services using pure C/AL</title>
		<link>http://vjeko.com/blog/web-services-black-belt-consuming-nav-web-services-using-pure-cal</link>
		<comments>http://vjeko.com/blog/web-services-black-belt-consuming-nav-web-services-using-pure-cal#comments</comments>
		<pubDate>Sun, 30 Sep 2012 20:23:29 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[NAV]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1233</guid>
		<description><![CDATA[Have you ever needed to connect to the Web services of one NAV instance from another one? If so, I bet that the approach was something like this: you created a .NET class where you defined a Web or Service reference to the target instance, and then you consumed that .NET class using .NET Framework interoperability. It was kind of clumsy, inflexible, but it worked. How cool would it be if you could do something like this: WITH WebService DO BEGIN &#160; CONNECT(&#8216;http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer&#8217;); &#160; INIT; &#160; SETVALUE(&#8216;Name&#8217;,'Test Customer&#8217;); &#160; SETVALUE(&#8216;Blocked&#8217;,Cust.Blocked::Ship); &#160; SETVALUE(&#8216;Credit_Limit_LCY&#8217;,10000); &#160; CREATE; &#160; MESSAGE(&#8216;I just created Customer No. %1 in another NAV instance.&#8217;,GETVALUE(&#8216;No&#8217;)); END; As a matter of fact, you can write something like that. You can write exactly that. And it compiles, runs, and accomplishes exactly what you expect it to do. The most beautiful thing, you don’t need to write a single line of code in Visual Studio, or deploy any external dependencies – it uses pure C/AL, and works equally well in NAV 2009 and NAV 2013. The only thing you need is a simple codeunit that you can download from Mibuso. If you missed the link in the previous sentence, then click here. I wrote that codeunit as a part of the demo I presented last Wednesday at Mibuso NAV TechDays 2012 in Antwerp, and as promised – I am making the code available for you to use. This simple codeunit does no magic, it simply harnesses the power of the features built into the .NET Framework. It builds the proxy class and compiles it on the fly, and then uses reflection to instantiate objects, set properties, and call methods to allow you to interact with any NAV page [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/09/MP9004067791.jpg"><img title="MP900406779[1]" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 8px 8px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="MP900406779[1]" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/09/MP9004067791_thumb.jpg" width="200" height="133" /></a>Have you ever needed to connect to the Web services of one NAV instance from another one? If so, I bet that the approach was something like this: you created a .NET class where you defined a Web or Service reference to the target instance, and then you consumed that .NET class using .NET Framework interoperability. It was kind of clumsy, inflexible, but it worked.</p>
<p>How cool would it be if you could do something like this:</p>
<p>WITH WebService DO BEGIN     <br />&#160; CONNECT(&#8216;<a href="http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer');">http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer&#8217;);</a></p>
<p>&#160; INIT;    <br />&#160; SETVALUE(&#8216;Name&#8217;,'Test Customer&#8217;);     <br />&#160; SETVALUE(&#8216;Blocked&#8217;,Cust.Blocked::Ship);     <br />&#160; SETVALUE(&#8216;Credit_Limit_LCY&#8217;,10000);     <br />&#160; CREATE;</p>
<p>&#160; MESSAGE(&#8216;I just created Customer No. %1 in another NAV instance.&#8217;,GETVALUE(&#8216;No&#8217;));    <br />END;</p>
<p><span id="more-1233"></span>
<p>As a matter of fact, you can write something like that. You can write <em>exactly</em> that. And it compiles, runs, and accomplishes exactly what you expect it to do. The most beautiful thing, you don’t need to write a single line of code in Visual Studio, or deploy any external dependencies – it uses pure C/AL, and works equally well in NAV 2009 and NAV 2013.</p>
<p>The only thing you need is <a href="http://www.mibuso.com/dlinfo.asp?FileID=1472" target="_blank">a simple codeunit that you can download</a> from <a href="http://www.mibuso.com/" target="_blank">Mibuso</a>. If you missed the link in the previous sentence, then <a href="http://www.mibuso.com/dlinfo.asp?FileID=1472" target="_blank">click here</a>.</p>
<p>I wrote that codeunit as a part of the demo I presented last Wednesday at Mibuso NAV TechDays 2012 in Antwerp, and as promised – I am making the code available for you to use.</p>
<p>This simple codeunit does no magic, it simply harnesses the power of the features built into the .NET Framework. It builds the proxy class and compiles it on the fly, and then uses reflection to instantiate objects, set properties, and call methods to allow you to interact with any NAV page web service.</p>
<p>Before you can consume a NAV page Web service from C/AL you do not need to know anything about the service, except for its URL. If it’s a page web service, you can use it to read, create, update, and delete data in another NAV instance, simply using C/AL.</p>
<p>At this stage, it supports the following page web service functions:</p>
<ul>
<li>Read </li>
<li>ReadMultiple </li>
<li>Create </li>
<li>CreateMultiple </li>
<li>Update </li>
<li>UpdateMultiple </li>
<li>Delete </li>
</ul>
<p>Right now, I am providing no documentation for it, but I believe it should not be difficult to figure out what it can do by following these couple of examples.</p>
<h4></h4>
<h4>Creating a customer</h4>
<p>That’s the example above. Just declare a variable named WebService of type Codeunit 50113, and you are good to go.</p>
<h4>Iterating through a set of customers read, with a filter applied</h4>
<p>WITH WebService DO BEGIN     <br />&#160; CONNECT(&#8216;<a href="http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer');">http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer&#8217;);</a>     <br />&#160; SETFILTER(&#8216;Balance_LCY&#8217;,'&gt;0&#8242;);     <br />&#160; SETFILTER(&#8216;Name&#8217;,'A*&#8217;);     <br />&#160; IF READMULTIPLE THEN     <br />&#160;&#160;&#160; REPEAT     <br />&#160;&#160;&#160;&#160;&#160; MESSAGE(&#8216;Customer %1 %2 has balance of %3&#8242;,GETVALUE(&#8216;No&#8217;),GETVALUE(&#8216;Name&#8217;),GETVALUE(&#8216;Balance_LCY&#8217;));     <br />&#160;&#160;&#160; UNTIL NEXT = 0;     <br />END;     <br />EXIT;</p>
<h4>Updating an item</h4>
<p>WITH WebService DO BEGIN     <br />&#160; INIT;     <br />&#160; SETVALUE(&#8216;No’,’1000’);     <br />&#160; READ;     <br />&#160; SETVALUE(‘Description’,’Bicycle 2’);     <br />&#160; UPDATE;     <br />END;</p>
<h4>Creating a purchase order from a sales order</h4>
<p>WITH WebService DO BEGIN     <br />&#160; CONNECT(&#8216;<a href="http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/PurchOrder');">http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/PurchOrder&#8217;);</a>     <br />&#160; INIT;     <br />&#160; SETVALUE(&#8216;Buy_from_Vendor_No&#8217;,Rec.&quot;Sell-to Customer No.&quot;);     <br />&#160; SalesLine.SETRANGE(&quot;Document Type&quot;,Rec.&quot;Document Type&quot;);     <br />&#160; SalesLine.SETRANGE(&quot;Document No.&quot;,Rec.&quot;No.&quot;);     <br />&#160; IF SalesLine.FINDSET THEN     <br />&#160;&#160;&#160; REPEAT     <br />&#160;&#160;&#160;&#160;&#160; NEWLINE;     <br />&#160;&#160;&#160;&#160;&#160; SETLINEVALUE(&#8216;Type&#8217;,FORMAT(SalesLine.Type));     <br />&#160;&#160;&#160;&#160;&#160; SETLINEVALUE(&#8216;No&#8217;,FORMAT(SalesLine.&quot;No.&quot;));     <br />&#160;&#160;&#160;&#160;&#160; SETLINEVALUE(&#8216;Quantity&#8217;,SalesLine.Quantity);     <br />&#160;&#160;&#160; UNTIL SalesLine.NEXT = 0;     <br />&#160; CREATE;     <br />&#160; MESSAGE(&#8216;Purchase Order No. %1 is created in the vendor&#8221;s system.&#8217;,GETVALUE(&#8216;No&#8217;));     <br />END;</p>
<p>I’ll be updating the functionality of this codeunit and uploading a more comprehensive version, as I find time to do this.</p>
<p>This post is a series of posts where I’ll present most of the stuff I talked about at NAV TechDays 2012, and expand those topics into the areas that I either had to leave out due to time constraints, or that I thought were not as interesting as those that I chose to put into the presentation.</p>
<p>Please, let me know how you like this small gadget.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/web-services-black-belt-consuming-nav-web-services-using-pure-cal">http://vjeko.com/blog/web-services-black-belt-consuming-nav-web-services-using-pure-cal</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Lwa_qYBGJ1w:PQH-Y0YpzJw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Lwa_qYBGJ1w:PQH-Y0YpzJw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/web-services-black-belt-consuming-nav-web-services-using-pure-cal/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Benchmarking Results: NAV 2013 Outperforms All Previous Versions</title>
		<link>http://vjeko.com/blog/benchmarking-results-nav-2013-outperforms-all-previous-versions</link>
		<comments>http://vjeko.com/blog/benchmarking-results-nav-2013-outperforms-all-previous-versions#comments</comments>
		<pubDate>Mon, 25 Jun 2012 06:50:00 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[Classic]]></category>
		<category><![CDATA[Native database]]></category>
		<category><![CDATA[NAV]]></category>
		<category><![CDATA[Per Mogensen]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[RoleTailored]]></category>
		<category><![CDATA[RTC]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1223</guid>
		<description><![CDATA[Marketing is nice as long as it matches the reality. With Microsoft Dynamics NAV 2013, Microsoft has promised a lot of improvements, but how well does NAV 2013 stand the reality test? Apparently, outstandingly well. Over the past two days, I have intensively tested NAV 2009 and NAV 2013 through a series of five different tests that measure different aspects of NAV data handling. My conclusion is clear: NAV 2013 is faster than any NAV you have ever seen, including the Classic client on the native database. Continue reading to find out more about my findings and testing approach. Is This Some Kind Of A Trick? No, this is not a trick. It’s for real. Several days ago I wrote about performance improvements in Microsoft Dynamics NAV 2013, and then got a comment that it all looks nice in theory, but that NAV 2013 is actually slower than NAV 2009. Per Mogensen of Mergetool.com has done some testing and published a video demonstrating the results. I’ve reviewed the video, and I’ve noticed a couple of possible issues with how the performance was measured, so I decided to do check for myself. My results show something completely different: not only NAV 2013 is faster than NAV 2009, it’s also faster than the Classic client on the native database – kind of a holy grail of NAV performance. And then I double-checked with Per, and he confirmed to me that he also noticed a couple of problems himself. He has repeated the tests, and his tests now also show great improvement in NAV 2013. His updated video is here. But, let&#8217;s continue with my results. The Racing Horses To find out how fast NAV 2013 really is, I’ve [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image5.png"><img style="background-image: none; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb4.png" alt="image" width="202" height="146" align="right" border="0" /></a>Marketing is nice as long as it matches the reality. With Microsoft Dynamics NAV 2013, Microsoft has promised a lot of improvements, but how well does NAV 2013 stand the reality test?</p>
<p>Apparently, outstandingly well.</p>
<p>Over the past two days, I have intensively tested NAV 2009 and NAV 2013 through a series of five different tests that measure different aspects of NAV data handling. My conclusion is clear: <em>NAV 2013 is faster than any NAV you have ever seen, including the Classic client on the native database</em>.</p>
<p>Continue reading to find out more about my findings and testing approach.</p>
<p><span id="more-1223"></span></p>
<p><strong>Is This Some Kind Of A Trick?</strong></p>
<p>No, this is not a trick. It’s for real.</p>
<p>Several days ago I wrote about performance improvements in Microsoft Dynamics NAV 2013, and then got a comment that it all looks nice in theory, but that NAV 2013 is actually slower than NAV 2009. Per Mogensen of <a title="Mergetool.com" href="http://Mergetool.com" target="_blank">Mergetool.com</a> has done some testing and published a <a title="http://www.youtube.com/watch?v=18HoElGEs_0" href="http://www.youtube.com/watch?v=18HoElGEs_0" target="_blank">video demonstrating the results</a>.</p>
<p>I’ve reviewed the video, and I’ve noticed a couple of possible issues with how the performance was measured, so I decided to do check for myself. My results show something completely different: not only NAV 2013 is faster than NAV 2009, it’s also faster than the Classic client on the native database – kind of a holy grail of NAV performance.</p>
<p>And then I double-checked with Per, and he confirmed to me that he also noticed a couple of problems himself. He has repeated the tests, and his tests now also show great improvement in NAV 2013. His updated video is <a title="NAV 2009 R2 versus 2013 Beta posting performance (pure C/AL execution compared)" href="http://www.youtube.com/watch?v=f2xVrZs4w60" target="_blank">here</a>.</p>
<p>But, let&#8217;s continue with my results.</p>
<p><strong>The Racing Horses</strong></p>
<p>To find out how fast NAV 2013 really is, I’ve compared it to other flavors of NAV. The racing horses were:</p>
<ul>
<li>Microsoft Dynamics NAV 2013 RoleTailored Client</li>
<li>Microsoft Dynamics NAV 2013 Web Services</li>
<li>Microsoft Dynamics NAV 2009 RoleTailored Client</li>
<li>Microsoft Dynamics NAV 2009 Web Services</li>
<li>Microsoft Dynamics NAV 2009 Classic Client – SQL Server Option</li>
<li>Microsoft Dynamics NAV 2009 Classic Client – Native Database Option</li>
</ul>
<p>So, quite a jolly bunch. I would love if I could also have tested the performance of 2009 NAS on both native database and SQL Server, but I chose to let it pass.</p>
<p><strong>The Environment</strong></p>
<p>All of the applications have had exactly the same operating conditions, under exactly the same environment and system configuration settings. The following are the system specifications:</p>
<ul>
<li>Intel Core i7-2620M CPU (Quad Core)</li>
<li>8 GB of RAM</li>
<li>OCZ Vertex2 SSD drive</li>
<li>Windows 7 Ultimate, Service Pack 1, 64-bit</li>
<li>Microsoft SQL Server 2008 R2, Standard Edition, 64-bit</li>
</ul>
<p>The machine was physical, not virtual. All flavors of NAV were installed on the same physical instance.</p>
<p><strong>The Tests</strong></p>
<p>All of the six applications had to endure the same testing conditions, and have run the following tests:</p>
<ul>
<li>Creating, releasing, shipping and invoicing a sales order, 100 times in a row (the original Per Mogensen’s test)</li>
<li>Iterating through all customers, vendors, and items, 500 times in a row</li>
<li>Iterating through a filtered list of customers, vendors, and items, with an inefficient filter over a text field, 500 times in a row</li>
<li>Iterating through a unique list of G/L accounts from the G/L Entry table, 500 times in a row.</li>
<li>Manually summing flow fields of all customers, vendors, and items, by calling CALCFIELDS on each row, 500 times in a row.</li>
</ul>
<p>In addition, under NAV 2013 I’ve run the following test as well:</p>
<ul>
<li>Manually summing the balance and inventory flow fields of all customers, vendors, and items, respectively, by calling SETAUTOCALCFIELDS before the iteration, 500 times in a row.</li>
</ul>
<p><strong>The Methodology</strong></p>
<p>Before each of the tests, I prepared the environment by doing the following:</p>
<ul>
<li>I stopped all instances of NAV and closed all clients and made sure no applications were running.</li>
<li>I created a new empty database.</li>
<li>I restored the W1 database into the just created database.</li>
<li>I started the relevant service tier and clients, and then ran all the tests three times to warm the system up.</li>
<li>I cleared the time logs to eliminate the warm-up results, and make sure they don’t distort the test results.</li>
<li>Closed any unnecessary applications (e.g. the Classic Client before using the RTC to run the tests) to ensure that only the environment which is running the test is open.</li>
</ul>
<p>Then, after the environment was ready, for each of the tests I did the following:</p>
<ul>
<li>Ran the test three times in a row.</li>
<li>Copied the results from the log table into Excel.</li>
</ul>
<p>The warm-up is indeed slower under NAV 2013, than under any other system, and my methodology disregarded the warm-up measurements. Warm up times mostly don&#8217;t show anything useful.</p>
<p>Each of the tests records the time right before the test starts, and then again right after it ends. The time difference is then logged into the database.</p>
<p>I measured the time by creating two DateTime instances, setting them to current system time, then subtracting the start time from the end time. This gives the duration in milliseconds. In addition to this, under NAV 2013 I’ve added another measurement method: the .NET System.Diagnostics.Stopwatch class, just in case – if there is anything flawed with NAV’s time variable in 2013, certainly nothing will be wrong with the .NET Stopwatch. As expected, there was no difference between what NAV calculated and what the System.Diagnostics.Stopwatch measured.</p>
<p>In the results, all measurements I present are in milliseconds, and in all test results I’ll show, less is better.</p>
<p><strong>The Results</strong></p>
<p>Finally, we get to the point which I believe you await as much as did I: the results. Let me present them test by test.</p>
<p><em><span style="text-decoration: underline;">1. Sales Orders</span></em></p>
<p>In the Per Mogensen’s tests, the NAV 2009 Classic Client on a native database is the winner of this test. At pure C/AL level, NAV 2013 there performs almost as fast as Classic on native, but the RTC under NAV 2013 is still the slowest. My results are very different. I can’t be 100% sure why, but I’ll give a couple of thoughts at the end of this post.</p>
<p>In any case, these are the measurements I got:</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2013, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">5,169</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">6,186</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, Native</strong></td>
<td valign="top" width="79">
<p align="right">7,467</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">11,778</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, SQL</strong></td>
<td valign="top" width="79">
<p align="right">14,420</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">14,690</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>A picture is worth a thousand words, so here it comes:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image6.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb5.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 1: Sales Orders test results</strong></p>
<p>As I expected, the Web Services perform faster on both 2009 and 2013, because there is no user interface and only the NST is involved in code execution. Under Web Services, NAV 2013 performs about 44% faster than the fastest breed of NAV ever – the Classic Client on a native database. Stripped off the burden of a UI, NAV 2013 Web Services practically demonstrate pure SQL Server performance, and SQL Server is faster than ever before, just as it says on the tin.</p>
<p>But NAV 2013 RTC also showed respectable performance. It performed 21% better than NAV 2009 Classic Client on native database. I kind of didn’t expect this to occur, because the Classic Client on native database is a native ISAM system and NAV business logic is entirely optimized to fly on it. What astonishes me is 128% improvement of NAV 2013 over NAV 2009 in Web Services, or 137% improvement in RoleTailored Client performance. That’s truly amazing.</p>
<p>Obviously, NAV 2013 provides considerable improvement over NAV 2009.</p>
<p><span style="text-decoration: underline;"><em>2. Repeated Read</em></span></p>
<p>This test measures the capability of a client to iterate through a series of records. Iteration is something that C/AL code frequently does, and where any flavor of NAV somewhat sucked under SQL Server, as compared with the sheer performance of the native database. Again, native database and C/AL as a language are optimized precisely for this kind of access, and it was never a wonder that the native was a king here.</p>
<p>However, NAV 2013 seems to have just deposed that king:</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2013, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">16</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">25</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, Native</strong></td>
<td valign="top" width="79">
<p align="right">644</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">8,081</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">8,133</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, SQL</strong></td>
<td valign="top" width="79">
<p align="right">8,637</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Graphically, this is how it looks:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image7.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb6.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 2: Repeated Read of Customers, Vendors and Items</strong></p>
<p>NAV 2013 is lightning fast here, and no wonder why: the caching. While NAV 2009 on SQL Server had to maintain a series of cursors, NAV 2013 ran a single T-SQL query, and then cached the records for subsequent reads. It simply outperforms everything.</p>
<p>I don’t want to spend any time comparing the speed of NAV 2013 with the speed of NAV 2009 native; what I want to do is point out the speed improvement by a factor of more than 400x over NAV 2009 on SQL. How cool is that?</p>
<p><span style="text-decoration: underline;"><em>3. Repeated Read of Filtered Tables</em></span></p>
<p>The beauty of this test is that it shows how well a system copes with a complex filter. I’ve set the filter on Name and Description columns on Customer, Vendor and Item table respectively to this: @*a* (it searches for letter <em>a</em> anywhere in the field, in a case-insensitive way).</p>
<p>This filter can’t make meaningful use of any key, so what shall win or lose this race will be the capability of the database management system to handle such a process on foot.</p>
<p>Again, NAV 2013 played this one coolly.</p>
<p>Here go the results:</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2013, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">20</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">24</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, Native</strong></td>
<td valign="top" width="79">
<p align="right">515</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">5,720</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">5,741</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, SQL</strong></td>
<td valign="top" width="79">
<p align="right">6,178</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>This is the graph:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image8.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb7.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 3: Repeated Read of Filtered Tables</strong></p>
<p>While the variances in NAV 2009 SQL Server flavors are insignificant, the improvement of NAV 2013 is again verging with insane. It’s obvious that the cache kicked in here bit time, but I also assume that there may be some .NET-level code optimization that made this kind of thing possible.</p>
<p><span style="text-decoration: underline;"><em>4. Reading Unique G/L Account Numbers from G/L Entry</em></span></p>
<p>Now, this was a tricky one. It uses several concepts, combination of which is a total no-brainer for the ISAM-based NAV 2009 on native, but verges on rocket science for anything SQL-related. It was literally the most inefficient thing to do to a SQL database in NAV, and running a piece of code such as this literally smothers SQL by causing it to drop existing and create new cursors all the time.</p>
<p>The algorithm is as follows:</p>
<ol>
<li>Set the key on G/L Account column</li>
<li>Find the first G/L Entry row</li>
<li>Set a filter on the G/L Account column to that G/L Account which is currently selected</li>
<li>Find the last G/L Entry with this filter applied</li>
<li>Remove the filter on the G/L Account column</li>
<li>Repeat 3 to 6 until there are more G/L Entry rows</li>
</ol>
<p>In previous versions, steps 2, 4, and 6 drop existing (except for the first iteration) and create new cursors in SQL Server, and I was curious to find out how well SQL coped with this task now that cursors are gone, and MARS is taking their role. There are much less read rows in this test than in the simple repeated read, and if you understand how ISAM works, and how SQL works, you should also expect ISAM to do this with no speed penalty over a simple iterative read, while you can expect SQL to run way slower than a simple iterative read, no matter which approach it takes.</p>
<p>And this is exactly what the results show:</p>
<p>&nbsp;</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, Native</strong></td>
<td valign="top" width="79">
<p align="right">478</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">1,129</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">1,142</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">11,029</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">11,113</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, SQL</strong></td>
<td valign="top" width="79">
<p align="right">11,555</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>And then, the picture:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image9.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb8.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 4: Repeated Read of SIFT-Filtered Tables</strong></p>
<p>Now, before jumping out from your seat and shouting “gotcha!”, think of this test once again. NAV 2013 is almost 10x faster than NAV 2009 here, and whatever it did deep there in its engine is close to a miracle. If it did caching to attain this speed, that caching must be pretty smart, because this piece of code was accessing some very small sets and jumping around the records like crazy.</p>
<p>While I have a very plausible explanation what made NAV 2013 win all previous tests, I don’t have a faintest idea what kind of magic made it perform this well here. Yes, it is slower than native, but this was kind of like making a Formula One compete in a rally.</p>
<p>Catch this: native is fully optimized to do this kind of access, and doing this is no smarter for it than doing the simplest kind of data iteration. As a matter of fact, since there were less rows to read, this one should have been faster than the repeated read test. And it was. At the same time, NAV 2009 on SQL was slower here, because this put much more pressure on it, and it had to struggle. And struggle it did.</p>
<p>Yet, NAV 2013, while still struggling, has shown an incredible performance improvement to make even this kind of thing perform well. Quite a job, Microsoft!</p>
<p><span style="text-decoration: underline;"><em>5. SIFT Read</em></span></p>
<p>I measured how various systems perform with SIFTs, in a scenario quite common in real life: iterating through a set of data and calculating flow fields for each row. NAV does this in many situations, and I was very curious to find out how fast NAV 2013 would be here, because of the many changes Microsoft has done in handling the flow fields in NAV 2013.</p>
<p>Here are the results:</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2013, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">1,517</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">1,518</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, Native</strong></td>
<td valign="top" width="79">
<p align="right">1,638</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Web Services</strong></td>
<td valign="top" width="79">
<p align="right">9,500</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, RoleTailored Client</strong></td>
<td valign="top" width="79">
<p align="right">9,552</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009, Classic Client, SQL</strong></td>
<td valign="top" width="79">
<p align="right">9,745</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Or graphically:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image10.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb9.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 5: SIFT Read</strong></p>
<p>When handling flow fields, NAV 2013 performs slightly better than native ever did, about 8% faster. This is quite a feat, if you have in mind that native handles this functionality again, well, natively, by building the flow field information right into indexes, something that SQL never could.</p>
<p>Okay, I assume that some serious caching took place here as well, but still, caching or not, the whole system performs better and faster in NAV 2013. Compared to SQL Server flavors in NAV 2009, the improvement of 532% is quite amazing, and even more so if you think that probably everybody thought that Microsoft has hit the limit with replacing SIFT tables with indexed views in 5.0 SP1. With that obviously not having been a limit at all, I now wonder shall we experience even more improvement here in the future?</p>
<p><span style="text-decoration: underline;"><em>5a. SETAUTOCALCFIELDS</em></span></p>
<p>Finally, I ran the same test as the previous one, with the SETAUTOCALCFIELDS. I expected serious improvement, but at average of 1,466 milliseconds, this test performed practically only insignificantly faster than the previous one. I expected this one to show the real improvement over the traditional CALCFIELDS approach, but it stubbornly declined. I can’t explain this, but hey, let’s not get too picky <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/wlEmoticon-smile.png" alt="Smile" /></p>
<p><strong>Overall Results</strong></p>
<p>When you add all of the figures above together, the cumulative results demonstrate that Microsoft Dynamics NAV 2013 outperforms its previous incarnations, including the so-far unbeatable Classic Client on a native database.</p>
<p>On average, this is what it took the three clients to execute all tests:</p>
<table width="292" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="211"><strong>2009 SQL</strong></td>
<td valign="top" width="79">
<p align="right">48,636</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2009 Native</strong></td>
<td valign="top" width="79">
<p align="right">10,743</p>
</td>
</tr>
<tr>
<td valign="top" width="211"><strong>2013</strong></td>
<td valign="top" width="79">
<p align="right">8,374</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>And the last picture of the day:</p>
<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image11.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb10.png" alt="image" width="480" height="362" border="0" /></a></p>
<p align="center"><strong>Image 6: Overall Results</strong></p>
<p>Obviously, the improvements that NAV 2013 promises are not just plain words, as these test results show. The overall performance is about 28% better than with the NAV 2009 Classic Client on a native database, and about 480% better (that’s almost 6x performance improvement!) than with NAV 2009 under SQL Server.</p>
<p>However, this is only a part of the story. There is another one: concurrency. Performance is always welcome, but performance is not what has been preventing NAV to scale as much as, for example, AX could. I wonder if Microsoft will release a hardware sizing document that would estimate some kind of the upper limit for vertical scalability of NAV 2013. The last time we got such numbers from Microsoft was with version 5.0 SP1, when it was set at 250 concurrent users.</p>
<p>Of course, any estimates of the kind are comparing apples to oranges, anyway, because at that number of users, the application is probably always heavily customized, and the actual upper vertical scalability limit will invariably depend on a very complex set of parameters, and can be determined only on a case-by-case basis.</p>
<p>I would’ve loved to have done concurrency tests together with the performance tests, but I may do that another time. However, based on the figures I see here, I dare estimating that everything else being equal, concurrency levels can at least be doubled in any given NAV 2013 deployment, over an equal NAV 2009 deployment.</p>
<p><strong>But What About The Other Test?</strong></p>
<p>So, why do Per Mogensen’s test show somewhat different results? On the C/AL level, hist test is very consistent with my measurements with Web services, but in Per&#8217;s tests, NAV 2013 performance with RTC is still inferior to all other clients and platforms.</p>
<p>I can’t tell for sure, but I’ll give my best guess:</p>
<ul>
<li><strong>Virtualization: </strong>The systems were comparable, but the tests were run under different virtual machines, and the virtual hypervisor in charge might have redistributed resources, or other virtual machines were doing some cleanups while NAV 2013 was running, or a whole range of other things might have happened.</li>
<li><strong>Hardware:</strong> The RTC is a .NET application, and depends a lot on hardware on a machine to execute all the things that .NET applications do: just-in-time compilation during warm-up, and talking to video drivers at run time. Since it was a virtual box, maybe the virtual hardware causes troubles with .NET applications talking to it, while it performs better when Win32 applications (as the Classic client) are talking to it.</li>
<li><strong>Warm-up: </strong>While it certainly should be enough to run 100 sales orders through the create-release-ship-invoice cycle to warm a system up, I still think that a thorough warm-up is required for any kind of benchmarking. The warm-up time itself should be disregarded as it is no measure of either real performance under pressure, or the scalability. To determine if the system is properly warmed up, you need to keep running warm-ups until you see no significant performance between the two runs. Only then you can start measuring. The minimum number of runs to determine this condition is three runs.</li>
</ul>
<p><strong>Don’t Take My Word For This</strong></p>
<p>So, who do you trust, Per or me? Neither one! Please, don’t just take my findings for granted. Do the measurements yourself.</p>
<p>Here, I’ve attached the objects that I’ve used to run the benchmark, so you can run the same tests on your own machine, and see your own results. I am really curious about the results you’ll get.</p>
<p>So, download the objects:</p>
<ul>
<li><a title="Microsoft Dynamics NAV 2009 Native - Performance Test" href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/Microsoft-Dynamics-NAV-2009-Performance-Test.zip" target="_blank">Performance Test, NAV 2009 Native</a></li>
<li><a title="Microsoft Dynamics NAV 2009 SQL - Performance Test" href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/Microsoft-Dynamics-NAV-2009-Performance-Test-NST.zip" target="_blank">Performance Test, NAV 2009 SQL</a></li>
<li><a title="Microsoft Dynamics NAV 2013 - Performance Test" href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/Microsoft-Dynamics-NAV-2013-Performance-Test.zip" target="_blank">Performance Test, NAV 2013</a></li>
</ul>
<p>The reason why there are three distinct sets of objects is that NAV 2013 uses .NET Interoperability in addition to system time to measure time, and that native doesn’t use role centers. Everything else is exactly the same.</p>
<p>(Just in case you need it, here is also <a title="Microsoft Dynamics NAV 2013 Benchmarking Results" href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/Microsoft-Dnamics-NAV-Performance-Test.xlsx" target="_blank">my Excel sheet with testing results and charts</a>.)</p>
<p>Run the tests, and then come back here and share your findings. I’d love to hear from you!</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/benchmarking-results-nav-2013-outperforms-all-previous-versions">http://vjeko.com/blog/benchmarking-results-nav-2013-outperforms-all-previous-versions</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=V0QLPE1hLsk:1287wsD7ptk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=V0QLPE1hLsk:1287wsD7ptk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/benchmarking-results-nav-2013-outperforms-all-previous-versions/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Top 5 SQL Server Improvements in NAV 2013</title>
		<link>http://vjeko.com/blog/top-5-sql-server-improvements-in-nav-2013</link>
		<comments>http://vjeko.com/blog/top-5-sql-server-improvements-in-nav-2013#comments</comments>
		<pubDate>Thu, 21 Jun 2012 20:13:05 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Cursors]]></category>
		<category><![CDATA[Improvement]]></category>
		<category><![CDATA[Jörg A. Stryk]]></category>
		<category><![CDATA[MARS]]></category>
		<category><![CDATA[NST]]></category>
		<category><![CDATA[Performace]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[SIFT]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1202</guid>
		<description><![CDATA[Performance is one of those things you can’t get enough of and NAV is one of those systems where an extra operation per second is always welcome. Yesterday, during the Expert Panel at the NAV day of the Decisions Spring conference, there was a question: is there any improvement in how NAV 2013 works on SQL Server. And the answer is: oh yeah! As a matter of fact, everything is new and improved. Jörg has already posted an overview of the news of NAV on SQL Server in his last blog post, but I still think there’s room for a couple of more words on the really amazing palette of news and improvements. As I said, the SQL Server improvements are plenty. Here’s the list of the top 5 technical improvements that rock my boat. 1. Cursors are gone If there was a single thing that was killing performance in NAV, that was server-side cursors. The burden on SQL Server, especially in critical multi-user environments was tremendous, and I’ve seen server monsters crawling under pressure. The cursors are replaced with MARS (Multiple Active Result Sets), which basically take the browsing through recordset chore away from the SQL and assign it to the NST. 2. Caching Apart from MARS, another killer improvement is the caching. Most of data access operations are cached on the NST, which results in a considerable reduction in the number of SQL Server calls. Now, caching alone is a great improvement, but caching + MARS is a winner. Try profiling a simple thing, such as this: IF Cust.FINDSET THEN&#160; REPEAT&#160; UNTIL Cust.NEXT = 0; Run it a couple of times in a row. Under NAV 2013, you get a single SELECT against [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb3.png" width="202" height="136" /></a>Performance is one of those things you can’t get enough of and NAV is one of those systems where an extra operation per second is always welcome. Yesterday, during the Expert Panel at the NAV day of the Decisions Spring conference, there was a question: is there any improvement in how NAV 2013 works on SQL Server.</p>
<p>And the answer is: oh yeah!</p>
<p>As a matter of fact, everything is new and improved.</p>
<p><a title="NAV/SQL Performance - My Two Cents (by Jörg Stryk)" href="http://dynamicsuser.net/blogs/stryk/default.aspx" target="_blank">Jörg</a> has already posted an overview of the news of NAV on SQL Server in his <a title="NAV 2013 Beta – First Impressions" href="http://dynamicsuser.net/blogs/stryk/archive/2012/05/24/nav-2013-beta-first-impressions.aspx" target="_blank">last blog post</a>, but I still think there’s room for a couple of more words on the really amazing palette of news and improvements.</p>
<p><span id="more-1202"></span>
<p>As I said, the SQL Server improvements are plenty. Here’s the list of the top 5 technical improvements that rock my boat.</p>
<p><strong>1. Cursors are gone</strong></p>
<p>If there was a single thing that was killing performance in NAV, that was server-side cursors. The burden on SQL Server, especially in critical multi-user environments was tremendous, and I’ve seen server monsters crawling under pressure. The cursors are replaced with <a title="Multiple Active Result Sets (MARS) in SQL Server 2005" href="http://msdn.microsoft.com/en-us/library/ms345109(v=sql.90).aspx" target="_blank">MARS</a> (Multiple Active Result Sets), which basically take the browsing through recordset chore away from the SQL and assign it to the NST.</p>
<p><strong>2. Caching</strong></p>
<p>Apart from MARS, another killer improvement is the caching. Most of data access operations are cached on the NST, which results in a considerable reduction in the number of SQL Server calls. Now, caching alone is a great improvement, but caching + MARS is a winner.</p>
<p>Try profiling a simple thing, such as this:</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>IF Cust.FINDSET THEN</p><p>&#160; REPEAT</p><p>&#160; UNTIL Cust.NEXT = 0;</p></pre>
<p></div>
<p>Run it a couple of times in a row. Under NAV 2013, you get a single SELECT against the SQL Server, then nothing else. The iteration happens on the NST, and every consecutive call to the same stuff does everything on the NST. Try that under NAV 2009, and the profiler goes bananas.</p>
<p><strong>3. SIFTs</strong></p>
<p>There are several improvements in how NAV 2013 handles SIFTs. First – you don’t have to explicitly declare SIFT fields on keys. You can do CALCFIELDS and CALCSUMS on any decimal field, regardless of the structure of keys on the source table. And SQL simply calculates the value. This relieves SQL from maintaining too many indexed views. Yes, I know, it also slows the read operations slightly, but did I mention the caching? Oh, sorry, I have. There.</p>
<p>Another improvement is that you can include the SIFT fields into the SQL statement, and get the SIFTs with the same single SELECT statement that NST issues against SQL. You do this with the SETAUTOCALCFIELDS statement which you call on a record variable just before you FIND or FINDSET the records.</p>
<p>Compare these two in the profiler, and it’s clear right away:</p>
<p>a) with CALCFIELDS</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>IF Cust.FINDSET THEN</p><p>  REPEAT</p><p>    <span style="color: #008000">// Balance is not calculated, we have to do it manually</span></p><p><span style="color: #008000"></span>    Cust.CALCFIELDS(Balance);</p><p>  UNTIL Cust.NEXT = 0;</p></pre>
<p></div>
<p>b) with SETAUTOCALCFIELDS</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Cust.SETAUTOCALCFIELDS(Balance);</p><p>IF Cust.FINDSET THEN</p><p>&#160; REPEAT</p><p>&#160;&#160;&#160; <span style="color: #008000">// No need for CALCFIELDS, Balance is returned already</span></p><p><span style="color: #008000"></span>&#160; UNTIL Cust.NEXT = 0;</p></pre>
<p></div>
<p>With the option a, whenever you hit the CALCFIELDS, the NST obeys and fetches the sum. With the option b, there is a single SELECT statement, which already includes the OUTER APPLY clause, which calculates the SUM for each row retrieved.</p>
<p>Pretty cool stuff.</p>
<p><strong>4. ADO.NET</strong></p>
<p>The whole shebang is now run on ADO.NET, instead of OLEDB/ODBC that it was before. There are plenty of benefits of that, performance included.</p>
<p>ADO.NET streamlines deployment and administration, increases performance, reduces the number of SQL connections (Jörg has explained some drawbacks of this access, but I think generally that this is a good thing), reduces the memory consumption, and maybe a couple other things.</p>
<p><strong>5. Unicode</strong></p>
<p>I’ve already blogged about this, Jörg has also mentioned this, so I won’t play the same tune yet another time. NAV is now <a title="Unicode (Wikipedia)" href="http://en.wikipedia.org/wiki/Unicode" target="_blank">Unicode</a>, which allows you to store characters in any language, at the same time.</p>
<p>Unfortunately, Unicode is not as Unicode as I’d truly love it to be, because the object captions remain tied to the chosen database collation (yes, you still need to choose this). That practically means that while you’ll be able to store characters from any alphabet, your RTC user interface will remain limited to a single character set.</p>
<p><strong>Wrap up</strong></p>
<p>So, to wrap it up, there is a lot of new things, bigger or smaller, that have been changed and that warrant better performance, or user experience, or both.</p>
<p>You may notice that I didn’t mention queries. Yes, they are a mind-boggling improvement over previous versions, but they are simply a completely new feature, not something that NAV had, and now has better than before. My list here is the list of tweaks and tune-ups that take those things that we are used to have to a new level altogether. Queries? Well, they are out of this world, but their true power is yet to come – when (I’m kind of sure it’s about “when”, not “if”) we’ll be able to use them as sources for pages or reports.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/top-5-sql-server-improvements-in-nav-2013">http://vjeko.com/blog/top-5-sql-server-improvements-in-nav-2013</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=mQZXM7IlivE:yZ0ICelLA4A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=mQZXM7IlivE:yZ0ICelLA4A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/top-5-sql-server-improvements-in-nav-2013/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>NAV Expert Panel Session Begins</title>
		<link>http://vjeko.com/blog/nav-expert-panel-session-begins</link>
		<comments>http://vjeko.com/blog/nav-expert-panel-session-begins#comments</comments>
		<pubDate>Wed, 20 Jun 2012 11:53:19 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Decisions]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[MSDynamicsWorld.com]]></category>
		<category><![CDATA[NAV]]></category>
		<category><![CDATA[NAV 2013]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1198</guid>
		<description><![CDATA[I’m right now sitting in the virtual lobby of the NAV Expert Panel Session of the NAV day of the Decisions Spring 2012 conference. The panel features three MVPs, three book authors, and established members of the NAV community: Eric Wauters, Matt Traxinger, Steven Renders, Brent Fisher and myself. With Microsoft Dynamics NAV 2013 beta out and a lot of partners having laid their hands on it, I assume the discussion will develop around NAV 2013 topics. I don’t know how much time I’ll have during the session, because I’ll probably be busy answering questions, but I’ll be tweeting live from the session, so if you don’t have an opportunity to join the conference, you can still stay in the loop by following me at @vjekob, or follow the conference hashtag #msdwdecisions. Read this post at its original location at http://vjeko.com/blog/nav-expert-panel-session-begins, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image3.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb2.png" width="202" height="145" /></a>I’m right now sitting in the virtual lobby of the NAV Expert Panel Session of the NAV day of the Decisions Spring 2012 conference. The panel features three MVPs, three book authors, and established members of the NAV community: Eric Wauters, Matt Traxinger, Steven Renders, Brent Fisher and myself.</p>
<p>With Microsoft Dynamics NAV 2013 beta out and a lot of partners having laid their hands on it, I assume the discussion will develop around NAV 2013 topics.</p>
<p>I don’t know how much time I’ll have during the session, because I’ll probably be busy answering questions, but I’ll be tweeting live from the session, so if you don’t have an opportunity to join the conference, you can still stay in the loop by following me at @vjekob, or follow the conference hashtag #msdwdecisions.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/nav-expert-panel-session-begins">http://vjeko.com/blog/nav-expert-panel-session-begins</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=gjdYWCsBMPw:oKB9_rv8Mwk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=gjdYWCsBMPw:oKB9_rv8Mwk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/nav-expert-panel-session-begins/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Decisions Spring 2013 Kicking-off Next Week</title>
		<link>http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week</link>
		<comments>http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week#comments</comments>
		<pubDate>Thu, 14 Jun 2012 07:45:21 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[Decisions]]></category>
		<category><![CDATA[Microsoft Dynamics]]></category>
		<category><![CDATA[MSDynamicsWorld.com]]></category>
		<category><![CDATA[NAV]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1194</guid>
		<description><![CDATA[Make sure not to miss Decisions, the virtual conference about Microsoft Dynamics, by MSDynamicsWorld.com. It’s starting next Monday, and I hope you already have it in your calendar. It’s a four day conference, a day per Dynamics flavor (SL is the only one not being served). The best of all – it’s free! Be there. The Microsoft Dynamics NAV day is on Wednesday, June 20, and it’s featuring a program manager from Microsoft, three MVPs, (at least) three book authors, and a team of seasoned professionals in a series of interesting presentations. Just like the previous years, I’ll be speaking there myself, and if you would like to join me for an excursion into the world beyond ERP, where several disruptive trends are shaping the future of the IT, and consequently the ERP. I’ll take an angle at the challenges the present and the future bring, and how Microsoft Dynamics NAV faces them, copes with them, and plays along. I promise it’ll be time well spent. The conference is virtual, so you can attend it in your slippers, I won’t mind. See you in the cloud! Read this post at its original location at http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a title="Decisions Spring 2012" href="http://decisions.msdynamicsworld.com/" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image2.png" width="202" height="88" /></a>Make sure not to miss <a title="Decisions Spring 2012" href="http://decisions.msdynamicsworld.com/" target="_blank">Decisions</a>, the virtual conference about Microsoft Dynamics, by <a title="MSDynamicsWorld.com" href="http://MSDynamicsWorld.com/" target="_blank">MSDynamicsWorld.com</a>. It’s starting next Monday, and I hope you already have it in your calendar. It’s a four day conference, a day per Dynamics flavor (SL is the only one not being served). The best of all – it’s free! Be there.</p>
<p>The <a title="The Microsoft Dynamics NAV day" href="http://decisions.msdynamicsworld.com/product/microsoft-dynamics-nav-day" target="_blank">Microsoft Dynamics NAV day</a> is on Wednesday, June 20, and it’s featuring a program manager from Microsoft, three MVPs, (at least) three book authors, and a team of seasoned professionals in a series of interesting presentations.</p>
<p>Just like the previous years, I’ll be speaking there myself, and if you would like to join me for an excursion into the <a title="Microsoft Dynamics NAV: A World Beyond ERP" href="http://decisions.msdynamicsworld.com/session/microsoft-dynamics-nav-world-beyond-erp" target="_blank">world beyond ERP</a>, where several disruptive trends are shaping the future of the IT, and consequently the ERP. I’ll take an angle at the challenges the present and the future bring, and how Microsoft Dynamics NAV faces them, copes with them, and plays along. I promise it’ll be time well spent.</p>
<p>The conference is virtual, so you can attend it in your slippers, I won’t mind. See you in the cloud!</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week">http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=nSaE6EFxVy8:0xb9iSoQLrM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=nSaE6EFxVy8:0xb9iSoQLrM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/decisions-spring-2013-kicking-off-next-week/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Unlimited Text Length in NAV 2013</title>
		<link>http://vjeko.com/blog/unlimited-text-length-in-nav-2013</link>
		<comments>http://vjeko.com/blog/unlimited-text-length-in-nav-2013#comments</comments>
		<pubDate>Wed, 13 Jun 2012 20:25:36 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Text]]></category>
		<category><![CDATA[Unlimited]]></category>
		<category><![CDATA[What's New]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1191</guid>
		<description><![CDATA[Have you noticed already that in Microsoft Dynamics NAV 2013 the text variables can have unlimited length? That’s quite a leap ahead of the previous versions which couldn’t handle more than 1024 characters per variable. If you wanted to achieve bug-free code then, when you were assigning texts around, you had to concatenate the result down to the MAXSTRLEN of the target text. Not anymore. The trick is to simply not declare the Length property on text variables. If you declare a variable of type Text, and then leave the Length empty, it means – unlimited. Don’t worry – you won’t kill NAV by eating up all the available memory. Underneath C/AL there is .NET now, and strings in .NET are of unlimited length, or better yet – unlimittable – length anyway. Strings will only make things slow if you stuff the revised version of King James’s Bible in them. In all practical situations, there will be absolutely no performance penalty of leaving Texts unlimited. I don’t know about you, but from tomorrow morning, I won’t be setting Length to my Texts. Read this post at its original location at http://vjeko.com/blog/unlimited-text-length-in-nav-2013, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb1.png" width="202" height="134" /></a>Have you noticed already that in Microsoft Dynamics NAV 2013 the text variables can have unlimited length? That’s quite a leap ahead of the previous versions which couldn’t handle more than 1024 characters per variable. If you wanted to achieve bug-free code then, when you were assigning texts around, you had to concatenate the result down to the MAXSTRLEN of the target text.</p>
<p>Not anymore.</p>
<p>The trick is to simply not declare the Length property on text variables. If you declare a variable of type Text, and then leave the Length empty, it means – unlimited.</p>
<p>Don’t worry – you won’t kill NAV by eating up all the available memory. Underneath C/AL there is .NET now, and strings in .NET are of unlimited length, or better yet – unlimittable – length anyway. Strings will only make things slow if you stuff the revised version of King James’s Bible in them. In all practical situations, there will be absolutely no performance penalty of leaving Texts unlimited.</p>
<p>I don’t know about you, but from tomorrow morning, I won’t be setting Length to my Texts.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/unlimited-text-length-in-nav-2013">http://vjeko.com/blog/unlimited-text-length-in-nav-2013</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=S-8dFLrJg78:U6Y9EQrzODU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=S-8dFLrJg78:U6Y9EQrzODU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/unlimited-text-length-in-nav-2013/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Length of G/L Account Name in NAV 2013</title>
		<link>http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013</link>
		<comments>http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013#comments</comments>
		<pubDate>Sun, 10 Jun 2012 08:41:46 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Microsoft Dynamics]]></category>
		<category><![CDATA[Description]]></category>
		<category><![CDATA[G/L Account]]></category>
		<category><![CDATA[Master data]]></category>
		<category><![CDATA[Name]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[What's New]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1185</guid>
		<description><![CDATA[A small but important change often slips under the radar of the What’s New kinds of documents. One of those is the standard length of the Name field in G/L Account table. I’ve just noticed that in Microsoft Dynamics NAV 2013 the length of this field has been increased from 30 characters to 50 characters. While this seams a minor thing, it’s actually a huge improvement. If 30 characters was not enough in previous versions, increasing it was not a simple thing to do, and required you to change thirty or so other objects as well. It was in fact one of those annoying things that you better got used to, rather than changed. Yes, I’ve seen customers who insisted on changing it, but most of them simply gave in. In NAV 2013, this change is not only about G/L Account – the length of all Name and Description fields in all master tables has been consistently set to 50. In the previous versions of NAV the length varied between 30 and 50, but now all of the master table Name and Description fields are of length 50. A small step for man, a giant leap for mankind. Read this post at its original location at http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/06/image_thumb.png" width="202" height="136" /></a>A small but important change often slips under the radar of the What’s New kinds of documents. One of those is the standard length of the Name field in G/L Account table. I’ve just noticed that in Microsoft Dynamics NAV 2013 the length of this field has been increased from 30 characters to 50 characters.</p>
<p>While this seams a minor thing, it’s actually a huge improvement. If 30 characters was not enough in previous versions, increasing it was not a simple thing to do, and required you to change thirty or so other objects as well. It was in fact one of those annoying things that you better got used to, rather than changed. Yes, I’ve seen customers who insisted on changing it, but most of them simply gave in.</p>
<p>In NAV 2013, this change is not only about G/L Account – the length of all Name and Description fields in all master tables has been consistently set to 50. In the previous versions of NAV the length varied between 30 and 50, but now all of the master table Name and Description fields are of length 50.</p>
<p>A small step for man, a giant leap for mankind.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013">http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=pCniZN2EmWw:8uRgYB-QV-0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=pCniZN2EmWw:8uRgYB-QV-0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/length-of-gl-account-name-in-nav-2013/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>NAV 2013 beta mini-launch at Adriatics Community</title>
		<link>http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community</link>
		<comments>http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community#comments</comments>
		<pubDate>Tue, 22 May 2012 08:52:04 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Adriatics]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[Ivan Koletić]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1180</guid>
		<description><![CDATA[If you want to learn more about the upcoming release of Microsoft Dynamics NAV 2013, and you are from Zagreb, or don’t mind coming to it, the next community event of Microsoft Dynamics Community Adriatics will be fully dedicated to NAV 2013. There are going to be two presentations. In the first one on the topic of “What’s new in application functionality”, hosted by Ivan Koletić, a member of Microsoft Dynamics NAV product team, who will give an overview of new application features in NAV 2013, and by now you should already know there are plenty. The second presentation will be about “What’s new in technology”, and will be hosted by me. I won’t be doing any deep-dive this time, and I’ll provide a cloud-perspective overview of a myriad of architecture changes and technology improvements in NAV 2013. Both of these presentations are merely going to be an introduction in the series of the presentations that will follow over the next several community events. It’s going to be an exciting summer and fall. If you would like to attend, then please register your attendance (for free, of course) at the event homepage. We are looking forward to seeing you there! Read this post at its original location at http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34]]></description>
				<content:encoded><![CDATA[<p><a title="Microsoft Community Croatia" href="http://www.mscommunity.hr/"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="Microsoft Comomunity Croatia" border="0" alt="Microsoft Comomunity Croatia" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/05/image3.png" width="202" height="143" /></a>If you want to learn more about the upcoming release of Microsoft Dynamics NAV 2013, and you are from Zagreb, or don’t mind coming to it, the next community event of Microsoft Dynamics Community Adriatics will be fully dedicated to NAV 2013.</p>
<p>There are going to be two presentations. In the first one on the topic of “What’s new in application functionality”, hosted by Ivan Koletić, a member of Microsoft Dynamics NAV product team, who will give an overview of new application features in NAV 2013, and by now you should already know there are plenty.</p>
<p>The second presentation will be about “What’s new in technology”, and will be hosted by me. I won’t be doing any deep-dive this time, and I’ll provide a cloud-perspective overview of a myriad of architecture changes and technology improvements in NAV 2013.</p>
<p>Both of these presentations are merely going to be an introduction in the series of the presentations that will follow over the next several community events. It’s going to be an exciting summer and fall.</p>
<p>If you would like to attend, then please register your attendance (for free, of course) at the <a title="11. sastanak Microsoft Dynamics Community Adriatics" href="http://www.mscommunity.hr/Event/Detail/359" target="_blank">event homepage</a>. We are looking forward to seeing you there!</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community">http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=_Y6hUVZq6e4:tEe1OXiXXt8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=_Y6hUVZq6e4:tEe1OXiXXt8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/nav-2013-beta-mini-launch-at-adriatics-community/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generics in .NET Interop for NAV 2013</title>
		<link>http://vjeko.com/blog/generics-in-net-interop-for-nav-2013</link>
		<comments>http://vjeko.com/blog/generics-in-net-interop-for-nav-2013#comments</comments>
		<pubDate>Thu, 17 May 2012 22:55:54 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C/AL]]></category>
		<category><![CDATA[Dictionary]]></category>
		<category><![CDATA[DotNet]]></category>
		<category><![CDATA[Generics]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1175</guid>
		<description><![CDATA[.NET Framework is full of programming conceptual gems, that are now at the fingertips of us poor C/AL folks. One of those is generics. However, the C/AL support for generics at the first glance seems rather limited, and the help file says that you can’t specify data types, and that all generics will be instantiated with System.Object as their type. However, with Microsoft Dynamics NAV 2013, there is a very simple way which allows you to use generics with other data types, as well. So, if .NET Framework Interoperability interests you a slightest bit, here’s a solution. The example below will be for the System.Collections.Generic.Dictionary&#60;,&#62;, and I will show how to use instances of the Dictionary&#60;,&#62; object with any desired data type, without having to pull in any external assemblies. The Solution Before I show the example, I’ll first explain the solution. Declaratively, you can’t declare a generic variable, and specify the type. C/SIDE is just not (yet) that flexible. But that doesn’t matter, because .NET Framework includes a nice feature which allows you to create instances of any type on the fly: Reflection. By using reflection, you can create an instance of a generic type, and specify which type(s) it should use, all with very little coding. In the examples that follow, I’ll create an instance of Dictionary&#60;string,int&#62;. The whole process in C# would look, more or less, like this: Dictionary&#60;string, int&#62; dict = Activator.CreateInstance( typeof(Dictionary&#60;,&#62;).MakeGenericType( new Type[] { typeof (string), typeof (int) })) as Dictionary&#60;string, int&#62;; &#160; Okay, it’s kind of hax0rish, because all is inline, so if you prefer it step by step, here it goes: // Step 1Type[] types = new Type[] { typeof (string), typeof (int) };&#160;// Step 2Type dictionaryType [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/05/image2.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 8px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/05/image_thumb.png" width="202" height="143" /></a>.NET Framework is full of programming conceptual gems, that are now at the fingertips of us poor C/AL folks. One of those is <a title="An Introduction to C# Generics" href="http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx" target="_blank">generics</a>. However, the C/AL support for generics at the first glance seems rather limited, and the help file says that you can’t specify data types, and that all generics will be instantiated with System.Object as their type.</p>
<p>However, with Microsoft Dynamics NAV 2013, there is a very simple way which allows you to use generics with other data types, as well. So, if .NET Framework Interoperability interests you a slightest bit, here’s a solution.</p>
<p>The example below will be for the System.Collections.Generic.Dictionary&lt;,&gt;, and I will show how to use instances of the Dictionary&lt;,&gt; object with any desired data type, without having to pull in any external assemblies.</p>
<p><span id="more-1175"></span>
<p><strong>The Solution</strong></p>
<p>Before I show the example, I’ll first explain the solution.</p>
<p>Declaratively, you can’t declare a generic variable, and specify the type. C/SIDE is just not (yet) that flexible. But that doesn’t matter, because .NET Framework includes a nice feature which allows you to create instances of any type on the fly: <a title="Reflection in the .NET Framework" href="http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.100).aspx" target="_blank">Reflection</a>.</p>
<p>By using reflection, you can create an instance of a generic type, and specify which type(s) it should use, all with very little coding. In the examples that follow, I’ll create an instance of Dictionary&lt;string,int&gt;.</p>
<p>The whole process in C# would look, more or less, like this:</p>
<div>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">int</span>&gt; dict =</p><p>    Activator.CreateInstance(</p><p>        <span style="color: #0000ff">typeof</span>(Dictionary&lt;,&gt;).MakeGenericType(</p><p>            <span style="color: #0000ff">new</span> Type[]</p><p>                {</p><p>                    <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">string</span>), </p><p>                    <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">int</span>)</p><p>                })) <span style="color: #0000ff">as</span> Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">int</span>&gt;;</p></pre>
</div>
<div>&#160;</div>
<div>Okay, it’s kind of hax0rish, because all is inline, so if you prefer it step by step, here it goes:</div>
<div>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #008000">// Step 1</span></p><p><span style="color: #008000"></span>Type[] types =</p><p>    <span style="color: #0000ff">new</span> Type[]</p><p>        {</p><p>            <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">string</span>),</p><p>            <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">int</span>)</p><p>        };</p><p><span style="color: #008000"></span>&#160;</p><p><span style="color: #008000">// Step 2</span></p><p><span style="color: #008000"></span>Type dictionaryType = <span style="color: #0000ff">typeof</span> (Dictionary&lt;,&gt;).MakeGenericType(types);</p><p>&#160;</p><p><span style="color: #008000">// Step 3</span></p><p><span style="color: #008000"></span>Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">int</span>&gt; dict = </p><p>    Activator.CreateInstance(dictionaryType) <span style="color: #0000ff">as</span></p><p><span style="color: #0000ff">        </span>Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">int</span>&gt;;</p></pre>
</div>
<div>&#160;</div>
<p>Step 1 creates an instance of a 2-element array of Type. This is needed for creating a generic type using reflection.</p>
<p>Step 2 uses reflection to create a generic type of specified types. The types are specified in the array we created in the step 1.</p>
<p>Step 3 uses reflection to create an instance of the type created in step 2.</p>
<p>Now that we’ve seen it in C#, let’s map the same to C/AL.<br />
  </p>
<div>&#160;</div>
<p><strong>1. Declaration</strong></p>
<p>Let’s get it straight, you can’t declare a DotNet variable of a generic type, and specify the actual type (or types) it generalizes. The C/SIDE simply doesn’t allow that. But, don’t worry. Go ahead, and declare the following variables:</p>
<table border="1" cellspacing="0" cellpadding="2" width="492">
<tbody>
<tr>
<td valign="top" width="64">Name</td>
<td valign="top" width="426">Subtype</td>
</tr>
<tr>
<td valign="top" width="64">Dict</td>
<td valign="top" width="426">System.Collections.Generic.Dictionary`2.&#8217;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242;</td>
</tr>
<tr>
<td valign="top" width="64">Type</td>
<td valign="top" width="426">System.Type.&#8217;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242;</td>
</tr>
<tr>
<td valign="top" width="64">Activator</td>
<td valign="top" width="426">System.Activator.&#8217;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242;</td>
</tr>
<tr>
<td valign="top" width="64">Arr</td>
<td valign="top" width="426">System.Array.&#8217;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242;</td>
</tr>
<tr>
<td valign="top" width="64">String</td>
<td valign="top" width="426">System.String.&#8217;mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&#8242;</td>
</tr>
<tr>
<td valign="top" width="64">Int</td>
<td valign="top" width="426">&nbsp;</td>
</tr>
</tbody>
</table>
<p>Of course, all of the above are DotNet, except for the last one, which is Integer.</p>
<p>&#160;</p>
<p><strong>2. Creating an instance of an array</strong></p>
<p>To declare an instance of an array of type Type, we can call the CreateInstance method of the Array class, by providing the type of System.Type. Then we populate the array with the types of System.String, and System.Int32:</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Arr := Arr.CreateInstance(GETDOTNETTYPE(Type),2);</p><p>Arr.SetValue(GETDOTNETTYPE(String),0);</p><p>Arr.SetValue(GETDOTNETTYPE(Int),1);</p></pre>
<p></div>
<p>This isn’t nearly as elegant as in C#, but accomplishes the goal quite as nicely. Take a note of the <em>GETDOTNETTYPE</em> function – a new gem in C/AL, the equivalent of the <em>typeof</em> keyword in C#.</p>
<p>&#160;</p>
<p><strong>3. Creating the dictionary type</strong></p>
<p>To create the type for the Dictionary&lt;string,int&gt; that we need, we have two steps. First is to get the type of Dictionary, and the second is to use that type to reflect out the actual Dictionary type that we need, based on types specified in the array:</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Type := GETDOTNETTYPE(Dict);</p><p>Type := Type.MakeGenericType(Arr);</p></pre>
<p></div>
<p>Again, it can’t be a single line in C/AL, because the syntax of C/AL does not treat the result of the GETDOTNETTYPE as an object.</p>
<p>&#160;</p>
<p><strong>4. Creating an actual instance</strong></p>
<p>Finally, we create an actual instance of the Dictionary&lt;string,int&gt; object, exactly as we would in C# (except we do it in C/AL):</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">Dict := Activator.CreateInstance(Type);</pre>
<p></div>
<p>There. And now we are ready to use it.</p>
<p>&#160;</p>
<p><strong>5. Testing if it really is what we need</strong></p>
<p>Testing generics is easy – if you pass on to it the arguments of invalid type, they’d complain loudly. So, let’s try to pass some valid ones, and an invalid one:</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Dict.Add(<span style="color: #006080">'first'</span>,1);</p><p>Dict.Add(<span style="color: #006080">'second'</span>,2);</p><p>Dict.Add(<span style="color: #006080">'third'</span>,<span style="color: #006080">'three'</span>);</p></pre>
<p></div>
<p>Here, at the 3rd line, it fails with the following message, exactly as expected: <em>This message is for C/AL programmers: A call to System.Collections.Generic.Dictionary`2[System.String,System.Int32].Add failed with this message: The type of one or more arguments does not match the method&#8217;s parameter type.</em></p>
<p>So, obviously, we have an actual instance of the Dictionary&lt;string,int&gt; which receives exactly those elements, and behaves exactly as we would expect from a true .NET Framework generic class: if we try to pass a value of incorrect type, it’s not going to be happy.</p>
<p>&#160;</p>
<p><strong>6. And now for something completely different</strong></p>
<p>If you know anything about generics, at this moment you should be puzzled, as I was when I first tried this out. All of the C/AL voodoo above is the equivalent of this code in C#:</p>
<div id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Dictionary&lt;<span style="color: #0000ff">object</span>, <span style="color: #0000ff">object</span>&gt; dict =</p><p>    Activator.CreateInstance(</p><p>        <span style="color: #0000ff">typeof</span> (Dictionary&lt;,&gt;).MakeGenericType(</p><p>            <span style="color: #0000ff">new</span> Type[]</p><p>                {</p><p>                    <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">string</span>),</p><p>                    <span style="color: #0000ff">typeof</span> (<span style="color: #0000ff">int</span>)</p><p>                })) <span style="color: #0000ff">as</span> Dictionary&lt;<span style="color: #0000ff">object</span>, <span style="color: #0000ff">object</span>&gt;;</p></pre>
<p></div>
<p>No need to try running it, it fails. Actually, it doesn’t fail, it returns null. The problem is, being strongly typed, the .NET runtime can’t cast Dictionary&lt;string,int&gt; as Dictionary&lt;object,object&gt;, and the declared type of Dictionary&lt;object,object&gt; can’t hold a value of Dictionary&lt;string,int&gt;. It’s apples and oranges—even though both are instances of the same generic type, it’s not the same actual type, and they are not typecast compatible.</p>
<p>When you declare a DotNet of a generic type, in this case the Dictionary type, it’s declaratively Dictionary&lt;object,object&gt;, so how in the earth did we manage to stuff Dictionary&lt;string,int&gt; into it?</p>
<p>As a matter of fact, we never did that. I can’t say for sure, but I’ll give an educated guess here. DotNet is never actually the exact type we declare, but a wrapper class around just about anything. I assume it actually wraps around System.Object, and then uses reflection to access the members of the actual object it wraps.</p>
<p>But in the end, why do we care? It does what we need it to do.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/generics-in-net-interop-for-nav-2013">http://vjeko.com/blog/generics-in-net-interop-for-nav-2013</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=r5ET_P63yS0:BA1s1PP7ODk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=r5ET_P63yS0:BA1s1PP7ODk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/generics-in-net-interop-for-nav-2013/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hello, unicode!</title>
		<link>http://vjeko.com/blog/hello-unicode</link>
		<comments>http://vjeko.com/blog/hello-unicode#comments</comments>
		<pubDate>Thu, 17 May 2012 08:11:52 +0000</pubDate>
		<dc:creator>Vjeko</dc:creator>
				<category><![CDATA[NAV 2013]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://navigateintosuccess.com/?p=1171</guid>
		<description><![CDATA[你好，世界！გამარჯობა, მსოფლიო! હેલો, વિશ્વ! مرحبا، العالم! שלום, עולם! नमस्ते, दुनिया! こんにちは世界 ಹಲೋ, ವಿಶ್ವದ! 안녕하세요, 세계! Γεια σου, κόσμε! Привет, мир! வணக்கம், உலக! హలో, ప్రపంచం! สวัสดีโลก! No, no, I didn’t go fully crazy yet, but I’m surely closing in. Maybe it’s not at all such a big deal as I see it, but the new Unicode support in Microsoft Dynamics NAV 2013 is just blowing my socks off. After a quarter century of being tied to a single code page of choice, NAV has finally been freed of it’s single byte per character legacy. So, the scribble above is not just me showing off with my ability to use Google translate, it’s a playground for you to copy select pieces of it and paste it all over NAV text fields in your NAV 2013 installation. You have one, don’t you? If not, go grab your copy! This Unicode thingy, it was obvious this was coming. It was not exactly officially confirmed earlier, but with the good riddance of the Classic stack, and having the whole new stack built entirely upon .NET Framework and SQL Server (which had Unicode since ages), retaining ASCII would actually required far more work than simply adding the so much desired n in front of all those varchars in the database. In memory, everything was Unicode already anyway and if you have been in Antwerp at NAV TechDays last year, you may remember this presentation with the demo. With NAV 2013 beta out, the sheer number of news is frightening, and I hope I just get enough time to blog as much as I’d love to. But I’m sure my colleagues would kick-off as well, and there will be oceans of useful [...]]]></description>
				<content:encoded><![CDATA[<p><a title="Flags, by borkur.net" href="http://www.flickr.com/photos/borkurdotnet/691053039/" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://vjekocom.fortempodoo.netdna-cdn.com/wp-content/uploads/2012/05/image1.png" width="202" height="130" /></a>你好，世界！გამარჯობა, მსოფლიო! હેલો, વિશ્વ! مرحبا، العالم! שלום, עולם! नमस्ते, दुनिया! こんにちは世界 ಹಲೋ, ವಿಶ್ವದ! 안녕하세요, 세계! Γεια σου, κόσμε! Привет, мир! வணக்கம், உலக! హలో, ప్రపంచం! สวัสดีโลก!</p>
<p>No, no, I didn’t go fully crazy yet, but I’m surely closing in. Maybe it’s not at all such a big deal as I see it, but the new <a title="Unicode (Wikipedia)" href="http://en.wikipedia.org/wiki/Unicode" target="_blank">Unicode</a> support in Microsoft Dynamics NAV 2013 is just blowing my socks off. After a quarter century of being tied to a single code page of choice, NAV has finally been freed of it’s single byte per character legacy.</p>
<p><span id="more-1171"></span>
<p>So, the scribble above is not just me showing off with my ability to use Google translate, it’s a playground for you to copy select pieces of it and paste it all over NAV text fields in your NAV 2013 installation. You have one, don’t you? If not, <a title="Microsoft Dynamics NAV 2013 Beta" href="https://mbs.microsoft.com/partnersource/support/selfsupport/productreleases/msdnav2013betadownload.htm" target="_blank">go grab your copy</a>!</p>
<p>This Unicode thingy, it was obvious this was coming. It was not exactly officially confirmed earlier, but with the good riddance of the Classic stack, and having the whole new stack built entirely upon .NET Framework and SQL Server (which had Unicode since ages), retaining ASCII would actually required far more work than simply adding the so much desired <em>n</em> in front of all those varchars in the database. In memory, <a title="The Beauty and The Beast: NAV and .NET" href="http://navigateintosuccess.com/blog/the-beauty-and-the-beast-nav-and-net" target="_blank">everything was Unicode already anyway</a> and if you have been in Antwerp at NAV TechDays last year, you may remember this <a title=".NET and NAV Interop: The Beauty meets The Beast" href="http://www.mibuso.com/dlinfo.asp?FileID=1388" target="_blank">presentation with the demo</a>.</p>
<p>With NAV 2013 beta out, the sheer number of news is frightening, and I hope I just get enough time to blog as much as I’d love to. But I’m sure my colleagues would kick-off as well, and there will be oceans of useful information about NAV 2013 pouring in. That I can promise.</p>
<hr />
Read this post at its original location at <a href="http://vjeko.com/blog/hello-unicode">http://vjeko.com/blog/hello-unicode</a>, or visit the original blog at <a href="http://vjeko.com/" title="Vjeko.com">http://vjeko.com</a>. 5e33c5f6cb90c441bd1f23d5b9eeca34<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Swo1iXjKYVM:9FMECHudy4w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?a=Swo1iXjKYVM:9FMECHudy4w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/NavigateIntoSuccess?d=qj6IDK7rITs" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://vjeko.com/blog/hello-unicode/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk: enhanced
Database Caching 2/24 queries in 0.922 seconds using disk
Object Caching 2586/2643 objects using disk
Content Delivery Network via vjekocom.fortempodoo.netdna-cdn.com

 Served from: vjeko.com @ 2013-05-23 22:05:27 by W3 Total Cache -->
