<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3406339728210894553</id><updated>2012-01-06T22:24:22.478+01:00</updated><category term='X++'/><category term='EnterprisePortal'/><category term='Reflection'/><category term='CLR'/><category term='Add-In'/><category term='Temporary Tables'/><category term='Client/Server'/><category term='Properties'/><category term='Framework'/><category term='Migration'/><category term='Business Connector'/><category term='DLL'/><category term='Tools'/><category term='Debugging'/><category term='Database interaction'/><category term='Security'/><category term='Fun'/><category term='Reporting Services'/><category term='x64'/><category term='Labels'/><title type='text'>AX@Luegisdorf</title><subtitle type='html'>Articles about development around Dynamics AX. Just retrieved by experience ...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7304056241767406393</id><published>2012-01-06T22:24:00.000+01:00</published><updated>2012-01-06T22:24:22.484+01:00</updated><title type='text'>New major release for SmartStart3000</title><content type='html'>Finally, and with huge delay (schedule for publish was October, but then, yeah - time flies, you know), the new version of SmartStart 3000 V.1.7 is now released.&lt;br /&gt;&lt;br /&gt;Most significant feature is the AX 2012 support. Also some shortcuts for tools of AX 2012 are added.&lt;br /&gt;&lt;br /&gt;Another new thingy is the free choice of the system tray icon. You can now refer to your favorite icon file; it will be used as Systray Icon for SmartStart. And the GUI has delighted with tool tips.&lt;br /&gt;&lt;br /&gt;Several bugs have been fixed and help file is updated. And, even I gave my best, probably some new bugs found their way in. Please let me know if you have any trouble.&lt;br /&gt;&lt;br /&gt;You can find the new release as usual on the &lt;a href="http://www.smartstart3000.luegisdorf.ch/"&gt;SmartStart 3000 Central&lt;/a&gt;. There you find the download, product description, language support, help file, feedback form and so on ...&lt;br /&gt;&lt;br /&gt;Many thanks to the translators!&lt;br /&gt;&lt;br /&gt;Known Issue: The graphic rendering on Windows Vista and Windows 7 is not as smooth as it should be. In a funny way, this does not concern Windows XP and older Windows versions. But to optimize the graphics you can size the buttons to 48 pixels. I will keep an eye on that issue and fix it with a minor/revision release.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7304056241767406393?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7304056241767406393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2012/01/new-major-release-for-smartstart3000.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7304056241767406393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7304056241767406393'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2012/01/new-major-release-for-smartstart3000.html' title='New major release for SmartStart3000'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-6955493081708137531</id><published>2011-12-21T18:11:00.000+01:00</published><updated>2011-12-21T18:11:32.310+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>ChangeCompany: common.company() vs. common.dataAreaId</title><content type='html'>When you use the &lt;span style="color: blue;"&gt;&lt;em&gt;changeCompany(...)&lt;/em&gt;&lt;/span&gt; functionality and the company should be retrieved by a record's company you should always use &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;changeCompany(common.company())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do something in the specific company&lt;br /&gt;}&lt;/pre&gt;instead of &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;changeCompany(common.dataAreaId)&lt;br /&gt;{&lt;br /&gt;    // do something in the specific company&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="brush: c-sharp;" style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;Why? Because the dataAreaId can contain a virtual company aswell as a normal company, and if you try to do &lt;em&gt;&lt;span style="color: blue;"&gt;changeCompany(virtualCompany)&lt;/span&gt;&lt;/em&gt;, this will&amp;nbsp;interrupt with a runtime error. But the &lt;span style="color: blue;"&gt;&lt;em&gt;company()&lt;/em&gt;&lt;/span&gt; property&amp;nbsp;returns always the selectable company which can properly used in a &lt;em&gt;&lt;span style="color: blue;"&gt;changeCompany(...)&lt;/span&gt;&lt;/em&gt; statement.&lt;br /&gt;&lt;br /&gt;This works also with table views and&amp;nbsp;crosscompany&amp;nbsp;selections:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;while select crosscompany:['Company1', 'Company2'] common&lt;br /&gt;{&lt;br /&gt;    changeCompany(common.company())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// do something in the specific company&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/pre&gt;&lt;div class="brush: c-sharp;" style="margin: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;By the way, probably unknown to much people, this &lt;span style="color: blue;"&gt;&lt;em&gt;company(...)&lt;/em&gt;&lt;/span&gt; property can be used before data modification to dictate operation company:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;    // current company is Company1&lt;br /&gt;    common.company('Company2');&lt;br /&gt;    select firstonly common; // this will return the first row in Company2 even you are in Company1!&lt;/pre&gt;&lt;br /&gt;I think, this can minimize the use of &lt;em&gt;&lt;span style="color: blue;"&gt;changeCompany(...)&lt;/span&gt; &lt;/em&gt;if used wisely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-6955493081708137531?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/6955493081708137531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2011/12/changecompany-commoncompany-vs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6955493081708137531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6955493081708137531'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2011/12/changecompany-commoncompany-vs.html' title='ChangeCompany: common.company() vs. common.dataAreaId'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-2969609549694604767</id><published>2011-06-14T12:17:00.001+02:00</published><updated>2011-12-22T13:38:31.522+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Fun'/><title type='text'>Change your Windows 7 into the Dynamics OS</title><content type='html'>Hi there&lt;br /&gt;&lt;br /&gt;However, this time a funny post. Have you ever considered to change the Windows 7 Start Button (the blinky orb on the left in the task pane)? Since it is just a ressource in &lt;span style="color: blue;"&gt;explorer.exe&lt;/span&gt;, it is quite easy to do.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download the 'Windows 7 button changer' from here:&amp;nbsp; &lt;a href="http://luegisdorf.ch/w7btnChange2.6.exe"&gt;http://luegisdorf.ch/w7btnChange2.6.exe&lt;/a&gt; (of course you can find it elsewere on the web too)&lt;/li&gt;&lt;li&gt;Download the 'Dynamics Orb' from here: &lt;a href="http://luegisdorf.ch/AX/6801_dynamics.bmp"&gt; http://luegisdorf.ch/AX/6801_dynamics.bmp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Make sure, your user has local administrator rights for the current machine&lt;/li&gt;&lt;li&gt;Change properties for explorer.exe in (...\Windows\explorer.exe) as follow:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Change owner to your account (security, advanced, owner)&lt;/li&gt;&lt;li&gt;Change security settings to allow full access for&amp;nbsp;current user&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Open the 'Windows 7 Button Changer' application, select the the downloaded bitmap file&lt;/li&gt;&lt;li&gt;Revert settings for explorer.exe (remove rights, reset owner)&lt;/li&gt;&lt;li&gt;Enjoy your new Dynamics OS!&lt;/li&gt;&lt;/ol&gt;And that's how it looks:&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-YMmyciUUmlQ/TfdCJrbKwWI/AAAAAAAAAEQ/op93M2XeR9Q/s1600/taskpane_idle.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="28" src="http://3.bp.blogspot.com/-YMmyciUUmlQ/TfdCJrbKwWI/AAAAAAAAAEQ/op93M2XeR9Q/s320/taskpane_idle.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Idle&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KkLB_kFK7ck/TfdCOJf7OhI/AAAAAAAAAEU/Wo4w9kxo_Jo/s1600/taskpane_hover.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="28" src="http://1.bp.blogspot.com/-KkLB_kFK7ck/TfdCOJf7OhI/AAAAAAAAAEU/Wo4w9kxo_Jo/s320/taskpane_hover.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Hover&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jWLjlfhUVqg/TfdCQ1EPRZI/AAAAAAAAAEY/0C32wy6CICM/s1600/taskpane_pressed.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="29" src="http://4.bp.blogspot.com/-jWLjlfhUVqg/TfdCQ1EPRZI/AAAAAAAAAEY/0C32wy6CICM/s320/taskpane_pressed.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Pressed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Of course, you need to run the&amp;nbsp;''visual style", not the "classic style" ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-2969609549694604767?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/2969609549694604767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2011/06/change-your-windows-7-into-dynamics-os.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2969609549694604767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2969609549694604767'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2011/06/change-your-windows-7-into-dynamics-os.html' title='Change your Windows 7 into the Dynamics OS'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-YMmyciUUmlQ/TfdCJrbKwWI/AAAAAAAAAEQ/op93M2XeR9Q/s72-c/taskpane_idle.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3019033054907516034</id><published>2010-12-20T14:43:00.001+01:00</published><updated>2010-12-20T14:54:53.606+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='DLL'/><category scheme='http://www.blogger.com/atom/ns#' term='Business Connector'/><title type='text'>WinAPI::getTempFilename() im .NET Business Connector auf einer x64 Maschine</title><content type='html'>Ein Aufruf auf die externe Methode &lt;span style="color: blue;"&gt;GetTempFileNameW&lt;/span&gt;&amp;nbsp;auf &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt;&amp;nbsp;verursacht eine Ausnahme, wenn sie im&amp;nbsp;.NET Business Connector verwendet wird und dieser auf einem x64-System ausgeführt wird.&lt;br /&gt;&lt;br /&gt;Das Problem betrifft zumindest AX 2009 (vielleicht AX 4.0 und AX 3.0 ebenfalls).&lt;br /&gt;&lt;br /&gt;Als&amp;nbsp;Workaround kann man folgenden Code verwenden:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;fileName = System.IO.Path::GetTempFileName(); // returns a filename in the temporary directory&lt;/pre&gt;&lt;br /&gt;oder&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;fileName = CLRInterop::getAnytypeForObject(System.IO.Path::GetTempPath() )+ curuserid() + int642str(CLRInterop::getAnyTypeForObject(netTime.get_Ticks());&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Egal wie man es löst, natürlich sollte man eine temporäre Datei nach Verwendung auch immer wieder löschen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3019033054907516034?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3019033054907516034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/winapigettempfilename-im-net-business.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3019033054907516034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3019033054907516034'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/winapigettempfilename-im-net-business.html' title='WinAPI::getTempFilename() im .NET Business Connector auf einer x64 Maschine'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3642402026885331752</id><published>2010-12-20T14:26:00.001+01:00</published><updated>2010-12-20T14:54:53.607+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='DLL'/><category scheme='http://www.blogger.com/atom/ns#' term='Business Connector'/><title type='text'>WinAPI::getTempFilename() in .NET Business Connector on a x64 machine</title><content type='html'>A call on the&amp;nbsp;external method &lt;span style="color: blue;"&gt;GetTempFileNameW&lt;/span&gt; on &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt; will raise an exception when called from the .NET Business Connector which is running on a x64 machine.&lt;br /&gt;&lt;br /&gt;This problem applies at least in AX 2009 (may be on AX 4.0 and AX 3.0&amp;nbsp;too).&lt;br /&gt;&lt;br /&gt;As a workaround you can use code such this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;fileName = System.IO.Path::GetTempFileName(); // returns a filename in the temporary directory&lt;/pre&gt;&lt;br /&gt;or &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;fileName = CLRInterop::getAnytypeForObject(System.IO.Path::GetTempPath() )+ curuserid() + int642str(CLRInterop::getAnyTypeForObject(netTime.get_Ticks());&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However don't forget to delete the temporary file after, since it makes no sense to let garbage alive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3642402026885331752?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3642402026885331752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/winapigettempfilename-in-net-business.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3642402026885331752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3642402026885331752'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/winapigettempfilename-in-net-business.html' title='WinAPI::getTempFilename() in .NET Business Connector on a x64 machine'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-4353986838469745943</id><published>2010-12-10T12:21:00.001+01:00</published><updated>2010-12-20T14:26:11.145+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>RLS in display methods on reports (AX 4.0)</title><content type='html'>X++ select statements&amp;nbsp;do ignore Record Level Security (&lt;span style="color: blue;"&gt;RLS&lt;/span&gt;)&amp;nbsp;by default.&amp;nbsp;With the property&amp;nbsp; &lt;em&gt;recordLevelSecurity &lt;/em&gt;the behaviour to use Record Level Security can be modified.&amp;nbsp;The property can also be used to retrieve the current behaviour.&lt;br /&gt;&lt;br /&gt;But there is a difference to select statements inside display methods. Every select statement has activated Record Level Security if the&amp;nbsp;command is in a scope inside a call stack&amp;nbsp;with&amp;nbsp;a display method root. But the current status is not really available trough the property recordLevelsSecurity. A call to this propery will return &lt;em&gt;false&lt;/em&gt;, make you thinking Record Level Security is off - but it is not.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplTable emplTable;&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    info(strfmt("%1", emplTable.recordLevelSecurity())); // this will return false, but actually it's true!&lt;br /&gt;&lt;br /&gt;    select firstonly Name from emplTable &lt;br /&gt;        where emplTable.EmplId == reportTable.emplId; // the record will use RLS (yeah, it's magic)&lt;br /&gt;&lt;br /&gt;name = emplTable.Name;&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Even here the Record Level Security is on, without explicit change to &lt;em&gt;recordLevelSecurity &lt;/em&gt;property:&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    name = EmplTable::find(reportTable.EmplId); // the select inside the find method will use RLS even you haven't activate this&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you want to ensure, that Record Level Security is really off, you need to touch the property explicit.&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplTable emplTable;&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    emplTable.recordLevelSecurity(false); // this will really free from RLS   &lt;br /&gt;&lt;br /&gt;    select firstonly Name from emplTable &lt;br /&gt;        where emplTable.EmplId == reportTable.emplId;&lt;br /&gt;&lt;br /&gt;    name = emplTable.Name;&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This Problem appears in AX 4.0. In AX 2009 this phenomen does not exists; Record Level Security&amp;nbsp;stays off until you change it explicit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-4353986838469745943?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/4353986838469745943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/rls-in-display-methods-on-reports-ax-40.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4353986838469745943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4353986838469745943'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/rls-in-display-methods-on-reports-ax-40.html' title='RLS in display methods on reports (AX 4.0)'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3655745260763977679</id><published>2010-12-10T10:44:00.001+01:00</published><updated>2010-12-20T14:26:11.145+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>RLS in Displaymethoden auf Berichten (AX 4.0)</title><content type='html'>X++ Select-Statements sind per Standard so eingestellt, dass sie die Sicherheit auf Datensatzebene (&lt;span style="color: blue;"&gt;RLS&lt;/span&gt;) ignorieren. Über die Eigenschaft &lt;em&gt;recordLevelSecurity &lt;/em&gt;kann aber dieses Feature ein- oder ausgeschaltet werden.&amp;nbsp;Die Eigenschaft kann aber auch dazu verwendet werden,&amp;nbsp;den aktuellen Status des Features zu ermitteln.&lt;br /&gt;&lt;br /&gt;Select-Anweisungen innerhalb von Display-Methoden verhalten sich jedoch ein wenig anders. Und zwar&amp;nbsp;ist für&amp;nbsp;jede Select-Anweisung die Sicherheit auf Datensatzebene aktiviert, welche aus dem Aufrufstapel einer Display-Methode stammt. Allerdings ist über die Abfrage der Eigenschaft &lt;em&gt;recordLevelSecurity&lt;/em&gt; nicht ermittelbar ob das Feature nun aktiviert ist oder nicht. Ein Aufruf von &lt;em&gt;recordLevelSecurity&lt;/em&gt; gibt in einer solchen Situation stets &lt;span style="color: black;"&gt;&lt;em&gt;false&lt;/em&gt;&lt;/span&gt; zurück was vermeintlicherweise zu der Annahme führen könnte, dass die Sicherheit auf Datensatzebene nicht aktiv ist obwohl sie das ist.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplTable emplTable;&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    info(strfmt("%1", emplTable.recordLevelSecurity())); // this will return false, but actually it's true!&lt;br /&gt;&lt;br /&gt;    select firstonly Name from emplTable &lt;br /&gt;        where emplTable.EmplId == reportTable.emplId; // the record will use RLS (yeah, it's magic)&lt;br /&gt;&lt;br /&gt;name = emplTable.Name;&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Auch so ist die Sicherheit auf Datensatzebene aktiv - ohne dass eine explizite&amp;nbsp;Änderung der&amp;nbsp;Eigschaft&amp;nbsp;&lt;em&gt;recordLevelSecurity&lt;/em&gt; erfolgt:&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    name = EmplTable::find(reportTable.EmplId); // the select inside the find method will use RLS even you haven't activate this&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Will man nun sicherstellen, dass die Sicherheit auf Datensatzebene wirklich deaktiviert ist, muss man explizit die Eigenschaft nocheinmal setzen.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;display showEmplName()&lt;br /&gt;{&lt;br /&gt;    EmplTable emplTable;&lt;br /&gt;    EmplName name;&lt;br /&gt;    ;&lt;br /&gt;    emplTable.recordLevelSecurity(false); // this will really free from RLS   &lt;br /&gt;&lt;br /&gt;    select firstonly Name from emplTable &lt;br /&gt;        where emplTable.EmplId == reportTable.emplId;&lt;br /&gt;&lt;br /&gt;    name = emplTable.Name;&lt;br /&gt;&lt;br /&gt;    return name;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dieses Problem betrifft AX 4.0. In AX 2009 tritt das Phänomen nicht mehr auf; die Sicherheit auf Datensatzebene bleibt deaktiviert bis sie explizit aktiviert wird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3655745260763977679?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3655745260763977679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/rls-in-displaymethoden-auf-berichten-ax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3655745260763977679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3655745260763977679'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/rls-in-displaymethoden-auf-berichten-ax.html' title='RLS in Displaymethoden auf Berichten (AX 4.0)'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7157596555210745948</id><published>2010-12-10T10:43:00.000+01:00</published><updated>2010-12-10T10:43:46.026+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Migration'/><title type='text'>Benutzergruppe lässt sich nicht löschen nach Migration von AX 3.0 nach AX 2009</title><content type='html'>Manchmal kann es vorkommen, dass sich von AX 3.0 migrierte Benutzergruppen nicht löschen lassen. Folgender Effekt tritt ein: Man löscht die Benutzergruppe und die Zeile verschwindet, öffnet man das Formular allerdings erneut, wird die Benutzergruppe wieder angezeigt.&lt;br /&gt;&lt;br /&gt;Das passiert, wenn der Konfigurationsschlüssel für Reporting Services aktiviert ist, aber keine Reporting Services Server angegeben und eingerichtet&amp;nbsp;wurden.&lt;br /&gt;&lt;br /&gt;Mit einer kleinen Anpassung in &lt;span style="color: blue;"&gt;AOT/Forms/SysUserGroupInfo/Data Sources/User Group Info/delete&lt;/span&gt;&amp;nbsp;kann dem Problem abgeholfen werden.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void delete()&lt;br /&gt;{&lt;br /&gt;    userGroupId groupID;&lt;br /&gt;    SysSRSTablePermissions permissionsTable;&lt;br /&gt;    AifEndpointUser aifEndpointUser;&lt;br /&gt;    SysSecurityFormTable    sysSecurityFormTable;&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;    groupID = userGroupInfo.Id;&lt;br /&gt;&lt;br /&gt;    ttsbegin;&lt;br /&gt;&lt;br /&gt;    delete_from aifEndpointUser&lt;br /&gt;        where aifEndpointUser.UserId == groupID&lt;br /&gt;        &amp;amp;&amp;amp; aifEndpointUser.AxaptaUserType == AifAxaptaUserType::UserGroup;&lt;br /&gt;&lt;br /&gt;    delete_from sysSecurityFormTable&lt;br /&gt;        where sysSecurityFormTable.UserGroupId == groupID;&lt;br /&gt;&lt;br /&gt;    super();&lt;br /&gt;&lt;br /&gt;    if (isConfigurationkeyEnabled(configurationKeyName2Id('ReportingServices')))&lt;br /&gt;    {&lt;br /&gt;        //Now that the group is deleted, we can synchronize all the secure views that&lt;br /&gt;        //include RLS criteria for this group. We need to keep the record for this&lt;br /&gt;        //group in SRSTablePermissions for now because they are used to determine which&lt;br /&gt;        //tables have permissions assigned to them for the specified group.&lt;br /&gt;        //Once all views have been synchronized, then we can delete those records.&lt;br /&gt;&lt;br /&gt;        if (SRSSecureViewManagerProxy::syncWithGroup(groupID) != 0)&lt;br /&gt;        {&lt;br /&gt;            // modificaton begin&lt;br /&gt;            if ((select * from SRSServers).RecId)&lt;br /&gt;            {&lt;br /&gt;                ttsabort;&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;            /*else&lt;br /&gt;            {&lt;br /&gt;                just fall trough, there is no need to abort, since there is no Reporting Services Servers located&lt;br /&gt;            }*/&lt;br /&gt;            // modification end&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //Delete all records for the group from the SRSTablePermissions table.&lt;br /&gt;        delete_from permissionsTable where permissionsTable.GroupId == groupID;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ttscommit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Nun können auch alte migrierte Benutzergruppen gelöscht werden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7157596555210745948?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7157596555210745948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/benutzergruppe-lasst-sich-nicht-loschen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7157596555210745948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7157596555210745948'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/12/benutzergruppe-lasst-sich-nicht-loschen.html' title='Benutzergruppe lässt sich nicht löschen nach Migration von AX 3.0 nach AX 2009'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-6161749551690450062</id><published>2010-10-22T14:20:00.001+02:00</published><updated>2010-12-10T10:44:00.387+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting Services'/><category scheme='http://www.blogger.com/atom/ns#' term='Migration'/><title type='text'>Unable to delete User Group after upgrade from AX 3.0 to AX 2009</title><content type='html'>Sometimes you are not able to delete user groups which are migrated from AX 3.0. The effect is as follow: you try to delete and the row removes, but re-opening the form will show the user group again.&lt;br /&gt;&lt;br /&gt;This happens if the configuration key for Reporting Services is enabled, but&amp;nbsp;there is no Reporting Services Server refered&amp;nbsp;and configured&amp;nbsp;in AX.&lt;br /&gt;&lt;br /&gt;With a little modification&amp;nbsp;in&amp;nbsp;&lt;span style="color: blue;"&gt;AOT/Forms/SysUserGroupInfo/Data Sources/User Group Info/delete&lt;/span&gt;&amp;nbsp;you can workaround the problem.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void delete()&lt;br /&gt;{&lt;br /&gt;    userGroupId groupID;&lt;br /&gt;    SysSRSTablePermissions permissionsTable;&lt;br /&gt;    AifEndpointUser aifEndpointUser;&lt;br /&gt;    SysSecurityFormTable    sysSecurityFormTable;&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;    groupID = userGroupInfo.Id;&lt;br /&gt;&lt;br /&gt;    ttsbegin;&lt;br /&gt;&lt;br /&gt;    delete_from aifEndpointUser&lt;br /&gt;        where aifEndpointUser.UserId == groupID&lt;br /&gt;        &amp;amp;&amp;amp; aifEndpointUser.AxaptaUserType == AifAxaptaUserType::UserGroup;&lt;br /&gt;&lt;br /&gt;    delete_from sysSecurityFormTable&lt;br /&gt;        where sysSecurityFormTable.UserGroupId == groupID;&lt;br /&gt;&lt;br /&gt;    super();&lt;br /&gt;&lt;br /&gt;    if (isConfigurationkeyEnabled(configurationKeyName2Id('ReportingServices')))&lt;br /&gt;    {&lt;br /&gt;        //Now that the group is deleted, we can synchronize all the secure views that&lt;br /&gt;        //include RLS criteria for this group. We need to keep the record for this&lt;br /&gt;        //group in SRSTablePermissions for now because they are used to determine which&lt;br /&gt;        //tables have permissions assigned to them for the specified group.&lt;br /&gt;        //Once all views have been synchronized, then we can delete those records.&lt;br /&gt;&lt;br /&gt;        if (SRSSecureViewManagerProxy::syncWithGroup(groupID) != 0)&lt;br /&gt;        {&lt;br /&gt;            // modificaton begin&lt;br /&gt;            if ((select * from SRSServers).RecId)&lt;br /&gt;            {&lt;br /&gt;                ttsabort;&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;            /*else&lt;br /&gt;            {&lt;br /&gt;                just fall trough, there is no need to abort, since there is no Reporting Services Servers located&lt;br /&gt;            }*/&lt;br /&gt;            // modification end&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //Delete all records for the group from the SRSTablePermissions table.&lt;br /&gt;        delete_from permissionsTable where permissionsTable.GroupId == groupID;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ttscommit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Now your able to delete migrated user groups.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-6161749551690450062?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/6161749551690450062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/unable-to-delete-user-group-after.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6161749551690450062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6161749551690450062'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/unable-to-delete-user-group-after.html' title='Unable to delete User Group after upgrade from AX 3.0 to AX 2009'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-8982518903952746515</id><published>2010-10-04T17:29:00.001+02:00</published><updated>2010-10-04T17:42:02.459+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Icons for Dynamics AX files</title><content type='html'>File used by Dynamics AX are often diplayed with the client executable&amp;nbsp;icon or even with no related icon.&lt;br /&gt;&lt;br /&gt;I've created some symbols which can be used as file icons for Dynamics AX. Additionally I've created a small&amp;nbsp;application to let assign the files with the icons.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.luegisdorf.ch/AX/AxIcons.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="337" px="true" src="http://www.luegisdorf.ch/AX/AxIcons.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The application can be downloaded here:&lt;br /&gt;&lt;a href="http://www.luegisdorf.ch/AX/AXIcons.exe"&gt;http://www.luegisdorf.ch/AX/AXIcons.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On Vista/7 you have to run the application with administrator rights, otherwise the application will not work properly. And the executable file should be permanent placed in a local path, where it doesn't move again, because the icons are embedded in the EXE file (a good place could be C:\Programm files\Microsoft Dynamics AX\Common).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-8982518903952746515?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/8982518903952746515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/icons-for-dynamics-ax-files.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8982518903952746515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8982518903952746515'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/icons-for-dynamics-ax-files.html' title='Icons for Dynamics AX files'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-1533336353607331750</id><published>2010-10-04T16:57:00.001+02:00</published><updated>2010-10-04T17:42:02.463+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Icons für Dynamics AX Dateien</title><content type='html'>Die für Dynamics AX eingesetzten Dateien haben meistens das Standard-Icon des Clients oder gar kein&amp;nbsp;Icon&amp;nbsp;zugewiesen.&lt;br /&gt;&lt;br /&gt;Ich habe ein paar Symbole gestaltet die sich als Datei-Icons für Dynamics AX verwenden lassen. Zusätzlich habe ich ein Programm erstellt, mit welchem&amp;nbsp;die Icons zugewiesen werden können.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.luegisdorf.ch/AX/AxIcons.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="337" px="true" src="http://www.luegisdorf.ch/AX/AxIcons.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Das Programm findet man hier:&lt;br /&gt;&lt;a href="http://www.luegisdorf.ch/AX/AXIcons.exe"&gt;http://www.luegisdorf.ch/AX/AXIcons.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Man muss es allerdings unter Vista/7 als Administrator ausführen damit es richtig funktioniert. Und das Programm sollte permanent an einen lokalen&amp;nbsp;Platz gelegt werden, an dem es nicht mehr wegverschoben wird, weil die Icons sich direkt in der EXE-Datei befinden (z.B: C:\Program files\Microsoft Dynamics AX\Common).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-1533336353607331750?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/1533336353607331750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/icons-fur-dynamics-ax-dateien.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1533336353607331750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1533336353607331750'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/10/icons-fur-dynamics-ax-dateien.html' title='Icons für Dynamics AX Dateien'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-8730180518032215212</id><published>2010-09-21T14:49:00.001+02:00</published><updated>2010-09-21T17:43:04.412+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='DLL'/><category scheme='http://www.blogger.com/atom/ns#' term='Business Connector'/><category scheme='http://www.blogger.com/atom/ns#' term='EnterprisePortal'/><category scheme='http://www.blogger.com/atom/ns#' term='CLR'/><title type='text'>FirstWeekOfYear without getLocaleInfo</title><content type='html'>Sometimes it happens, that the function&amp;nbsp;&lt;em&gt;WinAPI::getLocaleInfo()&lt;/em&gt;&amp;nbsp;raises an exception, when calling the Windows function &lt;span style="color: blue;"&gt;GetLocaleInfoW&lt;/span&gt; in &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;While the function works for the GUI client, you get this exception in Enterpriseportal:&lt;br /&gt;&lt;blockquote&gt;Dynamics Object Adapter Call failed.&lt;br /&gt;&lt;br /&gt;Funktion 'GetLocaleInfoW' in DLL-Bibliothek 'KERNEL32' hat eine Ausnahmebedingung ausgelöst.&lt;br /&gt;&lt;br /&gt;Microsoft.Dynamics.BusinessConnectorNet.XppException&lt;br /&gt;at Microsoft.Dynamics.BusinessConnectorNet.AxaptaObject.Call(String methodName, Object[] paramList)&lt;br /&gt;at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsObjectAdapter.Call(String methodName, Object param1)&lt;/blockquote&gt;&lt;br /&gt;The impact for the user was, that he just get a plain lookup popup window instead a calendar popup to select a date for a data field. *&lt;br /&gt;&lt;br /&gt;I was unable to find the excact reason for that bug. But I assume it's the combination of x64 architecture, the .NET Business Connector and the use of a Unicode Windows Kernel function.&lt;br /&gt;&lt;br /&gt;To bypass the error we've modified the method&lt;em&gt; Global::firstWeekOfYear()&lt;/em&gt;, which was the caller to &lt;em&gt;WinAPI::getLocaleInfo()&lt;/em&gt;, as follow:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Original:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static int firstWeekOfYear()&lt;br /&gt;{&lt;br /&gt;    #WinAPI&lt;br /&gt;    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Modified:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static int firstWeekOfYear()&lt;br /&gt;{&lt;br /&gt;    /* #WinAPI&lt;br /&gt;    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));&lt;br /&gt;    */&lt;br /&gt;&lt;br /&gt;    System.Globalization.DateTimeFormatInfo info = System.Globalization.DateTimeFormatInfo::get_CurrentInfo();&lt;br /&gt;    System.Globalization.CalendarWeekRule rule = info.get_CalendarWeekRule();&lt;br /&gt;    ;&lt;br /&gt;    return(CLRInterop::getAnyTypeForObject(rule));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this modification the Windows function &lt;span style="color: blue;"&gt;GetLocaleInfoW &lt;/span&gt;in &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt;&amp;nbsp;will not be direct used.&lt;br /&gt;&lt;br /&gt;* Webframework&amp;nbsp;based&amp;nbsp;on Webforms (until AX 2009)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-8730180518032215212?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/8730180518032215212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/09/firstweekofyear-without-getlocaleinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8730180518032215212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8730180518032215212'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/09/firstweekofyear-without-getlocaleinfo.html' title='FirstWeekOfYear without getLocaleInfo'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-4275127958914679477</id><published>2010-09-21T14:46:00.001+02:00</published><updated>2010-09-21T17:43:04.461+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='DLL'/><category scheme='http://www.blogger.com/atom/ns#' term='Business Connector'/><category scheme='http://www.blogger.com/atom/ns#' term='EnterprisePortal'/><category scheme='http://www.blogger.com/atom/ns#' term='CLR'/><title type='text'>FirstWeekOfYear ohne getLocaleInfo</title><content type='html'>Manchmal kommt es vor, dass die&amp;nbsp;Funktion &lt;em&gt;WinAPI::getLocaleInfo()&lt;/em&gt;&amp;nbsp;beim Aufruf der Windowsfunktion &lt;span style="color: blue;"&gt;GetLocaleInfoW&lt;/span&gt; in &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt; einen Fehler verursacht.&lt;br /&gt;&lt;br /&gt;Während die Funktion über den GUI-Client einwandfrei funktioniert, erhält man beim Aufruf über das Enterpriseportal eine Ausnahme:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Dynamics Object Adapter Call failed.&lt;br /&gt;&lt;br /&gt;Funktion 'GetLocaleInfoW' in DLL-Bibliothek 'KERNEL32' hat eine Ausnahmebedingung ausgelöst.&lt;br /&gt;&lt;br /&gt;Microsoft.Dynamics.BusinessConnectorNet.XppException&lt;br /&gt;at Microsoft.Dynamics.BusinessConnectorNet.AxaptaObject.Call(String methodName, Object[] paramList)&lt;br /&gt;at Microsoft.Dynamics.Framework.BusinessConnector.Session.DynamicsObjectAdapter.Call(String methodName, Object param1)&lt;/blockquote&gt;&lt;br /&gt;Für den Benutzer bedeutete dies, dass er in Lookupfenstern zum Auswählen eines Datums schlichtweg einfach nur eine weisse Seite sah, statt des erwarteten Kalenders.*&lt;br /&gt;&lt;br /&gt;Leider konnten wir die Ursache des Fehlers nicht herausfinden. Ich vermute allerdings, dass die Kombination von x64-Architektur, dem .NET-Business-Connector und dem Aufruf einer&amp;nbsp;Unicode-Windows-Kernelfunktion&amp;nbsp;etwas damit zu tun hat.&lt;br /&gt;&lt;br /&gt;Als Abhilfe haben wir die betreffende Methode&lt;em&gt; Global::firstWeekOfYear()&lt;/em&gt;, welche in unserem Fall die Aufrufende Methode war, wie folgt angepasst:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Original:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static int firstWeekOfYear()&lt;br /&gt;{&lt;br /&gt;    #WinAPI&lt;br /&gt;    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Modifiziert:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static int firstWeekOfYear()&lt;br /&gt;{&lt;br /&gt;    /* #WinAPI&lt;br /&gt;    return str2int(WinAPI::getLocaleInfo(#LOCALE_USER_DEFAULT, #LOCALE_FIRSTWEEKOFYEAR));&lt;br /&gt;    */&lt;br /&gt;&lt;br /&gt;    System.Globalization.DateTimeFormatInfo info = System.Globalization.DateTimeFormatInfo::get_CurrentInfo();&lt;br /&gt;    System.Globalization.CalendarWeekRule rule = info.get_CalendarWeekRule();&lt;br /&gt;    ;&lt;br /&gt;    return(CLRInterop::getAnyTypeForObject(rule));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Auf diese Weise wird die Windowsfunktion &lt;span style="color: blue;"&gt;GetLocaleInfoW&lt;/span&gt; in &lt;span style="color: blue;"&gt;Kernel32&lt;/span&gt; erst gar nicht direkt verwendet.&lt;br /&gt;&lt;br /&gt;* Webframework basierend auf Webforms (bis AX 2009)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-4275127958914679477?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/4275127958914679477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/09/firstweekofyear-ohne-getlocaleinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4275127958914679477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4275127958914679477'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/09/firstweekofyear-ohne-getlocaleinfo.html' title='FirstWeekOfYear ohne getLocaleInfo'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-4476250128880723428</id><published>2010-08-25T18:28:00.001+02:00</published><updated>2010-08-25T18:52:49.441+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Update_recordset and arrays from joint tables</title><content type='html'>The database modification command &lt;span style="color: blue;"&gt;update_recordset&lt;/span&gt; gives you nice possibility to modify data in a fast way.&lt;br /&gt;&lt;br /&gt;Unfortunately this kernel command a some little bug if you are using an array element of a joint table for value assignment. The follow &lt;span style="color: blue;"&gt;update_recordset&lt;/span&gt; will be partial ignored, specific from the assignement from the array element &lt;em&gt;custTableRead.Dimension[2]&lt;/em&gt;. This assignment and any following field value assignment will be left out (so the assignment of NameAlias with the value "any Alias" will just fail too):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;    CustTable    custTableUpdate;&lt;br /&gt;    CustTable    custTableRead;&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;    ttsbegin;&lt;br /&gt;&lt;br /&gt;    update_recordset custTableUpdate setting Street = custTableRead.Street, Name = custTableRead.Dimension[2], NameAlias = "any Alias"&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;br /&gt;    info(strfmt("%1", custTableUpdate.RowCount()));&lt;br /&gt;&lt;br /&gt;    select firstonly custTableUpdate where custTableUpdate.AccountNum == "00000001";&lt;br /&gt;&lt;br /&gt;    info(custTableUpdate.Street); // works fine so far&lt;br /&gt;    info(custTableUpdate.Name); // you didn't get what you expect&lt;br /&gt;    info(custTableUpdate.NameAlias); // you didn't get what you expect&lt;br /&gt;&lt;br /&gt;    ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s1600/update_recordset_join_array.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ox="true" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s320/update_recordset_join_array.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;But all works fine as long as you code it without any array field:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;update_recordset custTableUpdate setting Name = custTableRead.Name, NameAlias = "any Alias"&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Also works fine too, if the array field is hosted by the same table as the table which is selected for update.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;update_recordset custTableUpdate setting Name = custTableUpdate.Dimension[2], Street = custTableRead.Street&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To make a assignment from &lt;em&gt;custTableRead.Dimension[2]&lt;/em&gt; to &lt;em&gt;custTableUpdate.Name&lt;/em&gt; to work, you have to do it the old fashion way: select first, then update. Well, the execution of this code is slower, but it works (and that's prior in my eyes :).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;ttsbegin;&lt;br /&gt;&lt;br /&gt;    select firstonly Dimension from custTableRead&lt;br /&gt;        where custTableRead.AccountNum == "00000002"&lt;br /&gt;        join forupdate custTableUpdate&lt;br /&gt;            where custTableUpdate.AccountNum == "00000001";&lt;br /&gt;        &lt;br /&gt;    custTableUpdate.Name = custTableRead.Dimension[2];&lt;br /&gt;    custTableUpdate.update();&lt;br /&gt;        &lt;br /&gt;    ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This behaviour relates to AX 2009 only and (if not fixed in the meantime) later versions, since the ability to use joins in &lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&lt;/span&gt; was invented in version AX 2009.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-4476250128880723428?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/4476250128880723428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/08/updaterecordset-and-arrays-from-joint.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4476250128880723428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/4476250128880723428'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/08/updaterecordset-and-arrays-from-joint.html' title='Update_recordset and arrays from joint tables'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s72-c/update_recordset_join_array.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-2311906693087933776</id><published>2010-08-06T13:04:00.001+02:00</published><updated>2010-08-25T18:52:49.447+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Update_recordset und Arrays von gejointen Tabellen</title><content type='html'>Die Datenbankmodifikationsansweisung &lt;span style="color: blue;"&gt;update_recordset&lt;/span&gt; bietet hübsche Möglichkeiten zum schnellen&amp;nbsp;Ändern von Daten.&lt;br /&gt;&lt;br /&gt;Leider hat sich hier im Kernel ein kleiner Fehler eingeschlichen, wenn man als Wertzuweisung ein Array-Element einer gejointen Tabelle verwendet. Folgendes &lt;span style="color: blue;"&gt;update_recordset&lt;/span&gt; wird&amp;nbsp;teilweise ignoriert, konkret&amp;nbsp;ab der Zuweisung des&amp;nbsp;Array-Element &lt;em&gt;custTableRead.Dimension[2]&lt;/em&gt; wird diese sowie jede weitere Feldwertzuweisung ausgelassen (also auch die Zuweisung von NameAlias mit dem Wert "any Alias" wird schlichtweg nicht durchgeführt):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;    CustTable    custTableUpdate;&lt;br /&gt;    CustTable    custTableRead;&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;    ttsbegin;&lt;br /&gt;&lt;br /&gt;    update_recordset custTableUpdate setting Street = custTableRead.Street, Name = custTableRead.Dimension[2], NameAlias = "any Alias"&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;br /&gt;    info(strfmt("%1", custTableUpdate.RowCount()));&lt;br /&gt;&lt;br /&gt;    select firstonly custTableUpdate where custTableUpdate.AccountNum == "00000001";&lt;br /&gt;&lt;br /&gt;    info(custTableUpdate.Street); // works fine so far&lt;br /&gt;    info(custTableUpdate.Name); // you didn't get what you expect&lt;br /&gt;    info(custTableUpdate.NameAlias); // you didn't get what you expect&lt;br /&gt;&lt;br /&gt;    ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s1600/update_recordset_join_array.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ox="true" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s320/update_recordset_join_array.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Allerdings funktioniert alles prima, wenn kein Array-Feld im Spiel ist:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;update_recordset custTableUpdate setting Name = custTableRead.Name, NameAlias = "any Alias"&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Es funktioniert auch wenn das Array-Feld von der gleichen Tabelle stammt wie die zu aktualisierende Tabelle.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;update_recordset custTableUpdate setting Name = custTableUpdate.Dimension[2], Street = custTableRead.Street&lt;br /&gt;        where custTableUpdate.AccountNum == "00000001"&lt;br /&gt;        join custTableRead&lt;br /&gt;            where custTableRead.AccountNum == "00000002";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Damit eine Zuweisung von &lt;em&gt;custTableRead.Dimension[2]&lt;/em&gt; in &lt;em&gt;custTableUpdate.Name&lt;/em&gt; korrekt funktioniert muss man leider den altmodischen Weg gehen: Die Datensätze erst auswählen, dann die Zuweisung vornehmen und danach aktualisieren. Dies kostet zwar mehr Zeit, funktioniert dafür aber korrekt (was meiner Meinung nach auch mehr Priorität geniesst :).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;ttsbegin;&lt;br /&gt;&lt;br /&gt;    select firstonly Dimension from custTableRead&lt;br /&gt;        where custTableRead.AccountNum == "00000002"&lt;br /&gt;        join forupdate custTableUpdate&lt;br /&gt;            where custTableUpdate.AccountNum == "00000001";&lt;br /&gt;        &lt;br /&gt;    custTableUpdate.Name = custTableRead.Dimension[2];&lt;br /&gt;    custTableUpdate.update();&lt;br /&gt;        &lt;br /&gt;    ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Dieses Verhalten bezieht sich nur auf AX 2009 und (falls nicht korrigiert) spätere Versionen. Die Möglichkeit zur Verwendung von Joins in &lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&lt;/span&gt; steht nämlich erst ab AX 2009 zur Verfügung.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-2311906693087933776?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/2311906693087933776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/08/updaterecordset-und-arrays-von.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2311906693087933776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2311906693087933776'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/08/updaterecordset-und-arrays-von.html' title='Update_recordset und Arrays von gejointen Tabellen'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_dKaxGw6aZCc/TGv60UAE2kI/AAAAAAAAADY/_oSs8IVFDEs/s72-c/update_recordset_join_array.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7479709845017862437</id><published>2010-07-31T12:15:00.001+02:00</published><updated>2010-07-31T12:31:09.735+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Properties'/><category scheme='http://www.blogger.com/atom/ns#' term='Framework'/><title type='text'>Mandatory-Eigenschaft auf Formdatasource-Feldern mit deaktiviertem Konfigurationsschlüssel</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Es gibt einen Designfehler mit der&amp;nbsp;&lt;i&gt;Mandatory-&lt;/i&gt;Eigenschaft des Formdatasource-Feldes. Wenn man es auf &lt;i&gt;true &lt;/i&gt;setzt, wird auch auf den Feldinhalt geprüft, selbst wenn das Feld mit per Konfiguration deaktiviert ist.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Als Beispiel: Die Tabelle&amp;nbsp;&lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;span class="Apple-style-span" style="color: #bf9000;"&gt;TableA&lt;/span&gt;&lt;/span&gt;&amp;nbsp;hat zwei Felder:&amp;nbsp;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;FieldA&lt;/span&gt;&amp;nbsp;und&amp;nbsp;&lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;.&amp;nbsp;&lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;&amp;nbsp;hat als Konfigurationsschlüssel-Eigenschaft den Wert&amp;nbsp;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;ConfigKeyA&lt;/span&gt;. Man erstellt nun ein Formular mit einer Datasource der Tabelle&amp;nbsp;&lt;span class="Apple-style-span" style="color: #bf9000;"&gt;TableA&lt;/span&gt;&amp;nbsp;und setzt die &lt;i&gt;Mandatory&lt;/i&gt;&lt;i&gt;-&lt;/i&gt;Eigenschaft von&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;&amp;nbsp;auf &lt;i&gt;true&lt;/i&gt;. Dann deaktiviert man den Konfigurationsschlüssel&amp;nbsp;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;ConfigKeyA &lt;/span&gt;im Menü Administration/Einstellungen/System/Konfiguration. Zuletzt startet man den Client neu, öffnet das erstellte Formular und versucht einen neuen Datensatz zu speichern. Der Speichervorgang wird fehlschlagen mit der Meldung, dass &lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;&amp;nbsp;ausgefüllt werden muss.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Als Vorsicht beim Manipulieren der&amp;nbsp;&lt;i&gt;Mandatory-&lt;/i&gt;Eigenschaft auf &amp;nbsp;Formdatasource-Feldern.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Dies betrifft AX 2009, aber gut möglich dass das Fehlverhalten auch in früheren Versionen auftritt.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7479709845017862437?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7479709845017862437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/mandatory-eigenschaft-auf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7479709845017862437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7479709845017862437'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/mandatory-eigenschaft-auf.html' title='Mandatory-Eigenschaft auf Formdatasource-Feldern mit deaktiviertem Konfigurationsschlüssel'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-1167293146576971929</id><published>2010-07-31T12:01:00.001+02:00</published><updated>2010-07-31T12:31:09.738+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Properties'/><category scheme='http://www.blogger.com/atom/ns#' term='Framework'/><title type='text'>Mandatory falg on form data source field with disabled configuration key</title><content type='html'>There's a design bug with the form data source field property called &lt;i&gt;mandatory&lt;/i&gt;. If you set it to &lt;i&gt;true&lt;/i&gt;, the condition if the field is filled in will be checked even the field is deactivated by configuration.&lt;br /&gt;&lt;br /&gt;As an example: Your table &lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;span class="Apple-style-span" style="color: #bf9000;"&gt;TableA&lt;/span&gt;&lt;/span&gt; has two fields: &lt;span class="Apple-style-span" style="color: #38761d;"&gt;FieldA&lt;/span&gt; and &lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;. &lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt; has configuration key property value &lt;span class="Apple-style-span" style="color: #0b5394;"&gt;ConfigKeyA&lt;/span&gt;. You create a form with a data source from table &lt;span class="Apple-style-span" style="color: #bf9000;"&gt;TableA&lt;/span&gt;. You set the data source field &lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt;'s property &lt;i&gt;mandatory&lt;/i&gt; to true. Now you go to administration/settings/system/configuration and deactivate configuration key &lt;span class="Apple-style-span" style="color: #0b5394;"&gt;ConfigKeyA&lt;/span&gt;. At least restart client, open the created form and try to save a new record. It will fail with the message that field &lt;span class="Apple-style-span" style="color: #990000;"&gt;FieldB&lt;/span&gt; has to be filled in.&lt;br /&gt;&lt;br /&gt;So be careful if manipulating the &lt;i&gt;mandatory&lt;/i&gt; property on form data source fields.&lt;br /&gt;&lt;br /&gt;This applies to AX 2009, but I have not tested if it applies to former Versions too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-1167293146576971929?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/1167293146576971929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/mandatory-falg-on-form-data-source.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1167293146576971929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1167293146576971929'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/mandatory-falg-on-form-data-source.html' title='Mandatory falg on form data source field with disabled configuration key'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-591573253406096100</id><published>2010-07-31T11:48:00.001+02:00</published><updated>2010-07-31T12:04:24.819+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>Debugging von Tablemap-Code im Enterprise Portal</title><content type='html'>In AX 2009 (oder auch schon in AX 4.0, kann mich gerade nicht erinnern) ist es nicht möglich Ereigniscode von Steuerelementen auf Formularen zu debuggen.&lt;br /&gt;&lt;br /&gt;Eine ähnliche Verhaltensweise besteht beim X++-Debuggen im Enterprise Portal von von Tablemap-Methoden. Der Debugger reagiert nicht auch wenn ein Breakpoint vorhanden ist. Die einzige Möglichkeit eine Reaktion des Debugger zu erzwingen ist die Verwendung der Anweisung&amp;nbsp;'&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;breakpoint&lt;/span&gt;&lt;/span&gt;', die natürlich nach dem Debuggen wieder entfernt werden sollte.&lt;br /&gt;&lt;br /&gt;Vielleicht betrifft dieser Effekt das Debuggen von X++-Tablemap-Code ausgeführt durch den .NET-Business-Connector ganz allgemein, und nicht nur das Enterprise Portal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-591573253406096100?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/591573253406096100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/debugging-von-tablemap-code-im.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/591573253406096100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/591573253406096100'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/debugging-von-tablemap-code-im.html' title='Debugging von Tablemap-Code im Enterprise Portal'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-2811572636947595507</id><published>2010-07-28T10:41:00.001+02:00</published><updated>2010-07-31T12:04:24.819+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>Debugging tablemap code trough Enterprise Portal</title><content type='html'>As a known fact (or bug), it's not possible to catch breakpoints in control events on forms since AX 2009 (or even AX 4.0 can't remember exactly).&lt;br /&gt;&lt;br /&gt;A similar behaviour exists, if you try to debug X++ code of table maps methods in Enterprise Portal. The debugger won't react even if you have set a breakpoint. The only one method to force the degugger is to use the command '&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;breakpoint&lt;/span&gt;&lt;/span&gt;' in your code, which of course should be removed when finishing debugging.&lt;br /&gt;&lt;br /&gt;May be this affects X++ table map code debugging executed by .NET Business Connector in general, not especially the Enterprise Portal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-2811572636947595507?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/2811572636947595507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/debugging-tablemap-code-trough.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2811572636947595507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2811572636947595507'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/debugging-tablemap-code-trough.html' title='Debugging tablemap code trough Enterprise Portal'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3848352441277945437</id><published>2010-07-19T10:00:00.001+02:00</published><updated>2010-07-19T18:00:48.206+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Select Group by and Join Order By</title><content type='html'>Take care if you mix &lt;span style="color: blue;"&gt;Group By&lt;/span&gt; and &lt;span style="color: blue;"&gt;Order By&lt;/span&gt; in select statements. Queries like that will bring you data from the Data Base, but you loose data; Data retrieved form tables in &lt;span style="color: blue;"&gt;Order By&lt;/span&gt; mode will not be available.&lt;br /&gt;&lt;br /&gt;The code example below retrieves the desired due dates from table CustTransOpen, but the vouchers from table CustTrans are missing:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;CustTable custTable;&lt;br /&gt;CustTrans custTrans;&lt;br /&gt;CustTransOpen custTransOpen;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;while select CustGroup from custtable group by CustGroup // group by&lt;br /&gt;    join Voucher from custTrans // order by&lt;br /&gt;         where custTrans.AccountNum == custtable.AccountNum&lt;br /&gt;         join DueDate from custTransOpen group by DueDate // group by&lt;br /&gt;              where custTransOpen.RefRecId == custTrans.RecId&lt;br /&gt;{&lt;br /&gt;    info(custTable.CustGroup); // works&lt;br /&gt;    info(custTrans.Voucher); // works not&lt;br /&gt;    info(Date2StrUsr(custTransOpen.DueDate)); // works&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Add a 'group by' to CustTrans, and you get CustTrans data too:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;CustTable custTable;&lt;br /&gt;CustTrans custTrans;&lt;br /&gt;CustTransOpen custTransOpen;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;while select CustGroup from custtable group by CustGroup // group by&lt;br /&gt;    join Voucher, RecId from custTrans group by Voucher, RecId // group by&lt;br /&gt;         where custTrans.AccountNum == custtable.AccountNum&lt;br /&gt;         join DueDate from custTransOpen group by DueDate // group by&lt;br /&gt;              where custTransOpen.RefRecId == custTrans.RecId&lt;br /&gt;{&lt;br /&gt;    info(custTable.CustGroup); // works&lt;br /&gt;    info(custTrans.Voucher); // works now&lt;br /&gt;    info(Date2StrUsr(custTransOpen.DueDate)); // works&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This issue applies&amp;nbsp;to queries proceeded with a QueryRun object too.&lt;br /&gt;&lt;br /&gt;Still not clear, if the source of this behaviour is driven by AX or by the&amp;nbsp;SQL engine. But fact is, the mix of &lt;span style="color: blue;"&gt;Group By&lt;/span&gt; and &lt;span style="color: blue;"&gt;Order By&lt;/span&gt; raises hard finding bugs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3848352441277945437?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3848352441277945437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/select-group-by-and-join-order-by.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3848352441277945437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3848352441277945437'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/select-group-by-and-join-order-by.html' title='Select Group by and Join Order By'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-6551124129725982746</id><published>2010-07-19T08:10:00.001+02:00</published><updated>2010-07-19T18:00:48.210+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Select Group By und Join Order By</title><content type='html'>Vorsicht ist geboten bei Select-Statements, welche &lt;span style="color: blue;"&gt;Group By&lt;/span&gt; und &lt;span style="color: blue;"&gt;Order By&lt;/span&gt; mischen. Zwar funktioniert die Abfrage auf der&amp;nbsp;Datenbank korrekt, aber&amp;nbsp;mit der Einbusse von&amp;nbsp;Daten. Daten für &lt;span style="color: blue;"&gt;Order By&lt;/span&gt;-Tabellen sind&amp;nbsp;dann nämlich nicht verfügbar.&lt;br /&gt;&lt;br /&gt;Unten stehendes Beispiel bringt die gewünschten Fälligkeitsdaten der Tabelle CustTransOpen, aber die Belege der Tabelle CustTrans fehlen:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;CustTable custTable;&lt;br /&gt;CustTrans custTrans;&lt;br /&gt;CustTransOpen custTransOpen;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;while select CustGroup from custtable group by CustGroup // group by&lt;br /&gt;    join Voucher from custTrans // order by&lt;br /&gt;         where custTrans.AccountNum == custtable.AccountNum&lt;br /&gt;         join DueDate from custTransOpen group by DueDate // group by&lt;br /&gt;              where custTransOpen.RefRecId == custTrans.RecId&lt;br /&gt;{&lt;br /&gt;    info(custTable.CustGroup); // works&lt;br /&gt;    info(custTrans.Voucher); // works not&lt;br /&gt;    info(Date2StrUsr(custTransOpen.DueDate)); // works&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wenn man der Tabelle CustTrans ein 'group by' hinzufügt, erhält man dann auch Daten:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;CustTable custTable;&lt;br /&gt;CustTrans custTrans;&lt;br /&gt;CustTransOpen custTransOpen;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;while select CustGroup from custtable group by CustGroup // group by&lt;br /&gt;    join Voucher, RecId from custTrans group by Voucher, RecId // group by&lt;br /&gt;         where custTrans.AccountNum == custtable.AccountNum&lt;br /&gt;         join DueDate from custTransOpen group by DueDate // group by&lt;br /&gt;              where custTransOpen.RefRecId == custTrans.RecId&lt;br /&gt;{&lt;br /&gt;    info(custTable.CustGroup); // works&lt;br /&gt;    info(custTrans.Voucher); // works now&lt;br /&gt;    info(Date2StrUsr(custTransOpen.DueDate)); works&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Dieselbe Problematik besteht auch mit Datenabfragen die mit dem QueryRun-Objekt&amp;nbsp;verarbeitet werden.&lt;br /&gt;&lt;br /&gt;Es bleibt offen, ob die Ursache für dieses Problem bei AX oder an der SQL-Engine liegt; feststeht, dass man mit dem Mischen von &lt;span style="color: blue;"&gt;Group By&lt;/span&gt; und &lt;span style="color: blue;"&gt;Order By&lt;/span&gt; Bugs erzeugt, die man leider nicht so schnell herausfindet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-6551124129725982746?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/6551124129725982746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/select-group-by-und-join-order-by.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6551124129725982746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6551124129725982746'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/select-group-by-und-join-order-by.html' title='Select Group By und Join Order By'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-6837752024109036287</id><published>2010-07-15T19:57:00.001+02:00</published><updated>2010-07-15T20:32:22.456+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Bitmanipulation with integer64</title><content type='html'>Take care on bit shifting if the result should be a 64 bit integer. Fragments like the follow code example does not take the obviously desired effect:&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;int64 i64 = 1 &amp;lt;&amp;lt; 32; // move the very right positive bit just 32 ranks to the left&lt;br /&gt;&lt;/pre&gt;The result on that will be 0. The problem comes up with the return value from the operation &lt;span class="Apple-style-span" style="color: blue;"&gt;1 &amp;lt;&amp;lt; 32&lt;/span&gt;, it's an 32 bit integer, even the result will be copied in a 64 bit integer (the bit shfiting operation is executed encapsulated before copy to variable i64). The base operand sets the type of result, in our code it's a constant number (1). And because 1 is a 32 bit integer, the results represents a 32 bit integer too. But why it ends with zero result? Its the reaction for the overflow when trying to access a bit area which is not available on a 32 bit integer (a 32 bit integer has just its 32 bits - not more, not less). Other programming languages reacts in the same situation with exceptions type overflow  (f.ex. VB6) or moves the bits in circle (f.ex. C#), but AX quits that problem situation just with a type specified null value. &lt;br /&gt;&lt;br /&gt;To ensure the code works fine, do it that way:  &lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;int64 base = 1;&lt;br /&gt;int64 result = base &amp;lt;&amp;lt; 32; // move the very right positive bit just 32 ranks to the left&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-6837752024109036287?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/6837752024109036287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/bitmanipulation-with-integer64.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6837752024109036287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6837752024109036287'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/bitmanipulation-with-integer64.html' title='Bitmanipulation with integer64'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7530351686434904135</id><published>2010-07-15T19:18:00.001+02:00</published><updated>2010-07-15T20:32:22.460+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Bitmanipulation mit Integer64</title><content type='html'>Aufgepasst bei Bitverschiebungen wenn das Ergebnis ein Integer 64 Bit Länge sein soll. Manipulationen wie etwas der nachstehend abgebildete Code bringen leider nicht das offensichtlich erwünschte Ergebnis:&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;int64 i64 = 1 &amp;lt;&amp;lt; 32; // move the very right positive bit just 32 ranks to the left&lt;br /&gt;&lt;/pre&gt;Das Resultat draus ist nämlich 0. Das Problem liegt darin, dass der Rückgabewert der Operation &lt;span class="Apple-style-span" style="color: blue;"&gt;1 &amp;lt;&amp;lt; 32&lt;/span&gt; ein Integer 32 Bit Länge ist, auch wenn das ganze sogleich einem Integer 64 Bit Länge zugewiesen wird (die Bitverschiebung wird gekapselt ausgeführt bevor die Zuweisung an die Variable i64 erfolgt). Aber warum ist das Resultat 0? Der Basisoperand der Bitverschiebung bestimmt den Rückgabewert, in unserem Beispiel also eine konstante eins (1). Und weil eine 1 ein Integer 32 Bit Länge darstellt, ist auch das Ergebnis ein simpler Integer 32 Bit Länge. Das Resultat von 0 resultiert aus der Reaktion auf den Überlauf beim Zugriff auf ein Bit-Bereich den es auf einem Integers 32 Bit Länge nicht gibt (ein Integer 32 Bit Länge hat halt eben nur 32 Bits). Andere Programmiersprachen reagieren hier mit einer Ausnahme vom Typ Überlauf (z.B. VB6) oder schieben die Bits im Kreis herum (z.B. C#), AX beendet die Problemsituation schlicht mit einem typenspezifischen Nullwert.&lt;br /&gt;&lt;br /&gt;Damit der Code also richtig funktioniert muss er so geschrieben werden:  &lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;int64 base = 1;&lt;br /&gt;int64 result = base &amp;lt;&amp;lt; 32; // move the very right positive bit just 32 ranks to the left&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7530351686434904135?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7530351686434904135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/bitmanipulation-mit-integer64.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7530351686434904135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7530351686434904135'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/07/bitmanipulation-mit-integer64.html' title='Bitmanipulation mit Integer64'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-5124375688611483363</id><published>2010-05-31T21:57:00.001+02:00</published><updated>2010-05-31T22:23:25.059+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>throw "mischief"</title><content type='html'>Exception handling in AX is actually very simple. You have a bundle predefined exception codes (info, warning, error, CLRError, and so on) and that it is. As much more I was astonished, when a coworker shows me the follow code, saying the exception would be thrown, but the error message was never displayed:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw strfmt("Error in %1", funcname());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The right X++ code was then:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw error(strfmt("Error in %1", funcname()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;While the typical argument for throw is an enumeration of type Exception (), actually the throw instruction accepts any in AX existing type.&lt;br /&gt;&lt;br /&gt;After some tests I get the follow insights:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Kernel obviously tries to convert the given argument into an integer and then to procced the conversion:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;F.ex. this X++ code&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw "3";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;raises an exception with the type error. Ditto&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw "3.7";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;More complex types like objects and tables (except a not initialized CLR-Object) raises exception codes above value 255. Tough only exceptions between 0 and 255 can be handled in a different way, an exception above 255 can be catched with a general catch block.&lt;br /&gt;&lt;/li&gt;&lt;pre&gt;try&lt;br /&gt;{&lt;br /&gt;    throw 230;&lt;br /&gt;}&lt;br /&gt;catch (230)&lt;br /&gt;{&lt;br /&gt;    info("This works fine.")&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    throw 256;&lt;br /&gt;}&lt;br /&gt;catch (256)&lt;br /&gt;{&lt;br /&gt;    // this line will never reached&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;    info("That's the way it is!")&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/ul&gt;&lt;br /&gt;Of course you may think this statement gives the ability to use self defined exception codes. I advice against this idea; in further versions of AX, the self defined codes could be used by the Kernel itself and brings unexpected side effects like continue database transactions (in fact, some exception codes include this feature already).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-5124375688611483363?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/5124375688611483363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/throw-mischief.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5124375688611483363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5124375688611483363'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/throw-mischief.html' title='throw &quot;mischief&quot;'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-82893400645149430</id><published>2010-05-28T18:01:00.001+02:00</published><updated>2010-05-31T22:23:18.250+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>throw "dummfug"</title><content type='html'>Die Ausnahmebehandlung in AX ist ja im Prinzip sehr einfach gehalten. Es gibt eine vordefinierte Anzahl verschiedener Ausnahme-Codes (Info, Warning, Error, CLRError etc.) und damit hat es sich. Recht erstaunt war ich, als eine Arbeitskollegin mir folgenden Code zeigte, mit der Bemerkung dass wohl eine Ausnahme ausgelöst, aber die Feldermeldung dazu niemals angezeigt würde:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw strfmt("Fehler in %1", funcname());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Der korrekte X++ Code lautete schliesslich:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw error(strfmt("Fehler in %1", funcname()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Während typischerweise ein Element der Enumeration vom Typ Exception (also im Prinzip eine Ganzzahl) an throw übergeben wird, akzeptiert diese Anweisung aber in Wirklichkeit jeden in AX vorhandenen Typ.&lt;br /&gt;&lt;br /&gt;Nach ein paar Tests lässt sich folgende Aussagen machen:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Der Kernel versucht offensichtlich das Argument in eine Ganzzahl umzuwandeln und dann zu interpretieren:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Der Code&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw "3";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;löst beispielsweise eine Ausnahme vom Typ Error aus. Ebenso&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;throw "3.7";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Komplexere Typen wie Objekte und Tabellen (mit Ausnahme von nicht initialisierten CLR-Objekten) lösen einen Ausnahmecode grösser 255 aus. Obwohl nur Ausnahmen zwischen 0 und 255 differenziert behandelt werden können, kann eine Ausnahme mit einem höheren Wert als 255 durch einen allgemeinen Catch-Block trotzdem abgefangen werden.&lt;/li&gt;&lt;pre&gt;try&lt;br /&gt;{&lt;br /&gt;    throw 230;&lt;br /&gt;}&lt;br /&gt;catch (230)&lt;br /&gt;{&lt;br /&gt;    info("This works fine.")&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    throw 256;&lt;br /&gt;}&lt;br /&gt;catch (256)&lt;br /&gt;{&lt;br /&gt;    // this line will never reached&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;    info("That's the way it is!")&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/ul&gt;&lt;br /&gt;Nun könnte diese Feststellung natürlich dazu verleiten, selbst definierte Ausnahmecodes einzuführen und zu verwenden. Davon würde ich allerdings abraten; in kommenden Versionen könnten diese durch den Kernel definiert werden und spezielles Verhalten an den Tag legen, wie z.B. das weiterführen von Datenbranktransaktionen, was zur Zeit bei einigen Ausnahmen ja bereits der Fall ist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-82893400645149430?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/82893400645149430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/throw-dummfug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/82893400645149430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/82893400645149430'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/throw-dummfug.html' title='throw &quot;dummfug&quot;'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3969275019396402472</id><published>2010-05-26T19:56:00.005+02:00</published><updated>2010-05-27T09:28:19.193+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>ForUpdate record after record insert</title><content type='html'>Every time, if you save a record into database using method insert() or doInsert(), you're record handle is selected forUpdate. That means, that you can do data manipulation with update() or doUpdate() without reread the current record.&lt;br /&gt;&lt;br /&gt;But to do this you can run into trouble. If you have not a database transaction outside the insertation and manipulation, other users can modify your record as well. And as soon you want to do your update() or doUpdate() you get an exception:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Cannot edit a record in Table (Tablename).&lt;br /&gt;An update conflict occurred due to another user process deleting the record or changing one or more fields in the record.&lt;/blockquote&gt;&lt;br /&gt;Therefore avoid such code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Do it that way instead:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;ttsbegin;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or even this way:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;// time consuming other code here&lt;br /&gt;&lt;br /&gt;ttsbegin;&lt;br /&gt;table.selectForUpdate(true);&lt;br /&gt;table.reread();&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Depending on requirements you may need a database transaction over all code or not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3969275019396402472?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3969275019396402472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/forupdate-record-after-record-insert.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3969275019396402472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3969275019396402472'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/forupdate-record-after-record-insert.html' title='ForUpdate record after record insert'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-1464067810767231361</id><published>2010-05-26T19:56:00.004+02:00</published><updated>2010-05-27T09:26:00.717+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database interaction'/><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>ForUpdate-Datensatz nach dem Einfügen eines Datensatzes</title><content type='html'>Jedes mal, wenn ein Datensatz mit der insert()- oder der doInsert()-Methode auf der Datenbank erzeugt wird, erhält man den neu erzeugten Datensatz mit dem Prädikat forupdate. Das heisst im Prinzip, dass ich den Datensatz beliebig mit update() oder doUpdate() ändern kann ohne ich vorher von der Datenbank neu lesen zu müssen.&lt;br /&gt;&lt;br /&gt;Allerdings gibt es oft Probleme, wenn das ganze nicht in einer Datenbanktransaktion gehalten wird: U.u. wird der Datensatz nämlich in der Zwischenzeit verändert und das führt zu einer Ausnahme sobald update() oder doUpdate() die Änderung in die Datenbank schreiben soll:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Ein Datensatz in Debitoren (Tabellenname) kann nicht bearbeitet werden.&lt;br /&gt;Aktualisierungskonflikt, weil ein anderer Benutzerprozess den Datensatz gelöscht oder mindestens ein Feld im Datensatz geändert hat.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Deshalb sollte man solchen Code vermeiden:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Stattdessen sollte man ihn entweder so schreiben:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;ttsbegin;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Oder so:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;Table table;&lt;br /&gt;;&lt;br /&gt;table.KeyField = 'a';&lt;br /&gt;table.insert();&lt;br /&gt;&lt;br /&gt;// time consuming other code here&lt;br /&gt;&lt;br /&gt;ttsbegin;&lt;br /&gt;table.selectForUpdate(true);&lt;br /&gt;table.reread();&lt;br /&gt;table.AdditionalField = 'halli galli';&lt;br /&gt;table.update();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Je nach Anforderung ob der Datensatz in der Zwischenzeit verändert werden darf braucht es eine alles umfassende Datenbanktransaktion oder eben nicht.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-1464067810767231361?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/1464067810767231361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/forupdate-datensatz-nach-dem-einfugen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1464067810767231361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/1464067810767231361'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/forupdate-datensatz-nach-dem-einfugen.html' title='ForUpdate-Datensatz nach dem Einfügen eines Datensatzes'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-5486750626554784701</id><published>2010-05-02T20:48:00.001+02:00</published><updated>2010-05-03T19:52:33.281+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='CLR'/><title type='text'>Decode CLR Exception message</title><content type='html'>The ability to use .NET code inside X++ source code is a neat feature. If the native code brings limitations, you may can solve it with .NET code. Unfortunately the .NET framework exception messages in AX are very superficially.&lt;br /&gt;&lt;br /&gt;The following static method can be used to decode a .NET exception:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static void cRLExtendException(System.Exception _exception)&lt;br /&gt;{&lt;br /&gt;    System.Exception exception = _exception;&lt;br /&gt;    SysInfoLogStr infoLogStr;&lt;br /&gt;    ;&lt;br /&gt;    if (exception)&lt;br /&gt;    {&lt;br /&gt;        infoLogStr = exception.get_Message();&lt;br /&gt;        if (exception.Equals(exception.GetBaseException()))&lt;br /&gt;        {&lt;br /&gt;            // the most inner exception has reached, now we can write the infolog message and throw the exception&lt;br /&gt;            error(infoLogStr);&lt;br /&gt;            throw Exception::CLRError;&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            // the current exception is not the most inner exception, so we just set a infolog prefix&lt;br /&gt;            setprefix(infoLogStr);&lt;br /&gt;            MyClass::cRLExtendException(exception.get_InnerException());&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;    /* else&lt;br /&gt;    {&lt;br /&gt;        well, there was no CLR exception, so just left out&lt;br /&gt;    }&lt;br /&gt;    */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that's how to use it:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;System.String[] files;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    files = System.IO.Directory::GetFiles('c:\\halliGalli');&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;    MyClass::cRLExtendException(CLRInterop::getLastException());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now your infolog window will look like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.luegisdorf.ch/AX/clrmsg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="298" src="http://www.luegisdorf.ch/AX/clrmsg.png" tt="true" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In this case the auxiliary method is hosted on a class named 'MyClass'. Where the method should be implemented on your environment has to be decided by you or your team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-5486750626554784701?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/5486750626554784701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/decode-clr-exception-message.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5486750626554784701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5486750626554784701'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/05/decode-clr-exception-message.html' title='Decode CLR Exception message'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7478407997097992425</id><published>2010-04-26T12:39:00.001+02:00</published><updated>2010-05-03T19:52:21.048+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='CLR'/><title type='text'>CLR Fehlermeldungen aufschlüsseln</title><content type='html'>Die Einbindung von .NET-Code im X++ Sourcecode ist eine hübsche Sache. Was sich mit Native-Code nicht bewerkstelligen lässt, kann unter Umständen mit .NET-Code gelöst werden. Leider sind die Ausnahmen deren Ursprung dem .NET-Framework zuzuschreiben sind meist sehr oberflächlich gehalten.&lt;br /&gt;Folgende statischer Methode automatisiert das Aufschlüsseln der .NET-Ausnahme:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;static void cRLExtendException(System.Exception _exception)&lt;br /&gt;{&lt;br /&gt;    System.Exception exception = _exception;&lt;br /&gt;    SysInfoLogStr infoLogStr;&lt;br /&gt;    ;&lt;br /&gt;    if (exception)&lt;br /&gt;    {&lt;br /&gt;        infoLogStr = exception.get_Message();&lt;br /&gt;        if (exception.Equals(exception.GetBaseException()))&lt;br /&gt;        {&lt;br /&gt;            // the most inner exception has reached, now we can write the infolog message and throw the exception&lt;br /&gt;            error(infoLogStr);&lt;br /&gt;            throw Exception::CLRError;&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            // the current exception is not the most inner exception, so we just set a infolog prefix&lt;br /&gt;            setprefix(infoLogStr);&lt;br /&gt;            MyClass::cRLExtendException(exception.get_InnerException());&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;    /* else&lt;br /&gt;    {&lt;br /&gt;        well, there was no CLR exception, so just left out&lt;br /&gt;    }&lt;br /&gt;    */&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Und so wird die neue Hilfsmethode verwendet:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;System.String[] files;&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    files = System.IO.Directory::GetFiles('c:\\halliGalli');&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;    MyClass::cRLExtendException(CLRInterop::getLastException());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So sieht dann die Ausgabe des Infolog-Fensters aus:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.luegisdorf.ch/AX/clrmsg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="298" src="http://www.luegisdorf.ch/AX/clrmsg.png" tt="true" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In den Codebeispielen wurde die Hilfsmethode auf einer Klasse mit dem Namen 'MyClass' angelegt. Auf welcher Klasse schulssendlich die Methode implementiert wird, sollte aber der Entwickler, beziehungsweise das Entwicklerteam entscheiden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7478407997097992425?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7478407997097992425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/clr-fehlermeldungen-aufschlusseln.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7478407997097992425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7478407997097992425'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/clr-fehlermeldungen-aufschlusseln.html' title='CLR Fehlermeldungen aufschlüsseln'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-8663689337827143360</id><published>2010-04-12T20:00:00.001+02:00</published><updated>2010-04-12T20:00:55.324+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Communicate with the RunBase Dialog</title><content type='html'>Sometimes&amp;nbsp;you need to communicate with the&amp;nbsp;&lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object's dialog. Here are some information what you have to know to make it run well.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Caller&lt;/strong&gt;&lt;br /&gt;Say, your &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;&amp;nbsp;dialog calls a custom form which contains&amp;nbsp;special selection settings for the&amp;nbsp;&lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object&amp;nbsp;(which f.ex. cannot be integrated in the &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; dialog due layout specifications). So you've placed a m&lt;span style="color: black;"&gt;enu item button &lt;/span&gt;to your dialog. That way the user can call the custom form with the special selection settings:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;DialogRunbase ret;&lt;br /&gt;    ;&lt;br /&gt;    ret = super(dialog, forceOnClient);&lt;br /&gt;    ret.addMenuItemButton(MenuItemType::Display, menuItemDisplayStr(MyRunBaseSelectionForm));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But once the custom form is open, how to geht a handle to the &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object? To grab the &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object you need to&amp;nbsp;dig&amp;nbsp;the callers:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;FormRun         formRunCaller;&lt;br /&gt;    DialogRunBase   dialogRunBase;&lt;br /&gt;    MyRunBaseClass  caller;&lt;br /&gt;    ;&lt;br /&gt;    formRunCaller = element.args().caller(); // returns the dialog's form&lt;br /&gt;    dialogRunBase = formRunCaller.args().caller(); // returns a DialogRunBase object&lt;br /&gt;    caller = dialogRunBase.runBaseBatch(); // finally returns the RunBase object&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you have the handle to the &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object you can acceed all public parameter methods and even the &lt;span style="color: blue;"&gt;RunBase's QueryRun&lt;/span&gt; object.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Notify the caller&lt;/strong&gt;&lt;br /&gt;If the user decide to close your custom form with confirmation, so you need to&amp;nbsp;notify the &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt; object about the new data. The best way is to place this code in the method c&lt;em&gt;loseOK()&lt;/em&gt; on your custom form:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void closeOk()&lt;br /&gt;{&lt;br /&gt;    QueryRun qr = caller.queryRun();&lt;br /&gt;    ;&lt;br /&gt;    qr.whatEverYouHaveToManipulate(...);&lt;br /&gt;    caller.parmThisAndThat(...);&lt;br /&gt;    super();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Update the dialog values&lt;/strong&gt;&lt;br /&gt;As the user shall see the setting changes, you need to update the dialog controls. That for you can use the method&amp;nbsp;&lt;em&gt;dialogUpdate()&lt;/em&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void closeOk()&lt;br /&gt;{&lt;br /&gt;    QueryRun qr = caller.queryRun();&lt;br /&gt;    ;&lt;br /&gt;    qr.whatEverYouHaveToManipulate(...);&lt;br /&gt;    caller.parmThisAndThat(...);&lt;br /&gt;    caller.dialogUpdate(); // updates at least query range fields&lt;br /&gt;    super();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;If you want a little tutorial, you can download this &lt;a href="http://www.luegisdorf.ch/AX/PrivateProject_RunBaseDialogCommunication.xpo"&gt;sample&lt;/a&gt; project, demonstrates just what I tried to explain. Import the &lt;em&gt;XPO&lt;/em&gt; file&amp;nbsp;and open the class MyRunBaseClass, then click on the button "Pick customer".&lt;br /&gt;Keep in mind, it's only a tutorial, the code is&amp;nbsp;neither BP nor fool proofed!&lt;br /&gt;&lt;br /&gt;Hope this can improve your coding skills :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-8663689337827143360?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/8663689337827143360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/communicate-with-runbase-dialog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8663689337827143360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/8663689337827143360'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/communicate-with-runbase-dialog.html' title='Communicate with the RunBase Dialog'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-642686977687424365</id><published>2010-04-12T20:00:00.000+02:00</published><updated>2010-04-12T20:00:47.459+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Mit dem Dialog eines RunBase-Objektes kommunizieren</title><content type='html'>Manchmal ist es nötig mit dem Dialog eines &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekts zu kommunizieren. Nachstehend ein paar nützliche Informationen damit es auch gelingt.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;An den Aufrufer gelangen&lt;/strong&gt;&lt;br /&gt;Angenommen der &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Dialog ruft ein weiteres Formular auf, welches über spezielle Selektionseinstellungen für das &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekt verfügt (z.B. wenn die Darstellung dieser speziellen Einstellungen im &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Dialog nicht möglich ist). So wird dem Dialog also ein Menu-Item-Button hinzugefügt, damit der Benutzer das Formular mit den speziellen Einstellungsmöglichkeiten aufrufen kann:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;DialogRunbase ret;&lt;br /&gt;    ;&lt;br /&gt;    ret = super(dialog, forceOnClient);&lt;br /&gt;    ret.addMenuItemButton(MenuItemType::Display, menuItemDisplayStr(MyRunBaseSelectionForm));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wie erhält nun aber das Formular Zugriff auf das &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekt? Dafür muss durch die&amp;nbsp;Aufrufer 'gegraben' werden:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;FormRun         formRunCaller;&lt;br /&gt;    DialogRunBase   dialogRunBase;&lt;br /&gt;    MyRunBaseClass  caller;&lt;br /&gt;    ;&lt;br /&gt;    formRunCaller = element.args().caller(); // returns the dialog's form&lt;br /&gt;    dialogRunBase = formRunCaller.args().caller(); // returns a DialogRunBase object&lt;br /&gt;    caller = dialogRunBase.runBaseBatch(); // finally returns the RunBase object&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wenn man über das Handle des &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekts verfügt,&amp;nbsp;hat man Zugriff&amp;nbsp;auf alle öffentlichen Parametermethoden und auch&amp;nbsp;auf das&amp;nbsp;&lt;span style="color: blue;"&gt;QueryRun&lt;/span&gt;-Objekt des &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekts.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Den Aufrufer benachrichtigen&lt;/strong&gt;&lt;br /&gt;Wenn der Benutzer nun das Formular mit den speziellen Selektionskriterien mit OK schliesst, muss das &lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Objekt mit den allenfalls vorgenommenen Einstellungen aktualisiert werden. Am besten wird dies in der c&lt;em&gt;loseOK()&lt;/em&gt;-Methode auf dem Formular implementiert:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void closeOk()&lt;br /&gt;{&lt;br /&gt;    QueryRun qr = caller.queryRun();&lt;br /&gt;    ;&lt;br /&gt;    qr.whatEverYouHaveToManipulate(...);&lt;br /&gt;    caller.parmThisAndThat(...);&lt;br /&gt;    super();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Dialogfelder&amp;nbsp;aktualisieren&lt;/strong&gt;&lt;br /&gt;Damit der Benutzer die gemachten Änderungen&amp;nbsp;auf dem&amp;nbsp;&lt;span style="color: blue;"&gt;RunBase&lt;/span&gt;-Dialog sieht, müss zusätzlich die Dialogfelder aktualisiert werden, dies wird mit der Methode &lt;em&gt;dialogUpdate()&lt;/em&gt; sichergestellt:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin: 0px;"&gt;public void closeOk()&lt;br /&gt;{&lt;br /&gt;    QueryRun qr = caller.queryRun();&lt;br /&gt;    ;&lt;br /&gt;    qr.whatEverYouHaveToManipulate(...);&lt;br /&gt;    caller.parmThisAndThat(...);&lt;br /&gt;    caller.dialogUpdate(); // updates at least query range fields&lt;br /&gt;    super();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Ein kleines &lt;a href="http://www.luegisdorf.ch/AX/PrivateProject_RunBaseDialogCommunication.xpo"&gt;sample&lt;/a&gt;&amp;nbsp;steht als XPO-Datei&amp;nbsp;zum Download bereit und demonstriert, was ich hier zu erklären versucht war.&amp;nbsp;Nach dem&amp;nbsp;Importieren der &lt;em&gt;XPO-&lt;/em&gt;Datei einfach die Klasse MyRunBaseClass öffnen und auf die "Pick customer"-Schaltfläche drücken. &lt;br /&gt;Dieser Beispielcode wurde weder auf Optimale Verfahren geprüft, noch ist er gegen Fehler gefeit!&lt;br /&gt;&lt;br /&gt;Hoffe das dieser Beitrag&amp;nbsp;den Entwicklerhorizont ein klein wenig erweitert :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-642686977687424365?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/642686977687424365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/mit-dem-dialog-eines-runbase-objektes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/642686977687424365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/642686977687424365'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/04/mit-dem-dialog-eines-runbase-objektes.html' title='Mit dem Dialog eines RunBase-Objektes kommunizieren'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-3139436059982079155</id><published>2010-03-22T20:30:00.000+01:00</published><updated>2010-03-22T20:30:10.390+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Die firstonly-Falle</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Dies ist eine Übersetzung des englischsprachingen Beitrags&amp;nbsp;&lt;/span&gt;&lt;a href="http://axatluegisdorf.blogspot.com/2010/03/firstonly-trap.html"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;the firstonly trap&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Die Verwendung des&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Firstonly-&lt;/span&gt;Qualifizierer in einem X++ Select Statement kann die Ausführungsgeschwindigkeit erheblich steigern. Also warum den&amp;nbsp;Qualifizierer&amp;nbsp;nicht auch für&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&lt;/span&gt;&amp;nbsp;und&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;delete_from&amp;nbsp;&lt;/span&gt;anwenden? Das war meine Idee und so begann ich folgenden Code umzuschreiben:&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;ttsbegin;&lt;br /&gt;select firstonly forupdate myTable where myTable.NotUniqueField == 'anyValue';&lt;br /&gt;myTable.delete();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;nach&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;delete_from firstonly myTable where myTable.NotUniqueField == 'anyValue';&lt;br /&gt;&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Leider entsprach das Resultat nicht den Erwartungen. Alle Datensätze die mit den&amp;nbsp;Abfragekriterien&amp;nbsp;übereinstimmten wurden gelöscht. Zuerst dache ich,&lt;span class="Apple-style-span" style="color: blue;"&gt; delete_from firstonly&lt;/span&gt; leide an der gleichen Ungenauigkeit wie &lt;span class="Apple-style-span" style="color: blue;"&gt;select firstonly&amp;nbsp;&lt;span class="Apple-style-span" style="color: black;"&gt;und deshalb sei nicht sichergestellt, dass immer nur ein Datensatz verarbeitet würde. Aber in Wirklichkeit sieht es eher so aus, dass der&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Firstonly-&lt;/span&gt;Qualifizierer weder&amp;nbsp;für&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&amp;nbsp;&lt;/span&gt;noch für&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;delete_from &lt;/span&gt;implementiert wurde (auch wenn der X++ Kompiler es akzeptiert).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Andrerseits, T-SQL bietet die Möglichkeit das &lt;span class="Apple-style-span" style="color: blue;"&gt;TOP&lt;/span&gt;-Schlüsselwort in &lt;span class="Apple-style-span" style="color: blue;"&gt;Select&lt;/span&gt;-, &lt;span class="Apple-style-span" style="color: blue;"&gt;Update&lt;/span&gt;- und auch &lt;span class="Apple-style-span" style="color: blue;"&gt;Delete&lt;/span&gt;-Anweisungen zu verwenden - und warum sollte der Kompiler schlucken was keinen Sinn macht? Ich könnte mir vorstellen, dass diese Funktionalität in späteren Versionen zur Verfügung steht. Ich werden den&amp;nbsp;F&lt;span class="Apple-style-span" style="color: blue;"&gt;irstonly-&lt;/span&gt;Qualifizierer weiterhin gebrauchen, aber nur wenn die&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Where-&lt;/span&gt;Kriterien einen eindeutigen Datensatz referenzieren.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;delete_from firstonly myTable where myTable.UniqueField == 'keyValue';&lt;br /&gt;// and&lt;br /&gt;update_recordset firstonly myTable setting AnyField = 'anyValue' where myTable.UniqueField == 'keyValue';&lt;br /&gt;&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Vielleicht wird Code von heute auch in späteren AX-Versionen verwendet, wenn&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&amp;nbsp;&lt;/span&gt;und d&lt;span class="Apple-style-span" style="color: blue;"&gt;elete_from&lt;/span&gt;&amp;nbsp;den&lt;span class="Apple-style-span" style="color: blue;"&gt;&amp;nbsp;Firstonly-&lt;/span&gt;Qualifizierer&amp;nbsp;unterstützen. Ausserdem finde ich, dass es das Lesen des Codes ein wenig erleichtert.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Also tappt nicht auch in diese Falle ;)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-3139436059982079155?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/3139436059982079155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/die-firstonly-falle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3139436059982079155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/3139436059982079155'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/die-firstonly-falle.html' title='Die firstonly-Falle'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7013897296555794477</id><published>2010-03-22T20:05:00.000+01:00</published><updated>2010-03-22T20:05:18.991+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>The firstonly trap</title><content type='html'>Using the &lt;span class="Apple-style-span" style="color: blue;"&gt;firstonly &lt;/span&gt;qualifier on a X++ Select Statement can increase speed performance. So why don't use it for &lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset&lt;/span&gt; and &lt;span class="Apple-style-span" style="color: blue;"&gt;delete_from &lt;/span&gt;too? This was my Idea and I was going on to rewrite this code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;ttsbegin;&lt;br /&gt;select firstonly forupdate myTable where myTable.NotUniqueField == 'anyValue';&lt;br /&gt;myTable.delete();&lt;br /&gt;ttscommit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;into that&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;delete_from firstonly myTable where myTable.NotUniqueField == 'anyValue';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, the result was not as expected: All records which matched the condition were lost. First I&amp;nbsp;thought&amp;nbsp;the problem was, that a &lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;delete_from&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt; firstonly&lt;/span&gt; has the same inaccuracy as a&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;select firstonly&lt;/span&gt; and therefore it wouldn't be granted to proceed only one record. But actually it seems that the &lt;span class="Apple-style-span" style="color: blue;"&gt;firstonly&lt;/span&gt; qualifier is neither implemented for &lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset &lt;/span&gt;nor for&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;delete_from&amp;nbsp;&lt;/span&gt;(even the X++ compiler accept it).&lt;br /&gt;&lt;br /&gt;On the other hand, T-SQL provides the &lt;span class="Apple-style-span" style="color: blue;"&gt;TOP &lt;/span&gt;clause in &lt;span class="Apple-style-span" style="color: blue;"&gt;select&lt;/span&gt;, &lt;span class="Apple-style-span" style="color: blue;"&gt;update &lt;/span&gt;and &lt;span class="Apple-style-span" style="color: blue;"&gt;delete &lt;/span&gt;statement too - and why the compiler should swallow it, even it makes no sense? I could imagine, that this features will be implemented in later versions. I will use the &lt;span class="Apple-style-span" style="color: blue;"&gt;firstonly &lt;/span&gt;qualifier again, but only if the&lt;span class="Apple-style-span" style="color: blue;"&gt; where &lt;/span&gt;conditions refers a unique record.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;delete_from firstonly myTable where myTable.UniqueField == 'keyValue';&lt;br /&gt;// and&lt;br /&gt;update_recordset firstonly myTable setting AnyField = 'anyValue' where myTable.UniqueField == 'keyValue';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;May be, code from today is still active in later AX versions, when &lt;span class="Apple-style-span" style="color: blue;"&gt;update_recordset &lt;/span&gt;and d&lt;span class="Apple-style-span" style="color: blue;"&gt;elete_from&lt;/span&gt; are supporting the&lt;span class="Apple-style-span" style="color: blue;"&gt; firstonly&lt;/span&gt; qualifier. Further I like it as a hint when reading and try to understand source code.&lt;br /&gt;&lt;br /&gt;So be warned to fall into that trap :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7013897296555794477?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7013897296555794477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/firstonly-trap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7013897296555794477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7013897296555794477'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/firstonly-trap.html' title='The firstonly trap'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-6335569351934481772</id><published>2010-03-08T19:12:00.000+01:00</published><updated>2010-03-08T19:12:20.870+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Einfacher X++ Taschenrechner</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Vielen Lesern dürfte die Rechenfunktion des Steuerlements vom Typ FormRealControl bekannt sein. Falls nicht, hier eine kleine Einführung: Wenn man in einem Feld vom Typ Gleitkommazahl eine komplette Kalkulation eintippt (Abb. a) und anschliessend die Eingabe bestätigt, wird dem Feld der ausgerechnete Wert zugewiesen (Abb. b).&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s1600-h/Enter1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s320/Enter1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;i&gt;Abb. a:&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S5U2i9pOXoI/AAAAAAAAADQ/EOYfxlpvv_M/s1600-h/Enter2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S5U2i9pOXoI/AAAAAAAAADQ/EOYfxlpvv_M/s320/Enter2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;i&gt;Abb. b:&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;So dachte ich, den Nutzen dieses Features dürfte auch durch x++ möglich sein. Das Resultat war schlussendlich eine statische Methode zum Auswerten von Kalkulationen.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;So sieht die statische Methode aus:&lt;/div&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Calculates a simple math task&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="_expression"&amp;gt;&lt;br /&gt;/// A simple mathematic expression. +-/* operators and brackets can be used&lt;br /&gt;/// &amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;&lt;br /&gt;/// The calculated result. If the expression does not match the expected format, &lt;br /&gt;zero is returned.&lt;br /&gt;/// &amp;lt;/returns&amp;gt;&lt;br /&gt;/// &amp;lt;remarks&amp;gt;&lt;br /&gt;/// Uses functionality from &amp;lt;c&amp;gt;FormRealControl&amp;lt;/c&amp;gt;, therefore client execution &lt;br /&gt;is required.&lt;br /&gt;/// &amp;lt;/remarks&amp;gt;&lt;br /&gt;static client real calcExpression(str _expression)&lt;br /&gt;{&lt;br /&gt;    SysFormRun formRun;&lt;br /&gt;    Args args = new Args();&lt;br /&gt;    FormBuildControl buildCtrl;&lt;br /&gt;    FormRealControl realCtrl;&lt;br /&gt;    &lt;br /&gt;    ;&lt;br /&gt;    args.name(formstr(Dialog));&lt;br /&gt;    formRun = classFactory.formRunClass(args);&lt;br /&gt;    &lt;br /&gt;    buildCtrl = formRun.form().design().addControl(FormControlType::Real, &lt;br /&gt;    classstr(FormRealControl));&lt;br /&gt;    formRun.init();&lt;br /&gt;    realCtrl = formRun.design().control(buildCtrl.id());&lt;br /&gt;    realCtrl.pasteText(_expression);&lt;br /&gt;    return realCtrl.realValue();&lt;br /&gt;}&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Und so kann sie verwendet werden:&lt;/div&gt;&lt;pre class="brush: c-sharp;" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;info(strfmt('%1', MyClass::calcExpression('5+(5*2)')));&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Als Anmerkung bleibt zu sagen, dass die Funktion über alle Einschränkungen verfügt, über die auch das Rechen-Feature des FormRealControl-Objekt verfügt.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-6335569351934481772?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/6335569351934481772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/einfacher-x-taschenrechner.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6335569351934481772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/6335569351934481772'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/einfacher-x-taschenrechner.html' title='Einfacher X++ Taschenrechner'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s72-c/Enter1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7362276875067556962</id><published>2010-03-08T18:59:00.000+01:00</published><updated>2010-03-08T18:59:36.631+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>Simple x++ Calculator</title><content type='html'>May be you know the AX GUI calculator of the FormRealControl. If not, I will explain in a short way: If you enter a proper calculation expression in a real field (picture a) and commit the input expression will be calculated and the result set to the field (picture b).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s1600-h/Enter1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s320/Enter1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;picture a:&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S5U2i9pOXoI/AAAAAAAAADQ/EOYfxlpvv_M/s1600-h/Enter2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S5U2i9pOXoI/AAAAAAAAADQ/EOYfxlpvv_M/s320/Enter2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;picture b:&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;So I found this functionality can also be used trough x++. The result was a static method which can evaluate an expression to be calculated.&lt;br /&gt;&lt;br /&gt;That's the code behind:&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Calculates a simple math task&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="_expression"&amp;gt;&lt;br /&gt;/// A simple mathematic expression. +-/* operators and brackets can be used&lt;br /&gt;/// &amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;&lt;br /&gt;/// The calculated result. If the expression does not match the expected format, &lt;br /&gt;zero is returned.&lt;br /&gt;/// &amp;lt;/returns&amp;gt;&lt;br /&gt;/// &amp;lt;remarks&amp;gt;&lt;br /&gt;/// Uses functionality from &amp;lt;c&amp;gt;FormRealControl&amp;lt;/c&amp;gt;, therefore client execution &lt;br /&gt;is required.&lt;br /&gt;/// &amp;lt;/remarks&amp;gt;&lt;br /&gt;static client real calcExpression(str _expression)&lt;br /&gt;{&lt;br /&gt;    SysFormRun formRun;&lt;br /&gt;    Args args = new Args();&lt;br /&gt;    FormBuildControl buildCtrl;&lt;br /&gt;    FormRealControl realCtrl;&lt;br /&gt;    &lt;br /&gt;    ;&lt;br /&gt;    args.name(formstr(Dialog));&lt;br /&gt;    formRun = classFactory.formRunClass(args);&lt;br /&gt;    &lt;br /&gt;    buildCtrl = formRun.form().design().addControl(FormControlType::Real, &lt;br /&gt;    classstr(FormRealControl));&lt;br /&gt;    formRun.init();&lt;br /&gt;    realCtrl = formRun.design().control(buildCtrl.id());&lt;br /&gt;    realCtrl.pasteText(_expression);&lt;br /&gt;    return realCtrl.realValue();&lt;br /&gt;}&lt;/pre&gt;And that's how we use it:&lt;br /&gt;&lt;pre class="brush: c-sharp;"&gt;info(strfmt('%1', MyClass::calcExpression('5+(5*2)')));&lt;/pre&gt;&lt;br /&gt;Keep in mind, this function inherits all limits which the FormRealControl calculation feature owns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7362276875067556962?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7362276875067556962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/simple-x-calculator.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7362276875067556962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7362276875067556962'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/03/simple-x-calculator.html' title='Simple x++ Calculator'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_dKaxGw6aZCc/S5U2bAhUD9I/AAAAAAAAADI/x2MJKfx63j4/s72-c/Enter1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-2299154260587012568</id><published>2010-02-20T10:22:00.000+01:00</published><updated>2010-02-20T10:22:56.179+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>SmartStart 3000 V 1.6 for Dynamics AX</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;This Article is an announcement about the new Version of &lt;b&gt;SmartStart 3000&lt;/b&gt;. You don't know what the&amp;nbsp;SmartStart 3000 is? It's a free configuration manager for Dynamics AX. If you are working with more than just one AX configuration, this tool can make your life easier. A Full feature list can be found on the&amp;nbsp;&lt;a href="http://www.smartstart3000.luegisdorf.ch/"&gt;SmartStart 3000 Central&lt;/a&gt;&amp;nbsp;web page.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;About the new Version 1.6&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;It tooks some extra time to publish the new release (or even more time than I tought it would take :).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;What's new?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Support for Business Connector configurations&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Possibility to switch current/default configuration (for Client and BC configurations as well)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Source filter&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Extended export functionality&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Quick access button for custom tools/shortcuts&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Auto remove for invalid favorites&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Configuration drag'n'drop-to-target possibility for deletion and export&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;When deleting registry based configurations, they will collected in recycle bin as registry export files (so you can restore them if needed)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Global keyboard shortcut for application lookup&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;b&gt;Bugfixes&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Fixed favorite storage (AX version is now included, file storage fixed)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Fixed registry export (even the configurations work proper for Dynamics AX Client, user was not able to edit them in the Dynamics AX 2009 Configuration Utility)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Fixed unexpected flash flare on start up phase&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Prohibition of deleting original, installed configurations&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;Language support&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Refreshed language support for the following tongues:&amp;nbsp;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-size: 12px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Czech, Danish, German, English, Spanish, French, Norwegian, Polish and Swedish. A great thank-you for the dedicated translators!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;b&gt;Documentation&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;The PDF documentations is updated to the new V 1.6 functionality and shipped with inside the application and also downloadable from the Central web page&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;b&gt;Remarks&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;Due the fixed favorite storage process, all favorites will be cleared when running V 1.6 first time&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;SmartStart 3000 Argument Configurator&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;The online &lt;a href="http://www.luegisdorf.ch/smartStart3000ArgumentConfigurator.php"&gt;Argument Configurator&lt;/a&gt; has been extended with preview windows&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;Known Issues&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;When using SmartStart 3000 on terminal servers with very low color settings (due slow connection), SmartStart 3000 wont start up. In this case, just use the parameter &lt;i&gt;/noGDI&lt;/i&gt;. I'm working to fix that bug, but currently I haven't located the bug source.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;b&gt;Download&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Download the new release as usual at:&amp;nbsp;&lt;a href="http://www.smartstart3000.luegisdorf.ch/"&gt;SmartStart 3000 Central&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Next week I'm out of office, but I'm looking forward to get your feedback!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-2299154260587012568?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/2299154260587012568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/02/smartstart-3000-v-16-for-dynamics-ax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2299154260587012568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2299154260587012568'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/02/smartstart-3000-v-16-for-dynamics-ax.html' title='SmartStart 3000 V 1.6 for Dynamics AX'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-951115331318088869</id><published>2010-01-29T19:10:00.000+01:00</published><updated>2010-01-29T19:10:11.342+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='Reflection'/><title type='text'>Wie man die Modifier Private, Protected und Abstract umgeht</title><content type='html'>&lt;span style="font-size: x-small;"&gt;Auf Wunsch der Leserschaft werden meine Beiträge nun auch in deutscher Sprache veröffentlicht. Dieser Post bezieht sich auf den englischsprachigen Post&amp;nbsp;&lt;/span&gt;&lt;a href="http://axatluegisdorf.blogspot.com/2009/12/how-to-ignore-private-protected-and.html"&gt;&lt;span style="font-size: x-small;"&gt;How to ignore Private, Protected and Abstract&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;modifiers.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bisher habe ich mich immer über die Meldungen "Statisches Konstrukt implementieren, um Änderungen zu ermöglichen." und "'New' muss den Status 'protected' aufweisen." gewundert.&lt;br /&gt;&lt;br /&gt;Sagen wir, wir möchten eine neue Verarbeitung mit einer RunBaseBatch-Klasse realisieren: Wenn wir nun den Optimalen Verfahren folgen, werden wir folglich die &lt;i&gt;new()&lt;/i&gt;-Methode &lt;i&gt;Protected &lt;/i&gt;deklarieren. Aber wie soll nun das Framework der Stapelverarbeitung jemals ein Objekt aus dieser Klasse erstellen, sollte der Benutzer die Verarbeitung in den Stapel stellen?&lt;br /&gt;&lt;br /&gt;Weil die &lt;i&gt;new()&lt;/i&gt;-Methode ja nun mit dem Modifier &lt;i&gt;Protected &lt;/i&gt;geschützt ist, kann aus der Klasse kein Objekt mit &lt;i&gt;new()&lt;/i&gt; erstellt werden, richtig?&lt;br /&gt;Theoretisch ja, allerdings hat man da die Rechnung ohne die Möglichkeiten der Reflection-Technik in AX gemacht.&lt;br /&gt;&lt;br /&gt;Wie im Allgemeinen bekannt, ist es möglich mit dem Kernelobjekt vom Typ &lt;i&gt;DictClass&lt;/i&gt; (oder mit dem vielleicht besser bekannten abgeleiteten Typ &lt;i&gt;SysDictClass&lt;/i&gt;) dynamisch Objekte zu erstellen und Objektmethoden aufzurufen. Nach ein paar Tests hat sich herausgestellt, dass das &lt;i&gt;DictClass &lt;/i&gt;Objekt seinen ganz eigenen Regeln folgt, wenn es um die Möglichkeiten der Codeverarbeitung geht.&lt;br /&gt;&lt;br /&gt;Mit einem &lt;i&gt;DictClass&lt;/i&gt;-Objekt kann man Objekte aus Klassen erstellen, die dafür gar nicht geeignet sind. So kann man mit der &lt;i&gt;makeObject()&lt;/i&gt;-Methode:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Objekte aus abstrakten Klassen erzeugen&amp;nbsp;&lt;/li&gt;&lt;li&gt;Objekte erstellen auch wenn die &lt;i&gt;new()&lt;/i&gt;-Methode &lt;i&gt;Private &lt;/i&gt;oder &lt;i&gt;Protected &lt;/i&gt;deklariert ist (die &lt;i&gt;new()&lt;/i&gt;-Methode wird dann auch wirklich durchlaufen)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Objekte erstellen, auch wenn die jeweilige Klasse nicht alle abstrakten Methoden überschrieben hat&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;Aber die Möglichkeiten mit dem &lt;i&gt;DictClass&lt;/i&gt;-Objekt enden nicht einfach damit verbotene Objekte zu erstellen. Es ist auch möglich:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Member- und statische Methoden ungeachtet der Modifier &lt;i&gt;protected&lt;/i&gt;, &lt;i&gt;private &lt;/i&gt;oder &lt;i&gt;abstract &lt;/i&gt;aufzurufen (mit &lt;i&gt;callObject()&lt;/i&gt; und &lt;i&gt;callStatic()&lt;/i&gt;)&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Als wäre das nun nicht schon genug der Blasphemie: das &lt;i&gt;DictTable&lt;/i&gt;-Objekt verfügt ebenfalls über diese Verhaltenseigenschaften. Mit c&lt;i&gt;allStatic()&lt;/i&gt; und &lt;i&gt;callObject()&lt;/i&gt; des&lt;i&gt; DictTable&lt;/i&gt;-Objektes kann jede beliebige Tabellenmethode aufgerufen werden.&lt;br /&gt;&lt;br /&gt;Fazit: In AX existieren&amp;nbsp;zwar hässliche, aber&amp;nbsp;äusserst effektive&amp;nbsp;Verfahren um Codesicherheit und Kompilerprüfungen zu umgehen. Auch wenn es möglich ist, diese Tricks einzusetzen, rate ich &lt;b&gt;dringend &lt;/b&gt;davon ab. Dieser Artikel soll nur zeigen was möglich ist, das heisst aber nicht, dass es auch sinnvoll ist.&lt;br /&gt;&lt;br /&gt;(Inhalt bezieht sich auf AX 2009)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-951115331318088869?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/951115331318088869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2009/12/wie-man-die-modifier-private-protected.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/951115331318088869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/951115331318088869'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2009/12/wie-man-die-modifier-private-protected.html' title='Wie man die Modifier Private, Protected und Abstract umgeht'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-5159678961678685970</id><published>2010-01-29T19:09:00.000+01:00</published><updated>2010-01-29T19:09:30.926+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><title type='text'>TypeId from table field</title><content type='html'>How to retrieve the typeId by a given FieldId?&amp;nbsp;I didn't found&amp;nbsp;a method doing this&amp;nbsp;in AX,&amp;nbsp;so I wrote it by my self:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; fieldId2TypeId(TableId _tableId, FieldId _fieldId)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DictField dictField = &lt;span style="color: blue;"&gt;new&lt;/span&gt; DictField(_tableId, _fieldId);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; ret; // 32 bit length type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (dictField.typeId())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // extended type is given&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = dictField.typeId(); &lt;span style="color: #274e13;"&gt;// dictField.typeId() is an int 16 range value&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else if&lt;/span&gt; (dictField.enumId())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // enum type is given&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = dictField.enumId(); &lt;span style="color: #274e13;"&gt;// dictField.enumId() is an int 16 range value&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = ret&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&amp;lt;&lt;/span&gt; 16;&lt;span style="color: #274e13;"&gt; // move enum or exteneded type information to left side 16 bit area&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = dictField.type() | ret; &lt;span style="color: #274e13;"&gt;// combine left side 16 bits from typeId information with right side 16 bits from enum or extended type information&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; ret;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-5159678961678685970?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/5159678961678685970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/typeid-from-table-field.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5159678961678685970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5159678961678685970'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/typeid-from-table-field.html' title='TypeId from table field'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-5641837839967805825</id><published>2010-01-13T20:22:00.005+01:00</published><updated>2010-01-19T14:09:06.541+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Labels'/><title type='text'>Import and Export Labels for external translations</title><content type='html'>When working in international and multi language environment, often situation comes where you have a label file (&lt;span style="color: blue;"&gt;*.ald&lt;/span&gt;) and you should extract the labels for transfer to translation office. After, you have to create a new label file with the translated data from the translation office retrieved.&lt;br /&gt;&lt;br /&gt;To make that process more handy, I have created an export and import routine to do the import and the export from and to an excel file.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to install&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Download and import the&lt;a href="http://www.luegisdorf.ch/AX/PrivateProject_Label.xpo"&gt; XPO&lt;/a&gt;&amp;nbsp;file from here.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How to use it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open Menu &lt;span style="color: blue;"&gt;Microsoft Dynamics AX\Tools\Development tools\Label\Excel&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Choose &lt;span style="color: blue;"&gt;Dump &lt;/span&gt;(for export) or &lt;span style="color: blue;"&gt;Load &lt;/span&gt;(for import)&lt;/li&gt;&lt;li&gt;Or open from &lt;span style="color: blue;"&gt;AOT\MenuItems\Action&lt;/span&gt; the item &lt;span style="color: blue;"&gt;Dev_LabelFileToExcel&lt;/span&gt; or the item&amp;nbsp;&lt;span style="color: blue;"&gt;Dev_LabelFileFromExcel&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Exportation of Labels&lt;/span&gt;&lt;br /&gt;&lt;div align="center" class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dKaxGw6aZCc/S04TfL39LOI/AAAAAAAAAC4/PKYyUFrj94s/s1600-h/Export.png" imageanchor="1" style="cssfloat: left; margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dKaxGw6aZCc/S04TfL39LOI/AAAAAAAAAC4/PKYyUFrj94s/s400/Export.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;You can export into an Excel file from scratch or in an Excel file which was exported and translated before; template and translation labels will be read from source and written into Excel file. But if the template label expression given by Excel file (in case you select one) is not corresponding to the template expression that comes along the source, the translation expression is put just idle to Excel file so the translation office can translate it again (means: the expression has changed since last time export).&lt;br /&gt;&lt;/div&gt;First time exportation should always be done with option &lt;span style="color: blue;"&gt;Recreate file&lt;/span&gt;.&lt;br /&gt;The source can either be the current *.ald files given by application you are working on, or from a user defined application directory (or copy of). Keep in mind that you probably have to restart the AOS to ensure the label files are up to date.&lt;br /&gt;If you choose option &lt;span style="color: blue;"&gt;File System Directory (Server/AOS)&lt;/span&gt;, your client does not need file access to the application folder, the server will read the files.&lt;br /&gt;The process will finish with a display of the modified/created Excel file. All orange fields has now to be translated.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Importation of labels&lt;/i&gt;&lt;br /&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S04Wo5jRxgI/AAAAAAAAADA/a_WT_hu-vgo/s400/Import.png" /&gt;&lt;br /&gt;&lt;br /&gt;Choose the Excel file where the translated table are stored. The structure must correspond to the Excel file which was exported (otherwise the import will fail).&lt;br /&gt;Choose the directory where an *.ald label file should be created. Don't specify an application directory where an running AOS is accessing (otherwise you can get strange display effects in application, data access violations and label file loose). If a label file for the given translation language is already present, it will be replaced.&lt;br /&gt;&lt;br /&gt;Hope this tool makes your live with AX easier as did for me.&lt;br /&gt;&lt;br /&gt;It works in AX 2009 with Office 2007 (may be it works for AX 4.0 and Office 2003 as well)&lt;br /&gt;This post will not be translated into German, since it's not very hard to understand this tool ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-5641837839967805825?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/5641837839967805825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/import-and-export-labels-for-external.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5641837839967805825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/5641837839967805825'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/import-and-export-labels-for-external.html' title='Import and Export Labels for external translations'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dKaxGw6aZCc/S04TfL39LOI/AAAAAAAAAC4/PKYyUFrj94s/s72-c/Export.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7789524750374610447</id><published>2010-01-08T14:15:00.001+01:00</published><updated>2010-01-08T17:43:46.040+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Add-In'/><title type='text'>Add-In Extension: Create default methods for classes</title><content type='html'>May be you know the Add-In for&amp;nbsp;automated creation of&amp;nbsp;&lt;em&gt;find(..) &lt;/em&gt;&amp;amp; &lt;em&gt;exists(..)&lt;/em&gt; method for tables&amp;nbsp;provided&amp;nbsp;by &lt;a href="http://www.axaptapedia.com/Create_Standard_Methods_Extension"&gt;Axaptapedia&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Well, I have created a similar Add-In for classes. The goal of that Add-In is the same as the &lt;em&gt;find(..) &amp;amp; exists(..)&lt;/em&gt; Add-In, to speed up code implementation.&lt;br /&gt;&lt;br /&gt;What's the functionality?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It creates required abstract and interface methods&lt;/li&gt;&lt;li&gt;If the class is not abstract,&amp;nbsp;a&amp;nbsp;&lt;em&gt;protected new(..)&lt;/em&gt; and a static&lt;em&gt; construct(..)&lt;/em&gt; constructor will be created&lt;/li&gt;&lt;li&gt;If&amp;nbsp;the class&amp;nbsp;is in the RunBase tree, a&amp;nbsp;static &lt;em&gt;main(..)&lt;/em&gt; method is created&lt;/li&gt;&lt;li&gt;Already created methods will not be&amp;nbsp;touched&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;How to install:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Import this &lt;a href="http://www.luegisdorf.ch/AX/PrivateProject_Dev_CreateDefClsMeths.xpo"&gt;XPO&lt;/a&gt; containing&amp;nbsp;a private project with&amp;nbsp;a class and a menu item.&lt;/li&gt;&lt;li&gt;Add the menu Item to the &lt;span style="color: #b45f06;"&gt;menu&lt;/span&gt; &lt;em&gt;SysContextMenu&lt;/em&gt; (you can decide on what position)&lt;/li&gt;&lt;li&gt;Add a the code below to the &lt;span style="color: #b45f06;"&gt;class method&lt;/span&gt; &lt;em&gt;SysContextMenu/verifyItem&lt;/em&gt; before line 217 (&lt;em&gt;switch menuItem&lt;/em&gt;) &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: blue;"&gt;menuItemActionStr&lt;/span&gt;(&lt;strong&gt;DEV_CreateDefClsMeths&lt;/strong&gt;):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; ! docNode &amp;amp;&amp;amp; _firstType == UtilElementType::Class; &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Courier New;"&gt;I&lt;/span&gt;n AOT, select a class and open context menu/Add-Ins. You will see now the new entry named &lt;em&gt;Create default class methods&lt;/em&gt;. Klick it to process.&lt;/li&gt;&lt;/ul&gt;Tip: place the modification on a private layer (a layer which is used internally only): it's not really customer related, so you don't have to deliver it to them.&lt;br /&gt;&lt;br /&gt;It works in AX 2009.&amp;nbsp;Not tested&amp;nbsp;for AX 4.0&lt;br /&gt;&lt;br /&gt;(this article is available in English only)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7789524750374610447?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7789524750374610447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/add-in-extension-create-default-methods.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7789524750374610447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7789524750374610447'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/add-in-extension-create-default-methods.html' title='Add-In Extension: Create default methods for classes'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7349186445069837907</id><published>2010-01-06T20:21:00.001+01:00</published><updated>2010-01-07T07:36:27.127+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client/Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Temporary Tables'/><title type='text'>Join-Queries mit temporären Tabellen (und es funktioniert eben doch)</title><content type='html'>Join-Queries mit temporären Tabellen (und es funktioniert eben doch)&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Dieser Beitrag bezieht sich auf den englischsprachigen Artikel &lt;/span&gt;&lt;a href="http://axatluegisdorf.blogspot.com/2010/01/join-queries-with-temporary-tables.html"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Queries with temporary tables (nevertheless it works)&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Die Verwendung von temporären Tabellen innerhalb Queries kann ab und an zu Problemen führen; im Speziellen, wenn man die Fehlermeldung &lt;span style="color: blue;"&gt;"Ein Datensatz in % (%) kann nicht ausgewählt werden. Temporäre Tabellen müssen bei Verknüpfung mit persistenten Tabellen äußere Tabellen sein."&lt;/span&gt; erhält. Ein Arbeitskollege hat allerdings eine solche Query zu meinem Erstaunen trotzdem zum Laufen gebracht. Auf der Grundlage seiner Vorarbeit habe ich das Thema mal genauer untersucht.&lt;br /&gt;&lt;br /&gt;Die Inhaltsgrundlage dieses Beitrages basiert auf dem Wissen durchgeführten Tests. Die Funktionsweise von Queries mit temporären Tabellen wird hier allein durch Beobachtungen erklärt (auch wenn AX vielleicht anders als angenommen arbeitet).&lt;br /&gt;&lt;br /&gt;Der genannte Fehler wird ausgelöst wenn die Datenselektion der jeweiligen Datenquelle nicht auf dem gleichen Tier ausgeführt wird, wie die übergeordnete (parent) Datenquelle. Die erste Datenquelle nimmt allerdings eine Sonderstellung ein. Die Datenquellen werden nämlich auf dem Tier abgearbeitet wo sich der Datenpuffer der Datenquelle befindet. Hat aber der Server-Tier einmal mit der Abarbeitung einer Datenquelle begonnen, kann für die weitere Datenselektion nicht mehr zurück auf den Client-Tier gewechselt werden.&lt;br /&gt;&lt;br /&gt;Unter Beachtung einiger Regeln steht für eine Join-Query mit temporären Tabellen aber absolut nichts im Wege. Es gilt zu beachten:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Persistente Tabellen werden stets auf dem Server-Tier verarbeitet&lt;/li&gt;&lt;li&gt;Temporäre Tabellen werden auf dem Tier verarbeitet, auf den das Handle der Tabelle hinzeigt&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Temporäre Tabellen, die üblicherweise persistent sind, aber mit der &lt;i&gt;setTmp()&lt;/i&gt;-Methode zur Laufzeit temporär gestellt werden, werden auf dem Tier gehalten, wo die s&lt;i&gt;etTmp()&lt;/i&gt;-Methode angewendet wird&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;CustTable&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;custTable&lt;br /&gt;;&lt;br /&gt;custTable.setTmp(); &lt;span style="color: #38761d;"&gt;// now the handle will fixed on the current tier&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="color: #38761d;"&gt;&lt;/span&gt;&lt;/span&gt;Temporäre Tabellen welche bereits auch als solche im AOT definiert sind, werden dort gehalten wo sich auch die Deklaration befindet&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;TmpSysQuery&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;tmpSysQuery; &lt;span style="color: #38761d;"&gt;// the handle is already fixed on the current tier&lt;/span&gt;&lt;br /&gt;;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Die erste Datenquelle in der Query kann ihren Datenpuffer wahlweise vom Client- oder Server-Tier beziehen&lt;/li&gt;&lt;li&gt;Alle weiteren, und somit eingebetteten Datenquellen müssen ihren Datenpuffer entweder auf dem gleichen Tier wie ihre übergeordnete (parent) Datenquelle oder aber auf dem Server-Tier halten&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Folgende Konstellationen sind demnach möglich oder eben nicht (einige Beispiele):&lt;br /&gt;(&lt;a href="http://axatluegisdorf.blogspot.com/2010/01/join-queries-with-temporary-tables.html"&gt;Siehe englischer Artike&lt;/a&gt;l)&lt;br /&gt;&lt;br /&gt;Fazit: Die Meldung &lt;span style="color: blue;"&gt;"Ein Datensatz in % (%) kann nicht ausgewählt werden. Temporäre Tabellen müssen bei Verknüpfung mit persistenten Tabellen äußere Tabellen sein." &lt;/span&gt;würde wohl besser heissen:&lt;span style="color: #38761d;"&gt; "Temporäre Datenquelle % bezieht Daten nicht aus dem gleichen Tier wie die übergeordnete Datenquelle % noch vom Server-Tier selbst."&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Hier noch ein paar allgemeine Anmerkungen zur Verwendung der &lt;i&gt;setTmp()&lt;/i&gt;-Methode für persistente Tabellen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Die &lt;i&gt;setTmp()&lt;/i&gt;-Methode muss immer in derselben Methode wie die Deklaration der Tabelle erfolgen&lt;/li&gt;&lt;li&gt;Es darf noch keine Manipulation mit dem Tabellenpuffer erfolgt sein (andernfalls hat die&amp;nbsp;&lt;i&gt;setTmp()&lt;/i&gt;-Methode keinen Einfluss mehr auf den Puffer!)&lt;/li&gt;&lt;li&gt;Für Datenmanipulationen sollten die Skip-Methoden wie &lt;i&gt;skipDataMethods()&lt;/i&gt;/&lt;i&gt;skipDeleteMethods()&lt;/i&gt;/&lt;i&gt;skipEvents()&lt;/i&gt;/&lt;i&gt;s&lt;/i&gt;&lt;i&gt;kipDataBaseLog()&lt;/i&gt; verwendet werden und mit den Befehlen doUpdate(), doInsert() und doDelete() gearbeitet werden um ungewollte Änderungen an der persistenten Tabelle in der Datenbank zu verhindern&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;(Inhalt bezieht sich auf das QueryRun Objekt der Versionen AX 3.0 3tier, AX 4.0 und AX 5.0)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7349186445069837907?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7349186445069837907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/join-queries-mit-temporaren-tabellen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7349186445069837907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7349186445069837907'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/join-queries-mit-temporaren-tabellen.html' title='Join-Queries mit temporären Tabellen (und es funktioniert eben doch)'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-2426118363740154821</id><published>2010-01-06T20:16:00.000+01:00</published><updated>2010-01-06T20:16:55.949+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client/Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Temporary Tables'/><title type='text'>Join-Queries with temporary tables (nevertheless, it works)</title><content type='html'>Usage of temporary tables often ends in trouble, especially when the error message&lt;span style="color: blue;"&gt; “Cannot select a record in % (%). Temporary tables must be the inner tables when joined to permanent tables.“&lt;/span&gt; rises up.&lt;br /&gt;&lt;br /&gt;But a workmate of mine has solved the issue of that message with a special client/server constellation. Basing his solution I did some further research.&lt;br /&gt;&lt;br /&gt;This article is based on knowledge elaborated by tests. All explanation of query functionality is related to its results (even AX perhaps does not work as described).&lt;br /&gt;&lt;br /&gt;All problems begin, when the data selection of a data source is made in a different tier than its parent data source. Only the first data source has free tier choice. Data sources will be fetched on the tier where its data buffer is located. Once the server tier has become as data handler, it is not possible to re-access client data.&lt;br /&gt;&lt;br /&gt;But if you take care to some rules, a query with temporary tables will run fine. Keep in mind, that:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Permanent tables are fetched on server tier&lt;/li&gt;&lt;li&gt;Temporary tables are fetched on there, where its data buffer is located:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Temporary tables, which are usually permanent, but made temporary with a &lt;i&gt;setTmp()&lt;/i&gt; call, gets its tier where you make the &lt;i&gt;setTmp()&lt;/i&gt;-call.&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="background-color: white;"&gt;&lt;br /&gt;C&lt;/span&gt;&lt;span style="background-color: white;"&gt;ustTable&lt;/span&gt;&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="background-color: white;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="background-color: white;"&gt;custTable&lt;br /&gt;;&lt;br /&gt;&lt;span style="background-color: white;"&gt;custTable.setTmp();&lt;/span&gt;&lt;span style="color: lime;"&gt;&lt;span style="background-color: white;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="color: #38761d;"&gt;&lt;span style="background-color: white;"&gt;// now the handle will fixed on the current tier&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Temporary tables, which are already declared in AOT as temporary, gets its tier there, where its declaration is located&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;TmpSysQuery&lt;/span&gt;&lt;span style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;tmpSysQuery; &lt;span style="color: #38761d;"&gt;// the handle is already fixed on the current tier&lt;br /&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;First data source’s data buffer can either be located on the client tier or on the server tier as well&lt;/li&gt;&lt;li&gt;Every other, and therefore embedded data source must have its data buffer on the same tier as the parent data source or on the server tier&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Look these examples which are possible or even not (not all possibilities listed …):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0TcNj2d3OI/AAAAAAAAACg/EqUvH3qHM0Y/s1600-h/QueryVariant14.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0TcNj2d3OI/AAAAAAAAACg/EqUvH3qHM0Y/s320/QueryVariant14.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0TcK5toVMI/AAAAAAAAACY/EwwLB3kdQu4/s1600-h/QueryVariant13.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0TcK5toVMI/AAAAAAAAACY/EwwLB3kdQu4/s320/QueryVariant13.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcQK_-YfI/AAAAAAAAACo/a9rhrvWWTK0/s1600-h/QueryVariant15.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcQK_-YfI/AAAAAAAAACo/a9rhrvWWTK0/s320/QueryVariant15.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TcSl0-OCI/AAAAAAAAACw/qHHrvAbH4ro/s1600-h/QueryVariant16.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TcSl0-OCI/AAAAAAAAACw/qHHrvAbH4ro/s320/QueryVariant16.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0Tbb7aDI0I/AAAAAAAAAA4/6vsg5YAIVE4/s1600-h/QueryVariant1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0Tbb7aDI0I/AAAAAAAAAA4/6vsg5YAIVE4/s320/QueryVariant1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TbllFiFtI/AAAAAAAAABA/DsC0CllH5bI/s1600-h/QueryVariant2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TbllFiFtI/AAAAAAAAABA/DsC0CllH5bI/s320/QueryVariant2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0Tbpcoe0iI/AAAAAAAAABI/yecGHvZJeLQ/s1600-h/QueryVariant3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0Tbpcoe0iI/AAAAAAAAABI/yecGHvZJeLQ/s320/QueryVariant3.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TbsCuk5VI/AAAAAAAAABQ/0SwMCLK6CYU/s1600-h/QueryVariant4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0TbsCuk5VI/AAAAAAAAABQ/0SwMCLK6CYU/s320/QueryVariant4.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0Tbu-Qh3GI/AAAAAAAAABY/Ww1y2jy5H5o/s1600-h/QueryVariant5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_dKaxGw6aZCc/S0Tbu-Qh3GI/AAAAAAAAABY/Ww1y2jy5H5o/s320/QueryVariant5.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0Tby71sQCI/AAAAAAAAABg/3jkOvhuR1ts/s1600-h/QueryVariant6.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dKaxGw6aZCc/S0Tby71sQCI/AAAAAAAAABg/3jkOvhuR1ts/s320/QueryVariant6.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb2L9tpkI/AAAAAAAAABo/efAeKQ8Ot4c/s1600-h/QueryVariant7.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb2L9tpkI/AAAAAAAAABo/efAeKQ8Ot4c/s320/QueryVariant7.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb5r_zx9I/AAAAAAAAABw/LoaUhwVoB90/s1600-h/QueryVariant8.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb5r_zx9I/AAAAAAAAABw/LoaUhwVoB90/s320/QueryVariant8.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb9G-RfJI/AAAAAAAAAB4/nmS6HgldtZY/s1600-h/QueryVariant9.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0Tb9G-RfJI/AAAAAAAAAB4/nmS6HgldtZY/s320/QueryVariant9.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcDiW8XhI/AAAAAAAAACA/cJkOeLmApIo/s1600-h/QueryVariant10.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcDiW8XhI/AAAAAAAAACA/cJkOeLmApIo/s320/QueryVariant10.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcGXANxtI/AAAAAAAAACI/v84EwPGCZiQ/s1600-h/QueryVariant11.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_dKaxGw6aZCc/S0TcGXANxtI/AAAAAAAAACI/v84EwPGCZiQ/s320/QueryVariant11.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0TcIZL4udI/AAAAAAAAACQ/LCBPXwxZG5Q/s1600-h/QueryVariant12.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dKaxGw6aZCc/S0TcIZL4udI/AAAAAAAAACQ/LCBPXwxZG5Q/s320/QueryVariant12.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;Summary: The message &lt;span style="color: blue;"&gt;“Cannot select a record in % (%). Temporary tables must be the inner tables when joined to permanent tables.“&lt;/span&gt; would better be named as&lt;span style="color: #6aa84f;"&gt; “The temporary table's data buffer % is neither on the same tier as its parent % nor on the server tier”&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Some common remarks when using permanent tables as temporary tables:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The setTmp() method should done in the same method as where the table’s declaration is located&lt;/li&gt;&lt;li&gt;Between declaration and &lt;i&gt;setTmp()&lt;/i&gt;-call no buffer manipulation is allowed (otherwise &lt;i&gt;setTmp() &lt;/i&gt;will not work!)&lt;/li&gt;&lt;li&gt;When doing data manipulations use the skip-methods like &lt;i&gt;skipDataMethods()&lt;/i&gt;/&lt;i&gt;skipDeleteMethods()&lt;/i&gt;/&lt;i&gt;skipEvents()&lt;/i&gt;/&lt;i&gt;skipDatabaseLog()&lt;/i&gt; and the commands &lt;i&gt;doUpdate()&lt;/i&gt;, &lt;i&gt;doInsert()&lt;/i&gt; and &lt;i&gt;doDelete()&lt;/i&gt; to prevent unwanted manipulation on the permanent data base table&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;(Content is related to the QueryRun Object from Version AX 3.0 3tier, AX 4.0 und AX 5.0)&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-2426118363740154821?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/2426118363740154821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/join-queries-with-temporary-tables.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2426118363740154821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/2426118363740154821'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2010/01/join-queries-with-temporary-tables.html' title='Join-Queries with temporary tables (nevertheless, it works)'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dKaxGw6aZCc/S0TcNj2d3OI/AAAAAAAAACg/EqUvH3qHM0Y/s72-c/QueryVariant14.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3406339728210894553.post-7024624296404874259</id><published>2009-12-22T19:25:00.000+01:00</published><updated>2010-01-29T19:11:20.159+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='X++'/><category scheme='http://www.blogger.com/atom/ns#' term='Reflection'/><title type='text'>How to ignore Private, Protected and Abstract modifiers</title><content type='html'>&lt;div&gt;I was always curious about the Best Practices messages "Implement static construct to allow for modifications." and "New should be protected."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Say, you want to create a new class derived from RunBaseBatch; if you follow the Best Practice warnings (as named above), your &lt;em&gt;new()&lt;/em&gt;-method will be declared &lt;em&gt;Protected&lt;/em&gt;. But how the Batch Framework can create an object from this class if&amp;nbsp;the user decide to&amp;nbsp;let that process&amp;nbsp;run in batch mode? &lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Since the new()-method is protected, the object cannot created with that method, right? Theoretical yes, but&amp;nbsp;do not&amp;nbsp;underrate Reflection Technique in Dynamics AX.&lt;br /&gt;&lt;br /&gt;As known, you can create objects and invoke methods on it, using an object of the kernel class &lt;em&gt;DictClass&lt;/em&gt; (or its even more popular derivate &lt;em&gt;SysDictClass&lt;/em&gt;). The &lt;em&gt;DictClass&lt;/em&gt; object seems to be very powerful and follows its own rules of code execution abilities.&lt;br /&gt;&lt;br /&gt;With a &lt;em&gt;DictClass&lt;/em&gt; object you can create objects what theoretically not should be possible. Use the &lt;em&gt;makeObject()&lt;/em&gt;-method and you can:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create objects from classes which are abstract&lt;/li&gt;&lt;li&gt;Create objects from classes even the &lt;em&gt;new()&lt;/em&gt;-method is declared as &lt;em&gt;Private&lt;/em&gt; or &lt;em&gt;Protected&lt;/em&gt; (the code execution really runs through the &lt;em&gt;new()&lt;/em&gt;-method)&lt;/li&gt;&lt;li&gt;Create objects from classes which have not implemented all abstracted methods from the super class&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;But the power of the DictClass objects does not just end with creating other objects. You are also able to invoke:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Member and static methods despite &lt;em&gt;protected&lt;/em&gt;, &lt;em&gt;private&lt;/em&gt; or &lt;em&gt;abstract&lt;/em&gt; modifier (&lt;em&gt;callObject()&lt;/em&gt; and &lt;em&gt;callStatic()&lt;/em&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;As if this wasn't enough, the &lt;em&gt;DictTable&lt;/em&gt; object shares that behavior property too. You can invoke any table method you want&amp;nbsp;by calling the &lt;em&gt;callStatic()&lt;/em&gt;- or &lt;em&gt;callObject()&lt;/em&gt;-method on the &lt;em&gt;DictTable&lt;/em&gt; object. &lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;You see, there are dirty tricks to leverage AX's code security and compiler checks. Even it is possible to do such things, I &lt;strong&gt;really&lt;/strong&gt; recommend to avoid executing theoretical illegal operations as mentioned. This article just shows what is possible and&amp;nbsp;not what make sense :)&lt;br /&gt;&lt;br /&gt;(all content relates to AX 2009)&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3406339728210894553-7024624296404874259?l=axatluegisdorf.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://axatluegisdorf.blogspot.com/feeds/7024624296404874259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://axatluegisdorf.blogspot.com/2009/12/how-to-ignore-private-protected-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7024624296404874259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3406339728210894553/posts/default/7024624296404874259'/><link rel='alternate' type='text/html' href='http://axatluegisdorf.blogspot.com/2009/12/how-to-ignore-private-protected-and.html' title='How to ignore Private, Protected and Abstract modifiers'/><author><name>Luegisdorf</name><uri>http://www.blogger.com/profile/08857832247604204765</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_dKaxGw6aZCc/SzERckmNxyI/AAAAAAAAAAY/IEM67R1Pw1c/S220/clint.jpg'/></author><thr:total>0</thr:total></entry></feed>
