<?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:blogger='http://schemas.google.com/blogger/2008' 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-2484495037532005022</id><updated>2026-02-25T17:38:36.852+05:30</updated><category term="Dynamics AX"/><category term="Dynamics AX 2012"/><category term="AX development"/><category term="Budget control"/><category term="CCADOConnection"/><category term="Project"/><category term="UtilElements"/><category term="addRange"/><category term="caller"/><category term="moveNext"/><category term="Array"/><category term="AutoRefreshData"/><category term="CCADOCommand"/><category term="CCADORecordSet"/><category term="Cumulative Update"/><category term="Cumulative update pack 2"/><category term="Data export"/><category term="DateTimeUtil"/><category term="DateTimeUtil::addDays"/><category term="Debug BP error"/><category term="DevelopmentTools"/><category term="Diagnostic ID"/><category term="DocuView caller"/><category term="Dynamics AX 2009"/><category term="Dynamics AX 2009 batches with a recurrence of 1 minute"/><category term="Dynamics AX 2012 Pricing and Licencing information"/><category term="Employee self services"/><category term="EventLog"/><category term="Excel 2010"/><category term="Financial dimension"/><category term="Form User Experience Guidelines"/><category term="Form templates"/><category term="FormButtonManager"/><category term="FormControl.setFocus"/><category term="FormDesign.controlName"/><category term="Futures"/><category term="Illegal data conversion from original field"/><category term="Label files"/><category term="List"/><category term="Listpage datasource"/><category term="Map"/><category term="Microsoft Dynamics AX 2012 global virtual launch event"/><category term="Microsoft.ACE.OLEDB.12.0"/><category term="MultiSelectionContext"/><category term="MultiSelectionHelper"/><category term="NeedsRecord"/><category term="NumberSeqApplicationModule::loadall"/><category term="NumberSeqModule"/><category term="Only foreign key constraints are allowed on this table"/><category term="QueryDataSourceStr"/><category term="Regular expressions"/><category term="ReleaseUpdateDB::changeFieldId"/><category term="ReleaseUpdateDB::changeTableId"/><category term="Replace text option in Find window in Dynamics AX"/><category term="Role based security"/><category term="Runtime control events"/><category term="SID"/><category term="Spell Check"/><category term="SpellChecker"/><category term="SysCompareText"/><category term="SysHelpBookCrossword"/><category term="SysHelpCrosswordEngine"/><category term="SysQuery::findOrCreateRange"/><category term="SysQuery::valueEmptyString()"/><category term="SysTableBrowser"/><category term="Task"/><category term="The &#39;Microsoft.ACE.OLEDB.12.0&#39; provider is not registered on the local machine"/><category term="The field with ID &#39;0&#39; does not exist in table"/><category term="The server-side impersonated (RunAs) session tried to invoke a method that is available for client-side processing only"/><category term="TreeNode.AOTgetProperty"/><category term="TreeNode.applObjectLayerMask"/><category term="TreeNode.getNodeInLayer"/><category term="UserInfo"/><category term="WinAPI::createFile"/><category term="WinAPIServer::createFile"/><category term="Windows"/><category term="args"/><category term="budget amount"/><category term="canGoBatch"/><category term="controlId"/><category term="controlMethodOverload"/><category term="controlMethodOverloadObject"/><category term="create"/><category term="definition groups"/><category term="document handling"/><category term="duty"/><category term="exist()"/><category term="find()"/><category term="formControlStr"/><category term="formHasMethod"/><category term="hide enum values"/><category term="how to disable button when no record exists"/><category term="isTableMapped"/><category term="keywords"/><category term="match function"/><category term="model"/><category term="movePrevious"/><category term="mustGoBatch"/><category term="number sequence"/><category term="parmLastActivatedForm"/><category term="parmRuleImplementer"/><category term="price list"/><category term="privilege"/><category term="query"/><category term="ranges"/><category term="registerButtonRule"/><category term="remove enum values"/><category term="role"/><category term="rowCount"/><category term="security identifier"/><category term="selectRefRecord"/><category term="set focus"/><category term="setDatasources"/><category term="show hide ranges on dialog"/><category term="showIndexFields"/><category term="sysContextMenu"/><category term="text comparison with white spaces"/><category term="unionAllBranchId"/><category term="view"/><category term="xRecord.rowCount"/><category term="xRecord.selectRefRecord"/><category term="“Day in the Life Benchmark”"/><title type='text'>Microsoft Dynamics AX blog by Zubair</title><subtitle type='html'>This Microsoft Dynamics AX blog contains  tips and tricks, tutorials, How-to, code samples and other general discussions around Microsoft Dynamics AX.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default?start-index=26&amp;max-results=25'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-4891487974817203707</id><published>2013-11-26T22:55:00.002+05:30</published><updated>2013-11-29T22:37:48.812+05:30</updated><title type='text'>Book review: Developing SSRS Reports for Dynamics AX</title><content type='html'>Recently, I got a chance to review another book on developing SSRS reports for Dynamics AX 2012 - &lt;a href=&quot;http://bit.ly/16vc6FO&quot;&gt;Developing SSRS Reports for Dynamics AX&lt;/a&gt;. This book is authored by Mukesh Hirwani

This book is a good starting point if you are new to SSRS report development in Dynamics AX 2012 as it covers all topics related to the subject. The book uses a practical hands on approach and Mukesh gets right into business by showing pracitically how it is done with screen shots.

Apart from the standard auto and precision designs, there is a section on creating matrix, chart and drill through reports. UI designing using the new UIBuilder framework in Dynamics AX 2012 is also covered.

Finally, there is a section for report deployment and maintenance with best practices.

I&#39;ll definitely recommend this book as a readily available guide to start with SSRS report development in Dynamics AX 2012. To read more about the book click &lt;a href=&quot;http://bit.ly/16vc6FO&quot;&gt;here&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/4891487974817203707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/4891487974817203707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4891487974817203707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4891487974817203707'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2013/11/book-review-developing-ssrs-reports-for.html' title='Book review: Developing SSRS Reports for Dynamics AX'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-6775612766145661603</id><published>2013-10-20T16:14:00.004+05:30</published><updated>2013-10-20T16:14:49.250+05:30</updated><title type='text'>Book review: Dynamics AX 2012 reporting cookbook</title><content type='html'>&lt;p&gt;
Today I got a chance to review another book from Packt publications. This book is on SSRS report development titled &lt;b&gt;Dynamics AX 2012 reporting cookbook&lt;/b&gt; by Kamalakannan Elangovan. This book is a collection of 50+ techniques to get you up and running with report development using SSRS in Dynamics AX. Some of the great features of this book are,
&lt;/p&gt;
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;Develop all kind of reports ranging from autodesign, matrix, multicolumn, line and gauge reports&lt;/li&gt;
&lt;li&gt;Learn how to use query, RDP, XML feeds and OLAP cubes as datasources for your reports&lt;/li&gt;
&lt;li&gt;Learn how to use SQL report builder for creating reports&lt;/li&gt;
&lt;li&gt;Learn how to upgrade reports from previous versions to Dynamics AX 2012&lt;/li&gt;
&lt;li&gt;Learn how to add dimensions to reports&lt;/li&gt;
&lt;li&gt;Learn how to assess report performance and improve them&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
The language is very fluid and there are clear illustrations to help the reader. Also, every topic has clear code snippets to explain the code in detail. If you are serious about improving your report development skills and want to be confident about it, then this is a must have book. To know more about the book, click &lt;a href=&quot;http://bit.ly/1bmadzg&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/6775612766145661603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/6775612766145661603' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6775612766145661603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6775612766145661603'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2013/10/book-review-dynamics-ax-2012-reporting.html' title='Book review: Dynamics AX 2012 reporting cookbook'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-8453680036170931723</id><published>2013-10-02T18:21:00.000+05:30</published><updated>2013-10-02T18:21:13.011+05:30</updated><title type='text'>Book review: Extending Microsoft Dynamics AX 2012 Cookbook</title><content type='html'>Back in the days of Dynamics AX 4.0 &amp; Dynamics AX 2009, developers had few choice when picking a good book to learn Dynamics AX development.

My personal choice was the Inside Dynamics AX book from the Microsoft press and the Microsoft Dynamics AX cookbook by Mindaugas Pocius.

&lt;p&gt;Packt publications have been publishing a lot of cookbooks on various topics in Dynamics AX. They have more than 10 books on various topics in Dynamics AX.&lt;/p&gt;

&lt;p&gt;Recently I got a chance to review one of their book - Extending Microsoft Dynamics AX 2012 Cookbook by &lt;b&gt;Murray Fife&lt;/b&gt;.&lt;p&gt;

&lt;p&gt;
As the name suggests, this book is not specific about Dynamics AX, but how to extend Dynamics AX with other Microsoft technologies like 

&lt;ul&gt;
&lt;li&gt;SharePoint&lt;/li&gt;
&lt;li&gt;reporting tools like Power View and Power Pivot&lt;/li&gt;
&lt;li&gt;creating various analytical dashboards and BI scorecards&lt;/li&gt;
&lt;li&gt;collaborating with MS Outlook &amp; Lync&lt;/li&gt;
&lt;li&gt;creating help documents for your customization&lt;/li&gt;
&lt;li&gt;creating web services in Dynamics AX&lt;/li&gt;
&lt;li&gt;organizing workflows&lt;/li&gt;
&lt;li&gt;creating role centers in Dynamics AX.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;As you can see from the above list, all these technologies play an important role in designing complete real world solutions based around Dynamics AX.&lt;/p&gt;

&lt;p&gt;
Murray keeps the narration fluid and specific to the topic on hand. He starts with providing the context of the topic, what the reader can expect from the topic, how to do it and how it works. There are clear illustrations to guide the user and language is very easy.&lt;/P&gt;

&lt;p&gt;Go ahead and take a look at the book &lt;a href=&quot;http://bit.ly/1afWb1s&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my opinion a must own book for any Dynamics AX developer who is serious about integrating Dynamics AX with other technologies.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/8453680036170931723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/8453680036170931723' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/8453680036170931723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/8453680036170931723'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2013/10/book-review-extending-microsoft.html' title='Book review: Extending Microsoft Dynamics AX 2012 Cookbook'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7537845025418622976</id><published>2011-11-18T22:47:00.002+05:30</published><updated>2011-11-18T22:47:44.257+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cumulative update pack 2"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><title type='text'>Cumulative update pack 2 for Microsoft Dynamics AX 2012</title><content type='html'>Cumulative update pack 2 for Microsoft Dynamics AX 2012 has been released.&lt;br /&gt;
&lt;br /&gt;
This pack contains close to 70 fixes for various bugs. The pack also contains the cumulative update pack 1 for Microsoft Dynamics AX 2012 which was released earlier.&lt;br /&gt;
&lt;br /&gt;
The build number after applying this pack will be 6.0.947.280&lt;br /&gt;
&lt;br /&gt;
You can download the pack and read more about the fixes in the pack &lt;a href=&quot;http://support.microsoft.com/kb/2606916&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/7537845025418622976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/7537845025418622976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7537845025418622976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7537845025418622976'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/11/cumulative-update-pack-2-for-microsoft.html' title='Cumulative update pack 2 for Microsoft Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-4629600282783458856</id><published>2011-11-17T22:35:00.000+05:30</published><updated>2011-11-17T22:35:12.395+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="Financial dimension"/><title type='text'>Set financial dimension values through code in AX 2012</title><content type='html'>In Dynamics AX 2012, the dimensions framework has gone for a complete makeover. We can now have an unlimited number of financial dimensions. In Dynamics AX 4 and Dynamics AX 2009, the dimensions were actually stored as an array of string fi?&gt;elds. This has changed in Dynamics AX 2012 where the dimension is stored as a recid. Recently I came across a requirement where if the CostCenter dimension was set to a particular value, the department dimension&#39;s value should change to a different value and vice versa.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF0QGKXkf1FMK2NhMXhMzsMDuk5nDm3DWrSjwdbohcEcrmgrwPy_FVhZuhjg2lCfd2QR1pwKE5woRCTmGldPy6KbsqLZSAn_P8YSEO-e2gIcia76yyYVSNDhU-5f0h2GkiwrTeiWdHiMs/s1600/Financial_dimension.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;96&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF0QGKXkf1FMK2NhMXhMzsMDuk5nDm3DWrSjwdbohcEcrmgrwPy_FVhZuhjg2lCfd2QR1pwKE5woRCTmGldPy6KbsqLZSAn_P8YSEO-e2gIcia76yyYVSNDhU-5f0h2GkiwrTeiWdHiMs/s400/Financial_dimension.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
I developed the code and thought it will be a good idea to share it here.&lt;br /&gt;
&lt;br /&gt;
My requirement was in the ProjTable form but you can use this code in any of your form which uses the default financial dimensions.&lt;br /&gt;
&lt;br /&gt;
Override the DefaultDimension field&#39;s dataChanged() method on your main datasource and add the below code.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;// Financial dimension change code - Zubair - Begin
public void dataChanged()
{
    DimensionAttribute  dimToBeChanged;
    DimensionAttributeValue dimAttributeValue;

    boolean             triggerDimensionChange;
    str        10       valueToBeDefaulted;

    DictTable           dictTable;
    Common              common;

    FormStringControl   dimensionControl = element.selectedControl();

    super();

 // Our dimension change will trigger this method again, we dont want to skip it then.
    if (!dimensionValueChanged)
    {
        if (dimensionControl.name() == &#39;DimensionValue1&#39; &amp;&amp; dimensionControl.valueStr() == #CostCenterValue)
        {
            dimToBeChanged = dimAttributeDepartment;
            triggerDimensionChange = true;
            valueToBeDefaulted = #DepartmentValue;
        }

        if (dimensionControl.name() == &#39;DimensionValue2&#39; &amp;&amp; dimensionControl.valueStr() == #DepartmentValue)
        {
            dimToBeChanged = dimAttributeCostCenter;
            triggerDimensionChange = true;
            valueToBeDefaulted = #CostCenterValue;
        }

        if (triggerDimensionChange)
        {
            dictTable = new DictTable(dimToBeChanged.BackingEntityType);
            common = dictTable.makeRecord();

            select common where common.(fieldName2id(dimToBeChanged.BackingEntityType, #DimensionValueFieldName)) == valueToBeDefaulted;

   // Find the DimensionAttributeValue record for the dimension being changed
            dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimToBeChanged.RecId, common.RecId, false, true);

            // Set the new dimension value
            dimensionDefaultingController.setDimensionAttributeValue(dimToBeChanged, dimAttributeValue.RecId, valueToBeDefaulted);

            dimensionValueChanged = true;
        }
    }
    else
    {
        dimensionValueChanged = false;
    }
}
// Financial dimension change code - Zubair - End
&lt;/pre&gt; &lt;br /&gt;
Add the following lines in the init() method of your form after the call to super(). &lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;// Financial dimension change code - Zubair - Begin
    dimAttributeCostCenter = DimensionAttribute::findByName(#CostCenterDimension);
    dimAttributeDepartment = DimensionAttribute::findByName(#DepartmentDimension);
// Financial dimension change code - Zubair - End
&lt;/pre&gt;&lt;br /&gt;
Add the following lines in the classDeclaration of the form.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;// Financial dimension change code - Zubair - Begin
    DimensionAttribute  dimAttributeCostCenter;
    DimensionAttribute  dimAttributeDepartment;

    boolean             dimensionValueChanged;

    #define.CostCenterDimension(&#39;CostCenter&#39;)
    #define.DepartmentDimension(&#39;Department&#39;)
    #define.CostCenterValue(&#39;OU_3569&#39;)
    #define.DepartmentValue(&#39;OU_2561&#39;)
    #define.DimensionValueFieldName(&#39;Value&#39;)
// Financial dimension change code - Zubair - End
&lt;/pre&gt;&lt;br /&gt;
Thats it. Now try changing the value of the CostCenter dimension to OU_3569. Notice that the value in Department to OU_2561.&lt;br /&gt;
&lt;br /&gt;
Hope this snippet will be useful if you have a similiar requirement or atleast you know how it can be done now.&lt;br /&gt;
&lt;br /&gt;
Feel free to mail me or comment here if you need help with understanding the code.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/4629600282783458856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/4629600282783458856' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4629600282783458856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4629600282783458856'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/11/set-financial-dimension-values-through.html' title='Set financial dimension values through code in AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF0QGKXkf1FMK2NhMXhMzsMDuk5nDm3DWrSjwdbohcEcrmgrwPy_FVhZuhjg2lCfd2QR1pwKE5woRCTmGldPy6KbsqLZSAn_P8YSEO-e2gIcia76yyYVSNDhU-5f0h2GkiwrTeiWdHiMs/s72-c/Financial_dimension.png" height="72" width="72"/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7514308283555489772</id><published>2011-10-28T23:32:00.001+05:30</published><updated>2011-10-28T23:33:23.793+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="“Day in the Life Benchmark”"/><title type='text'>“Day in the Life Benchmark” available for download</title><content type='html'>Microsoft has recently released the &lt;b&gt;Day in the Life Benchmark&lt;/b&gt; documents on PartnerSource.&lt;br /&gt;
&lt;br /&gt;
You can read more about it on the &lt;a href=&quot;http://blogs.msdn.com/b/axperf/archive/2011/10/26/day-in-the-life-benchmark-available-for-download-on-partnersource-and-customersource.aspx&quot;&gt;Dynamics Ax Performance Team Blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The benchmark numbers shared there are really encouraging and truly shows that Dynamics AX 2012 is a robust and agile erp platform to base your business on.&lt;br /&gt;
&lt;br /&gt;
Note: PartnerSource or CustomerSource login is required.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/7514308283555489772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/7514308283555489772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7514308283555489772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7514308283555489772'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/10/day-in-life-benchmark-available-for.html' title='“Day in the Life Benchmark” available for download'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-32435237884658104</id><published>2011-10-19T20:57:00.002+05:30</published><updated>2011-10-19T21:32:07.394+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="MultiSelectionContext"/><category scheme="http://www.blogger.com/atom/ns#" term="MultiSelectionHelper"/><title type='text'>Get selected records in Dynamics AX 2012</title><content type='html'>In my earlier post, we discussed how we can retrieve all selected records on a list page. You can read that post &lt;a href=&quot;http://daxline.blogspot.com/2011/10/how-to-get-list-pages-datasource-in.html&quot;&gt;here&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Retrieving all selected records from a caller form is very easy. The code for this can be found in a number of places in standard Dynamics AX codebase. The general approach is to use the &lt;b&gt;dataSource.getFirst(1)&lt;/b&gt; statement to get the first selected record and loop through the remaining using &lt;b&gt;dataSource.getNext()&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX 2009, a new class was introduced for this purpose. This was the &lt;b&gt;MultiSelectionHelper&lt;/b&gt; class.&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX 2012, another new class has been introduced to retrieve the selected records. This is the &lt;b&gt;MultiSelectionContext&lt;/b&gt; class.&lt;br /&gt;
&lt;br /&gt;
The MultiSelectionHelper class is an application class. It presents two constrcutors. The standard constructor method just creates a new instance of the MultiSelectionHelper class. When this construct is used, you will have to explicitly set the dataSource to be used for fethcing selected records. This can be done in the following way,&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;MultiSelectionHelper multiSelectionHelper; 

multiSelectionHelper = MultiSelectionHelper::construct();
multiSelectionHelper.parmDatasource(element.dataSource());
&lt;/pre&gt;This way, the class is initialized and the datasource is specified.&lt;br /&gt;
&lt;br /&gt;
The other constructor method this class offers is the &lt;b&gt;createFromCaller()&lt;/b&gt; method. This method takes a formRun as an argument. When you want to retrieve the selected records from the caller form, you can pass the caller form as an argument here.&lt;br /&gt;
&lt;br /&gt;
Once the class has been initialized, you can traverse through the selected records using the getFirst() &amp; getNext() method.&lt;br /&gt;
&lt;br /&gt;
The &lt;b&gt;MultiSelectionHelper&lt;/b&gt; class provides the added benefit of caching the selected records if the object is initialized on the server.&lt;br /&gt;
&lt;br /&gt;
The other new class that has been introduced in Dynamics AX 2012 for selected records handling is &lt;b&gt;MultiSelectionContext&lt;/b&gt;. This is a kernel class. An object of this class exists in the &lt;b&gt;xArgs&lt;/b&gt; class. This class also provides the getFirst() and getNext() methods to traverse through the selected records.&lt;br /&gt;
&lt;br /&gt;
Below is a code sample on how these two classes can be used to implemented in code.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public void init()
{
    FormRun                 callerForm;
    FormDataSource          formDataSource;

    MultiSelectionHelper    multiSelectionHelper;
    MultiSelectionContext   multiSelectionContext;

    ProjTable       projTable;

    super();

    if (!element.args().caller())
    {
        throw error(&quot;@SYS22539&quot;);
    }

// ************** The standard way of doing it in Dynamics AX 4 and Dynamics AX 2009 **************
    callerForm = element.args().caller();
    formDataSource = callerForm.dataSource();

    ListView.add(&quot;Approach 1&quot;);

    for(projTable = formDataSource.getFirst(1); projTable; projTable = formDataSource.getNext())
    {        
        ListView.add(strFmt(&quot;%1 - %2&quot;,projTable.ProjId, projTable.Name));
    }

// ************** Using the new MultiSelectionHelper class in Dynamics AX 2012 **************
    multiSelectionHelper = MultiSelectionHelper::createFromCaller(element.args().caller());

    projTable = multiSelectionHelper.getFirst();
    ListView.add(&quot;Approach 2&quot;);

    while (projTable)
    {        
        ListView.add(strFmt(&quot;%1 - %2&quot;,projTable.ProjId, projTable.Name));
        projTable = multiSelectionHelper.getNext();
    }

// ************** Using the new MultiSelectionContext class in Dynamics AX 2012 **************
    multiSelectionContext = element.args().multiSelectionContext();

    projTable = multiSelectionContext.getFirst();
    ListView.add(&quot;Approach 3&quot;);

    while (projTable)
    {        
        ListView.add(strFmt(&quot;%1 - %2&quot;,projTable.ProjId, projTable.Name));
        projTable = multiSelectionContext.getNext();
    }

    if (!ListView.getCount())
    {
        throw error(&quot;No projects selected&quot;);
    }
}
&lt;/pre&gt;The below image shows which part of the code produced the what output.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXHJEPQQ1FJn4RtrcfcEPLEORL0nKuZspDwjL0UIw4oXy-6w1xslZeRfZwOMVHPWt6FCVsE13_JBaEG_uirvrKOG3mw2umL_Fb7V-QnXI58Iw6Ml_HiPUWzUl7I8LZ3TCA0mPjVMUJJ1I/s1600/Dynamics_AX_2012_Multiselect_scenarios.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;239&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXHJEPQQ1FJn4RtrcfcEPLEORL0nKuZspDwjL0UIw4oXy-6w1xslZeRfZwOMVHPWt6FCVsE13_JBaEG_uirvrKOG3mw2umL_Fb7V-QnXI58Iw6Ml_HiPUWzUl7I8LZ3TCA0mPjVMUJJ1I/s400/Dynamics_AX_2012_Multiselect_scenarios.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Going forward, I&#39;ll recommend that we start using these helper classes for dealing with selected records.&lt;br /&gt;
&lt;br /&gt;
Some of you may have a question as to which class to use and in what scenarios. Let me clarify that for you.&lt;br /&gt;
&lt;br /&gt;
Like I stated above, the MultiSelectionHelper class provides us the benefit of record caching provided you intantiate the object on the server tier. Now, because of this, you will have to call this class from within an object(not a form as forms run on the client tier) which is running on the server tier. This is because the RunOn property of the MultiSelectionHelper class is CalledFrom. So if you call it directly from a form, the object will be created on the client tier itself and your selected records will not be cached.&lt;br /&gt;
&lt;br /&gt;
But if you have designed your code such a way that your form calls a table or a class running on the server tier, and then this class in turns calls the MultiSelectionHelper class, we can then make use of the caching capabilities.&lt;br /&gt;
&lt;br /&gt;
So if your code is designed in such a way, I&#39;ll advice to make use of the MultiSelectionHelper class else you should go for the MultiSelectionContext class.&lt;br /&gt;
&lt;br /&gt;
You can download the project I&#39;ve developed for this demo &lt;a href=&quot;http://www.axaptapedia.com/images/2/2f/PrivateProject_Approach_to_get_Selected_Records.xpo&quot;&gt;here&lt;/a&gt;. Click on the Project details button on the Projects list page to open the new form.&lt;br /&gt;
&lt;br /&gt;
I hope this post was helpful. Please feel free to provide your comments.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, do check back soon for more.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/32435237884658104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/32435237884658104' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/32435237884658104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/32435237884658104'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/10/get-selected-records-in-dynamics-ax.html' title='Get selected records in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXHJEPQQ1FJn4RtrcfcEPLEORL0nKuZspDwjL0UIw4oXy-6w1xslZeRfZwOMVHPWt6FCVsE13_JBaEG_uirvrKOG3mw2umL_Fb7V-QnXI58Iw6Ml_HiPUWzUl7I8LZ3TCA0mPjVMUJJ1I/s72-c/Dynamics_AX_2012_Multiselect_scenarios.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-2388417224823321685</id><published>2011-10-15T09:39:00.000+05:30</published><updated>2011-10-15T09:39:48.904+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="duty"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="privilege"/><category scheme="http://www.blogger.com/atom/ns#" term="role"/><category scheme="http://www.blogger.com/atom/ns#" term="Role based security"/><title type='text'>New security model in Dynamics AX 2012</title><content type='html'>In Dynamics AX 2012, one of the key area that has gone a total overhaul is Security. In Dynamics AX 4.0 and Dynamics AX 2009, the security model was module based. Users were assigned to user groups which grouped permissions to the various objects. These permissions were controlled by security keys. The biggest drawback of this model was that you could not have the same security user group apply across multiple companies. You still had to create the same user group across different groups.&lt;br /&gt;
&lt;br /&gt;
With Dynamics AX 2012, all this has changed. The security model in Dynamics AX 2012 is role based. This means that you can relate the day to day business processes to roles. Users are assigned to roles. Roles contain a group of duties or privileges. It is logically very easy now to configure security in Dynamics AX 2012.&lt;br /&gt;
&lt;br /&gt;
The Security keys in the AOT are now obsolete in Dynamics AX 2012. It is present for backward compatibility. If you right click on the Security keys node, you dont have an option to create a new security key.&lt;br /&gt;
&lt;br /&gt;
Instead, in the AOT, you will find a new node - Security. This further has sub nodes - Privileges, Duties and Roles. Let us better understand these by relating to a real world example.&lt;br /&gt;
&lt;br /&gt;
Let us take an example of a school. A school needs to do a lot of day to day activities like teaching students, conducting exams, counselling, issuing books, buying new books etc. All these are privileges. These privileges can be group as duties. So teaching students and conducting exams can be grouped under one duty of learning enablement. At the same time issuing books and buying new books can be grouped under the book management duty. Now not everyone can perform these duties. These duties have to be assigned to some role. In some cases, multiple duties can be assigned to a single role.&lt;br /&gt;
&lt;br /&gt;
Take a look at the below image to better understand this.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLyn4onG2IseyBLVdn2iIpyt5S055vjHZUKha4zYUprm7FtovSBqPJLy-wcOMa0ObEmSYL-aom83pi-4YuWwhZPGCbhxvp7mzAILwvSTrglg9IOPYbNXw8DrpC0S4QtgqYjdj-dfyaBAg/s1600/Dynamics_AX_2012_Security.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;277&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLyn4onG2IseyBLVdn2iIpyt5S055vjHZUKha4zYUprm7FtovSBqPJLy-wcOMa0ObEmSYL-aom83pi-4YuWwhZPGCbhxvp7mzAILwvSTrglg9IOPYbNXw8DrpC0S4QtgqYjdj-dfyaBAg/s400/Dynamics_AX_2012_Security.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;In my opinion, the new role based security model is very logical and aimed at enabling business analysts to configure security. Of course, a developer&#39;s help may still be required but once the privileges are created, it is just a matter of group them under duties and assinging the right duties to the correct roles.&lt;br /&gt;
&lt;br /&gt;
The new security model is strictly enforced in Dynamics AX 2012. There are a bunch of best practice errors around this. Let us look at these.&lt;br /&gt;
&lt;br /&gt;
Every new menu item should be added as an entry point in a privilege. If this is not the case, the following best practice error is thrown.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Entry point is not in any privilege&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In case, you create a new privilege and add your menu item to it, and forget to add the privilege to a duty, you get the following best practice error.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Privilege is not in any duty&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
And finally, if you created a new duty and didnt add it to any role, you will get these best practice error.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All duties should be part of a role&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All duties should be part of a process cycle&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So, there are four best practice errors coaxing the user to complete the security modelling. In a way, this is a good thing as this ensures that there are no orphan or unused objects existing in the AOT.&lt;br /&gt;
&lt;br /&gt;
When configuring security, ensure that you analyze the out of the box duties and roles present in Dynamics AX 2012. Often, your new entry points should be easily sit in one of these. If they dont, then you can go ahead and create your own duties or roles.&lt;br /&gt;
&lt;br /&gt;
I&#39;ll encourage you to further go and read more about the new Security model in Dynamics AX 2012 on the &lt;a href=&quot;http://technet.microsoft.com/en-us/library/gg731783.aspx&quot;&gt;What&#39;s New: Security [AX 2012]&lt;/a&gt; page on MSDN.&lt;br /&gt;
&lt;br /&gt;
Also, take a look at this nice post by Brandon - &lt;a href=&quot;http://dynamics-ax.blogspot.com/2011/10/ax-2012-and-impact-on-design-with-new.html&quot;&gt;AX 2012 and the impact on Design with the new Security Model&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
That is all for today. In future posts, I&#39;ll cover some more topics on Security. Check back soon for more.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/2388417224823321685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/2388417224823321685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2388417224823321685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2388417224823321685'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/10/new-security-model-in-dynamics-ax-2012.html' title='New security model in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLyn4onG2IseyBLVdn2iIpyt5S055vjHZUKha4zYUprm7FtovSBqPJLy-wcOMa0ObEmSYL-aom83pi-4YuWwhZPGCbhxvp7mzAILwvSTrglg9IOPYbNXw8DrpC0S4QtgqYjdj-dfyaBAg/s72-c/Dynamics_AX_2012_Security.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-3180038887749963142</id><published>2011-10-11T23:03:00.000+05:30</published><updated>2011-10-11T23:03:10.625+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="Listpage datasource"/><title type='text'>How to get list page&#39;s datasource in Dynamics AX 2012?</title><content type='html'>Recently, I had a requirement where I needed to disable a button on a list page if the records selected did not meet a particular condition. Let me explain you this with an example. Say I have a new button on the Projects list page. This button should be enabled only if all projects selected have the same project contract ID. If the contract ID is different for the selected projects, the button should be disabled.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xGfkg1Rx4Q_xr0L9fF2Sp4gvMPomLfbmQQsVNu7y7EipHfAKv8UQCAwY8pknvkQzPXwetnfY-oZiT-_L4zpXMh2DP7wJf2FXBw2HG-EnTEuBjCERR51ufTHwDbQpQblJSm-2AWwtPJQ/s1600/Dynamics+AX+2012_Project.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;196&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xGfkg1Rx4Q_xr0L9fF2Sp4gvMPomLfbmQQsVNu7y7EipHfAKv8UQCAwY8pknvkQzPXwetnfY-oZiT-_L4zpXMh2DP7wJf2FXBw2HG-EnTEuBjCERR51ufTHwDbQpQblJSm-2AWwtPJQ/s400/Dynamics+AX+2012_Project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;So how can we achieve this? On a form, this can be done in a very straight forward way. Just loop through all the selected records and check if the project contract IDs are different. If they are, just disable the button. But on a list page, the form datasource is not readily available. After some investigation, I found out a way of doing this.&lt;br /&gt;
&lt;br /&gt;
As you must be knowing, all list pages in Dynamics AX 2012 are controlled via interaction classes. This is the new framework model. If you are new to this and dont know about these, I&#39;ll recommend you learn more on this on the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc586969.aspx&quot;&gt;How to: Create a List Page Form&lt;/a&gt; page on MSDN.&lt;br /&gt;
&lt;br /&gt;
Coming back to the post, the interaction class has a method &lt;b&gt;selectionChanged()&lt;/b&gt; which is fired every time a record is selected or deselected on the list page. We can use this method to check the project contract ID of the selected projects. So, our logic should go into this method.&lt;br /&gt;
&lt;br /&gt;
Now how to retrieve the form&#39;s datasource? To do that, I first got hold of the active record on the list page and then extracted the datasource object associated with it. The code to do that is&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;this.listPage().activeRecord(queryDataSourceStr(ProjTable_NoFilter, ProjTable)).dataSource();&lt;/pre&gt;&lt;br /&gt;
Notice how I have used the intrinsic function &lt;b&gt;queryDataSourceStr()&lt;/b&gt; here to get the datasource. You can read more about this function in my previous post on &lt;a href=&quot;http://daxline.blogspot.com/2011/10/querydatasourcestr-new-intrinsic.html&quot;&gt;queryDataSourceStr&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve created a new helper method called enableNewButton to return me a boolean value to enable/disable the button.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public boolean enableNewButton(FormDataSource  _formDataSource)
{
    ProjTable   projTableLocal;

    boolean     ret = true;

    for (projTableLocal = _formDataSource.getFirst(1); projTableLocal; projTableLocal = _formDataSource.getNext())
    {
        if (selectedProjects.elements() &amp;&amp; !selectedProjects.in(projTableLocal.ProjInvoiceProjId))
        {
            ret = false;
            break;
        }

        selectedProjects.add(projTableLocal.ProjInvoiceProjId);
    }

    return ret;
}
&lt;/pre&gt;&lt;br /&gt;
I call this method from the &lt;b&gt;selectionChanged()&lt;/b&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public void selectionChanged()
{
    super();

    this.enableButton(newButtonName,
    this.enableNewButton(this.listPage().activeRecord(queryDataSourceStr(ProjTable_NoFilter, ProjTable)).dataSource()));
}
&lt;/pre&gt;&lt;br /&gt;
That is it. You can download the objects I&#39;ve used in this sample from &lt;a href=&quot;http://www.axaptapedia.com/images/5/54/PrivateProject_Enable_Disable_ListPage_Button.xpo&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, do check back soon for more.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/3180038887749963142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/3180038887749963142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/3180038887749963142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/3180038887749963142'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/10/how-to-get-list-pages-datasource-in.html' title='How to get list page&#39;s datasource in Dynamics AX 2012?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xGfkg1Rx4Q_xr0L9fF2Sp4gvMPomLfbmQQsVNu7y7EipHfAKv8UQCAwY8pknvkQzPXwetnfY-oZiT-_L4zpXMh2DP7wJf2FXBw2HG-EnTEuBjCERR51ufTHwDbQpQblJSm-2AWwtPJQ/s72-c/Dynamics+AX+2012_Project.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-4962564794823421431</id><published>2011-10-10T23:09:00.000+05:30</published><updated>2011-10-10T23:09:33.862+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="QueryDataSourceStr"/><title type='text'>QueryDataSourceStr - new intrinsic function in Dynamics AX 2012</title><content type='html'>There is a new intrinsic function introduced in Dynamics AX 2012. This is the &lt;b&gt;QueryDataSourceStr()&lt;/b&gt; function. This function returns a string of the datasource name.&lt;br /&gt;
&lt;br /&gt;
The &lt;b&gt;queryDataSourceStr()&lt;/b&gt; function checks if the supplied datasource name exists in the query in the AOT or not.&lt;br /&gt;
&lt;br /&gt;
An important point to note here is that all the intrinsic functions like formStr, classStr, queryStr and queryDataSourceStr invoke real time compiler check. This means that the compiler checks for the existence of the object in the AOT as soon as the function call is completed. In case the object name is not found, an error is shown immediately by displaying a red squiggly line.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/4962564794823421431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/4962564794823421431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4962564794823421431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4962564794823421431'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/10/querydatasourcestr-new-intrinsic.html' title='QueryDataSourceStr - new intrinsic function in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-2611602380153713965</id><published>2011-09-29T21:03:00.000+05:30</published><updated>2011-09-29T21:03:05.584+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="Form templates"/><category scheme="http://www.blogger.com/atom/ns#" term="Form User Experience Guidelines"/><title type='text'>Form templates in Dynamics AX 2012</title><content type='html'>A primary focus in Dynamics AX 2012 was to increase a developer&#39;s productivity by automating common tasks. As part of this initiative, a new feature was introduced in Dynamics AX 2012 in the AOT. This is the creation of new forms using form templates. &lt;br /&gt;
&lt;br /&gt;
If you right click on the form node, you can see an extra option there - &lt;b&gt;New Form from template&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSwEmm5Mlf0-_zATrEagqhXh7RK1-YZBmqdVcheq2TzVZbzXUlZPFJFAM1J53aeVsoPC-yezyaKAhyphenhyphenAXU5PtHuhDXby52y5BVerpZjoJbLL_6ZQCIrnagHxDZdYKYdgrugPkoSwrz6HlU/s1600/Dynamics_AX_2012_New_form.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;224&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSwEmm5Mlf0-_zATrEagqhXh7RK1-YZBmqdVcheq2TzVZbzXUlZPFJFAM1J53aeVsoPC-yezyaKAhyphenhyphenAXU5PtHuhDXby52y5BVerpZjoJbLL_6ZQCIrnagHxDZdYKYdgrugPkoSwrz6HlU/s400/Dynamics_AX_2012_New_form.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;As seen in the image above, you have an option to create seven different form based on the pre-defined templates, these are&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;ListPage&lt;/li&gt;
&lt;li&gt;DetailsFormMaster&lt;/li&gt;
&lt;li&gt;DetailsFormTransaction&lt;/li&gt;
&lt;li&gt;SimpleListDetails&lt;/li&gt;
&lt;li&gt;SimpleList&lt;/li&gt;
&lt;li&gt;TableOfContents&lt;/li&gt;
&lt;li&gt;Dialog&lt;/li&gt;
&lt;li&gt;DropDialog&lt;/li&gt;
&lt;/ul&gt;Let us look at these in more details.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ListPage&lt;/b&gt; - A list page is a form that displays a list of data related to a particular entity or business object. A list page provides provisions for displaying data and taking actions on this data. Every module has at least a couple of list pages. List pages are further classified as primary and secondary list pages. A secondary list page will only display a subset of data from the primary list page. Example, CustTableListPage, VendTableListPage, ProjProjectsListPage. Best practice is to have ListPage as a suffix in the name of the form for all list pages.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DetailsFormMaster&lt;/b&gt; - This template is used for forms which displays data for stand-alone entities or business objects. Example, Customers, Vendors, Projects etc. If you look at the forms for these, i.e., CustTable, VendTable, ProjTable, their style property will be set to DetailsFormMaster.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DetailsFormTransaction&lt;/b&gt; - This template is used for forms which displays data for entities which have child records associated with it. In other words, if the data being displayed is header-lines type in nature, use this template. Example, Sales orders, Purchase orders etc. If you look at the style property of SalesTable, VendTable, their properties will be set to DetailsFormTransaction.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SimpleListDetails&lt;/b&gt; - This template is used to display primary fields in a list and detailed data in a tab page. This style is useful to view all records in a form and selecting a particular record will bring up their details. Example, MainAccount&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SimpleList&lt;/b&gt; - This template is a very basic form which displays data in a grid. No extra or fancy detail is displayed. This style is best suited for forms where data being shown is not very detailed in nature or has limited fields. Example, AifAction.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TableOfContents&lt;/b&gt; - This template is the new style which should be adopted for all parameter forms in Dynamics AX 2012. Take a look at any parameters form and its style property will be set to TableOfContents. This style sets all the tabs as a hot link in the left hand side navigation pane. Clicking on the link will bring up the controls on that tab page. This style is a very neat and appealing UI design which is surely welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dialog&lt;/b&gt; - This template is used on forms which shows static data or are intended to capture some user input for further actions. These forms are mostly modal in nature and should be dismissed before any further actions can be taken.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DropDialog&lt;/b&gt; - This template is used for forms that are used to gather quick user inputs to perform an action. Drop dialog forms are generally attached to an action pane button. They appear to be dropping from the menu button when clicked.&lt;br /&gt;
&lt;br /&gt;
Whenever going for a new form development, always ensure that you use the template to create a new form. The template almost does 40% of your design work for you. All you have to do is add the data sources and fields and add business logic.&lt;br /&gt;
&lt;br /&gt;
Microsoft has taken a lot of customer feedback and invested a lot in the UI design. There are reasons why the buttons and navigations are laid out like they are. If you are deviating from the recommended best practices, not only are you introducing best practice deviations, you may be complicating the design and navigation for your users.&lt;br /&gt;
&lt;br /&gt;
In case, you already have designed forms without using the pre defined templates, you can run the form style best practices checker from add-ins. This will list out all deviations your form has and you can fix them by clicking a button.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUtVg6ic_Zva2bda0oh6xZbfMRP4hQ3xuwITVhmwrvQi8cFNiWvOC-ArNBSg-USYzpZ3m47ssBN6iP3nfraf0izi9m3K9eASEqxe7ytgohBMCrLGeHeSDszFEWMDN2rVszbhyphenhyphenJmpPf6Sc/s1600/Dynamics_AX_2012_Form_style_checker.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;399&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUtVg6ic_Zva2bda0oh6xZbfMRP4hQ3xuwITVhmwrvQi8cFNiWvOC-ArNBSg-USYzpZ3m47ssBN6iP3nfraf0izi9m3K9eASEqxe7ytgohBMCrLGeHeSDszFEWMDN2rVszbhyphenhyphenJmpPf6Sc/s400/Dynamics_AX_2012_Form_style_checker.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Also, you may see some best practice warnings when designing forms using the templates. These can be safely ignored. Examples of such best practice warnings are&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;An Action Pane should not be present on a form that is not a list page or other content page.&lt;/li&gt;
&lt;li&gt;Expected: @SYS316708 (Attachments) | Actual: @SYS114630 (Attachments)&lt;/li&gt;
&lt;/ul&gt;Even though, these are listed as best practice warnings, there are numerous samples in standard AX forms where these deviations have been made.&lt;br /&gt;
&lt;br /&gt;
For more details on the new Dynamics AX 2012 forms and their design guidelines, check the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg886605.aspx&quot;&gt;Form User Experience Guidelines page&lt;/a&gt; on MSDN. &lt;br /&gt;
&lt;br /&gt;
I hope this post was useful and you will start using the new templates in your development.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, do check back soon for more updates.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/2611602380153713965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/2611602380153713965' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2611602380153713965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2611602380153713965'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/09/form-templates-in-dynamics-ax-2012.html' title='Form templates in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSwEmm5Mlf0-_zATrEagqhXh7RK1-YZBmqdVcheq2TzVZbzXUlZPFJFAM1J53aeVsoPC-yezyaKAhyphenhyphenAXU5PtHuhDXby52y5BVerpZjoJbLL_6ZQCIrnagHxDZdYKYdgrugPkoSwrz6HlU/s72-c/Dynamics_AX_2012_New_form.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-5903510867931075434</id><published>2011-09-28T20:54:00.001+05:30</published><updated>2011-09-28T21:03:20.983+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Debug BP error"/><category scheme="http://www.blogger.com/atom/ns#" term="Diagnostic ID"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="Only foreign key constraints are allowed on this table"/><title type='text'>Debug BP errors in Dynamics AX 2012</title><content type='html'>With Dynamics AX 2012, some new BP errors have been introduced. Often, while fixing BP errors, I turn to the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb530207(v=AX.50).aspx&quot;&gt;List of Best Practice Error and Warning Messages page&lt;/a&gt; on MSDN for help.&lt;br /&gt;
&lt;br /&gt;
But what if you are getting a BP error and there is no clear description on how to fix it. In such scenarios, I always debug the BP error and try to see what is causing this BP error in the first place.&lt;br /&gt;
&lt;br /&gt;
Let us do this with a simple example.&lt;br /&gt;
&lt;br /&gt;
On a Dynamics AX 2012 machine, Create a table with just two fields, ItemId and Name.&lt;br /&gt;
&lt;br /&gt;
Create a normal relation on the table with InventTable on ItemId == InventTable.ItemId&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNyD9Mj2P09nnz3sUuKF3tza77kwRV8IqbrzNjMVMjxXWSrSV4HkMsR_UYQPu63tcdNueEE8KXe0BvOzwoiOcCoqjBZbYnC8GuZUfGj0CCG7-9BMeDjPG-PUNNer8Pqgp8RX-Y4rqSjNA/s1600/Dynamics_AX_Sample_table.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;193&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNyD9Mj2P09nnz3sUuKF3tza77kwRV8IqbrzNjMVMjxXWSrSV4HkMsR_UYQPu63tcdNueEE8KXe0BvOzwoiOcCoqjBZbYnC8GuZUfGj0CCG7-9BMeDjPG-PUNNer8Pqgp8RX-Y4rqSjNA/s320/Dynamics_AX_Sample_table.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;On running the BP check on this table, among other BP errors, you will receive this new to Dynamics AX 2012 BP error - &lt;b&gt;Only foreign key constraints are allowed on this table.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Some of you may know the reason why this BP error is being thrown. For those who do not know the reason, please hold on to that doubt, I&#39;ll explain it shortly in the end. Let us get back to the original topic of the post, how to debug this BP error and find out why it is being thrown?&lt;br /&gt;
&lt;br /&gt;
If you look at the compiler output window, you will find a column titled Diagnostic ID. This is new in Dynamics AX 2012. So what does this column specify? Well, the diagnostic ID is the value of the BP error macro being thrown.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQoIeSjwoXacBRCS44959q9cUKKO2hGe2keS9vPZJA-6UxBpM_rcCO8RapVQrulbfC4WykWVN9lpTnLmQj5NksSLsgkVl8tf-FAZ-z6Vs8Gjsmw0N2BrPBGr3tWLPuWelBRQWb5mHQQpY/s1600/Dynamics_AX_2012_Compiler_output.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;22&quot; width=&quot;400&quot; src=&quot;http://1.bp.blogspot.com/-WL9_YOGuzAc/ToM6owf4GNI/AAAAAAAAALA/PMwPABowk-
Y/s1600/Dynamics_AX_2012_Compiler_output.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
In our case, the diagnostic ID for the BP error &lt;b&gt;Only foreign key constraints are allowed on this table&lt;/b&gt; is &lt;b&gt;839&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Now, let us open the SysBPCheck macro and search for 839. This is what we will find&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;#define.BPErrorTableNaturalKeyWithRecID(839)    // RecID field cannot be part of the NaturalKey index.&lt;/pre&gt;&lt;br /&gt;
Ok, so this means that somewhere in code, a BP error is being raised with this macro. Copy the macro name and search in the BP classes of the object type.&lt;br /&gt;
&lt;br /&gt;
The BP classes start with SysBPCheck. In our case, since the error was being thrown on a table, we will search in all the classes related to tables.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3dd-UGSUZTe9SY8-8t4hyBbYPdlKrWZzuVqMR96qxehFwDBwfJgMMtYffpuzeYEsqTQsIe_Zz6YLL8FZcyA-Al0iUNt0u3wiO2TFqVpCIHOUsxHDHrn3XM6wQS_hQmZY_KdikH8nGk5Y/s1600/Dynamics_AX_Search_BP_classes.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;75&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3dd-UGSUZTe9SY8-8t4hyBbYPdlKrWZzuVqMR96qxehFwDBwfJgMMtYffpuzeYEsqTQsIe_Zz6YLL8FZcyA-Al0iUNt0u3wiO2TFqVpCIHOUsxHDHrn3XM6wQS_hQmZY_KdikH8nGk5Y/s320/Dynamics_AX_Search_BP_classes.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;As seen in the image above, we found two instances of the macro in code. Open both the instances and check for the error message. The error in the second instance matches with the error we saw in the compiler output. So our error is being thrown from this location. If you want to confirm, you can set a break point here and run the BP check again on the table, the break point will be hit.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFIu6WMX1L396JjNS3b5GcspxhPjW7SMRBhnhq9AnmCgLjoZKZdjsZlq8TBILr98ryOSlQ2PWp6WzsiTpNQ7jqM31foPEUCdKKAg2a7u8l1dLktz9RrJIjwyDqfPpBs8ye8OiWJjav1NM/s1600/Dynamics_AX_BP_Error_in_code.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;136&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFIu6WMX1L396JjNS3b5GcspxhPjW7SMRBhnhq9AnmCgLjoZKZdjsZlq8TBILr98ryOSlQ2PWp6WzsiTpNQ7jqM31foPEUCdKKAg2a7u8l1dLktz9RrJIjwyDqfPpBs8ye8OiWJjav1NM/s320/Dynamics_AX_BP_Error_in_code.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Now if you scroll the code a little up, you will see why this condition is being hit. The code is&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;//If we need to Enforce RelationRules, Check to see if this is FK relation.
            //If it is not and FK check is not skipped, throw BP error if:
            //1. Not a Migrated relation (OR)
            //2. There is no Covering PKAK Index on the related Table covering the related fields in the relation

            if(sysDictTable.enforceRelationRules())
            {
                if(!foreignKeyRelation &amp;&amp; !skipFKCheck)
                {
                    //Dont Relax the BP error if:
                    //1. if the relation is not EDT relation (OR)
                    //2. The relation has ThisFieldFixed relationLines(OR)
                    //3. The relation has all Normal Field relations (OR)
                    //4. if the related Fields is not covered by PK or AK index in the related Table

                    if(!dictRelation.EDTRelation() || nonConfirmingRelationLines || (conLen(fixedFieldList)==0) || !relatedFieldsCoveredByPKAKIndex(joinDictTable,normalFieldList,fixedFieldList))
                    {
                        sysBPCheck.addError(#BPErrorTableNaturalKeyWithRecID,i,0,&quot;@SYS129769&quot;);  //use i as line number to avoid reporting identical BP errors, if multiple relations have the same error.
                    }
                }
            }
&lt;/pre&gt;So, in our case we see that this is not a foreign key relation hence the condition is satisfied and the error is thrown. I&#39;ll not go in the detail of the code, you can debug and find out what it means.&lt;br /&gt;
&lt;br /&gt;
For those of you who were wondering the reason for this BP error, it is because we should create a new Foreign key based relation instead of a normal relation.&lt;br /&gt;
&lt;br /&gt;
Simply put, when you drag and drop the ItemID EDT on the table, it will ask for your confirmation to add the relation on the EDT. The dialog will be like this&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqYUb2uzXq_MqmcbGRqWKl5VbZhfyjqeFSx4bqVnyVv3Fx758cFdXGrtCHV8cXhDS5XrhJmc9tahdTEM4XyV8tI5HqopXgK72Dbkt7D0y4zNKeABP-ODuk_l5U5LFjFIU-TPJoEk-zC88/s1600/Dynamics_AX_Add_relation.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;112&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqYUb2uzXq_MqmcbGRqWKl5VbZhfyjqeFSx4bqVnyVv3Fx758cFdXGrtCHV8cXhDS5XrhJmc9tahdTEM4XyV8tI5HqopXgK72Dbkt7D0y4zNKeABP-ODuk_l5U5LFjFIU-TPJoEk-zC88/s320/Dynamics_AX_Add_relation.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Press Yes and a Foreign key based relation will be created. If you press No and want to create the relation manually, make sure you create a Foreign key based relation and not a normal relation.&lt;br /&gt;
&lt;br /&gt;
Both the normal and foreign key relation looks the same and it is visually difficult to differnetiate between them. So, if you ever encounter the above mentioned BP and have a relation defined, delete and recreate a new foreign key relation.&lt;br /&gt;
&lt;br /&gt;
I hope this post was helpful. Please feel free to send me your queries and feedback.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, check back soon for more.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/5903510867931075434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/5903510867931075434' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5903510867931075434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5903510867931075434'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/09/debug-bp-errors-in-dynamics-ax-2012.html' title='Debug BP errors in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNyD9Mj2P09nnz3sUuKF3tza77kwRV8IqbrzNjMVMjxXWSrSV4HkMsR_UYQPu63tcdNueEE8KXe0BvOzwoiOcCoqjBZbYnC8GuZUfGj0CCG7-9BMeDjPG-PUNNer8Pqgp8RX-Y4rqSjNA/s72-c/Dynamics_AX_Sample_table.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7331026129041401671</id><published>2011-09-06T21:15:00.001+05:30</published><updated>2011-09-06T21:18:58.198+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="match function"/><category scheme="http://www.blogger.com/atom/ns#" term="Regular expressions"/><title type='text'>Regular expressions in Dynamics AX</title><content type='html'>In all versions of Dynamics AX, the Find window supports regular expressions. Recently I discovered that even the label editor supports regular expressions.&lt;br /&gt;
&lt;br /&gt;
Using regular expressions in the find window and the label editor can significantly reduce your search times and you can narrow down your search to exactly what you are searching for.&lt;br /&gt;
&lt;br /&gt;
Let us look at some example.&lt;br /&gt;
&lt;br /&gt;
Suppose I want to search for all classes which have methods which are named like the following,&lt;br /&gt;
&lt;br /&gt;
enable(Any text here)Buttons.&lt;br /&gt;
&lt;br /&gt;
So all names like enableActivityButtons, enableDisableButtons, enableAllButtons etc should be found.&lt;br /&gt;
&lt;br /&gt;
So, we first need to analyze our expression requirement. Our search string should start with &lt;b&gt;enable&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
For that, we need to enter &lt;b&gt;&amp;lt;enable&lt;/b&gt;. The &lt;b&gt;&amp;lt;&lt;/b&gt; character matches the specified string at the start of the string.&lt;br /&gt;
&lt;br /&gt;
Similiarly, for matching Buttons at the end of the string, we need to specify &lt;b&gt;Button&amp;gt;&lt;/b&gt;. The &lt;b&gt;&amp;gt;&lt;/b&gt; character matches the specified string before it at the end of the string.&lt;br /&gt;
&lt;br /&gt;
So, will just giving &lt;b&gt;&amp;lt;enablebuttons&amp;gt;&lt;/b&gt; in the find window work?&lt;br /&gt;
&lt;br /&gt;
The answer is no because this pattern will try to match a method name which is just enableButtons. But we are looking for some text between enable &amp; buttons. To specify this we need to use the &lt;b&gt;:a+&lt;/b&gt; combination.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;:a&lt;/b&gt; means match any character and &lt;b&gt;+&lt;/b&gt; suggests matching 1 or more occurences of the preceding character.&lt;br /&gt;
&lt;br /&gt;
So our complete match pattern should be &lt;b&gt;&amp;lt;enable:a+Buttons&amp;gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So if you enter this, it will search for all methods which have a name patter like this.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsXiqc-wqjIhID94-7qdBZvRWm3blPHHuIr9Q9dG3NmgpxofMZPrVdBcFrAQ7xHaD1hyphenhyphenK42PX77NiS8BpJq4iNNRGMsrLO6I54zs5U3HtjaGnmeymbWcvhGRxW6KpiDxxeKrOVD9nLQXU/s1600/Dynamics_AX_regular_expressions_in_find_window.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;210&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsXiqc-wqjIhID94-7qdBZvRWm3blPHHuIr9Q9dG3NmgpxofMZPrVdBcFrAQ7xHaD1hyphenhyphenK42PX77NiS8BpJq4iNNRGMsrLO6I54zs5U3HtjaGnmeymbWcvhGRxW6KpiDxxeKrOVD9nLQXU/s320/Dynamics_AX_regular_expressions_in_find_window.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;As you can see in the above image, all method names which begin with enable and end with Buttons has been fetched.&lt;br /&gt;
&lt;br /&gt;
Similiarly, you can also use these regular expressions in the label editor as well.&lt;br /&gt;
&lt;br /&gt;
Suppose, I want to see if I have a label like &lt;b&gt;&quot;Cannot copy the information to the source&quot;&lt;/b&gt;. Now, I can straight forward enter the label and try to find it. But I would also like to see what other variations may exists. So, even if the label is &lt;b&gt;&quot;Cannot copy the data to the %1&quot;&lt;/b&gt;, I can still reuse it. So to search for such labels, I formulate my pattern like &lt;b&gt;&amp;lt;Cannot copy&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This way, all labels which start with &lt;b&gt;Cannot copy&lt;/b&gt; will be fetched.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8VGIzfrAe4JrQk9wtdk3YU898KBn_vNOtqnR_XvO04RLU-gkdiGdjUiormtM2f_xvBkPTWrWtWa1NGjxkPnZfnI6-5eJKslOYUNiTvV7AAEje2rk1VfAB4ZLPrKXH4btmFx1WxchWwPo/s1600/Dynamics_AX_regular_expressions_in_label_editor.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;204&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8VGIzfrAe4JrQk9wtdk3YU898KBn_vNOtqnR_XvO04RLU-gkdiGdjUiormtM2f_xvBkPTWrWtWa1NGjxkPnZfnI6-5eJKslOYUNiTvV7AAEje2rk1VfAB4ZLPrKXH4btmFx1WxchWwPo/s320/Dynamics_AX_regular_expressions_in_label_editor.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
At first, using regular expressions may feel like a pain but they are very powerful and will speed up your searches.&lt;br /&gt;
&lt;br /&gt;
For a complete list of pattern formulation, check the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa886279.aspx&quot;&gt;Match function on MSDN&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/7331026129041401671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/7331026129041401671' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7331026129041401671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7331026129041401671'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/09/regular-expressions-in-dynamics-ax.html' title='Regular expressions in Dynamics AX'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsXiqc-wqjIhID94-7qdBZvRWm3blPHHuIr9Q9dG3NmgpxofMZPrVdBcFrAQ7xHaD1hyphenhyphenK42PX77NiS8BpJq4iNNRGMsrLO6I54zs5U3HtjaGnmeymbWcvhGRxW6KpiDxxeKrOVD9nLQXU/s72-c/Dynamics_AX_regular_expressions_in_find_window.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-5334170870059375913</id><published>2011-08-29T23:06:00.001+05:30</published><updated>2011-08-29T23:09:12.526+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="The field with ID &#39;0&#39; does not exist in table"/><title type='text'>The field with ID &#39;0&#39; does not exist in table - Cause and resolution.</title><content type='html'>Hello readers,&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX coding, you should have come across this error sometime - &lt;b&gt;The field with ID &#39;0&#39; does not exist in table &#39;SomeTable&#39;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So what causes this error and what is the possible resolution to it?&lt;br /&gt;
&lt;br /&gt;
Well, the most likely cause for this error is a missing mapping in a table map.&lt;br /&gt;
&lt;br /&gt;
Let us look at an example.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve a simple Map named CustVendAccount with one Account field. I&#39;ve created two mappings - one with CustTable&#39;s AccountNum field and for the otehr mapping, I just specify VendTable but no field.&lt;br /&gt;
&lt;br /&gt;
This is how my map looks like,&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Sv6j8QVg3XmkTJGBZF2a9P2RMDmorPXBuINlO2fdSgLZoFMDVkMsKKcSlbg_s7BfCJuOxDXFQpnxBmzonfaqnekMcyJXUuxSAxPm3MHf-22uidM3MNIwRfz__pwZNh1WFJOHln1m7-8/s1600/Dynamics_AX_Simple_table_map.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;143&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Sv6j8QVg3XmkTJGBZF2a9P2RMDmorPXBuINlO2fdSgLZoFMDVkMsKKcSlbg_s7BfCJuOxDXFQpnxBmzonfaqnekMcyJXUuxSAxPm3MHf-22uidM3MNIwRfz__pwZNh1WFJOHln1m7-8/s320/Dynamics_AX_Simple_table_map.png&quot; alt=&quot;Dynamics AX - Simple table map&quot;/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Now, I&#39;ve a simple job which just passes either CustTable or VendTable as an argument and then we print the Account field in the map.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;static void CustVendAccountMap(Args _args)
{
    CustTable   custTable;
    VendTable   vendTable;

    void readMap(CustVendAccount _custVendAccount)
    {
        info(strFmt(&quot;Value from table %1 is %2&quot;,tableId2name(_custVendAccount.TableId), _custVendAccount.Account));
    }

    select firstOnly custTable;
    select firstOnly vendTable;

    readMap(custTable);
    readMap(vendTable);

    pause;
}
&lt;/pre&gt;&lt;br /&gt;
If you run the job, you will get a run time error and the debugger will break at line 8 with this error.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggvAYgUa5r6smKpeXbJN_A6aLz5JYpYo8utmgbq-DLPkc9_K2qlFiZjnxKn2iqz4BN0oXjkE8HC-iQwBYkNiopwB9ep9n05uCKmql1iJN15jWwCPP6whn2_eKqQqRmldmjO41i41jZ_f0/s1600/Dynamics_AX_The_field_with_ID_%25270%2527_does_not_exist_in_table.png&quot; imageanchor=&quot;1&quot; style=&quot;clear:right; float:right; margin-left:1em; margin-bottom:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;149&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggvAYgUa5r6smKpeXbJN_A6aLz5JYpYo8utmgbq-DLPkc9_K2qlFiZjnxKn2iqz4BN0oXjkE8HC-iQwBYkNiopwB9ep9n05uCKmql1iJN15jWwCPP6whn2_eKqQqRmldmjO41i41jZ_f0/s320/Dynamics_AX_The_field_with_ID_%25270%2527_does_not_exist_in_table.png&quot; alt=&quot;Dynamics AX - The field with ID 0 does not exist in table&quot;/&gt;&lt;/a&gt;&lt;/div&gt;As you can see from the image, the error says that &lt;b&gt;The field with ID &#39;0&#39; does not exist in table &#39;VendTable&#39;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In our CustVendAccount map, we didn&#39;t map the Account field with any field from the VendTable table. Because of this misssing mapping, the field has an ID of zero and an error is thrown.&lt;br /&gt;
&lt;br /&gt;
So the next time, you hit this error, check your field mapping in your map. This should save you a lot of time.&lt;br /&gt;
&lt;br /&gt;
I hope this post was useful.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, check back soon.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/5334170870059375913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/5334170870059375913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5334170870059375913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5334170870059375913'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/field-with-id-0-does-not-exist-in-table.html' title='The field with ID &#39;0&#39; does not exist in table - Cause and resolution.'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Sv6j8QVg3XmkTJGBZF2a9P2RMDmorPXBuINlO2fdSgLZoFMDVkMsKKcSlbg_s7BfCJuOxDXFQpnxBmzonfaqnekMcyJXUuxSAxPm3MHf-22uidM3MNIwRfz__pwZNh1WFJOHln1m7-8/s72-c/Dynamics_AX_Simple_table_map.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7729594403015949955</id><published>2011-08-26T22:54:00.001+05:30</published><updated>2011-08-26T22:55:24.012+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="keywords"/><title type='text'>Problem caused by using keyword as object name in Dynamics AX</title><content type='html'>Hello Readers,&lt;br /&gt;
&lt;br /&gt;
When creating objects in Dynamics AX, it is advisable to use names which are not any keywords in Dynamics AX. Otherwise, you can end up with unexpected behavior.&lt;br /&gt;
&lt;br /&gt;
A list of all keywords in Dynamics AX 2012 can be found &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa661012.aspx&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I discovered one such issue in standrd Dynamics AX.&lt;br /&gt;
&lt;br /&gt;
Take a look at the table InventBuyerGroup. It has two fields named Group &amp; Description.&lt;br /&gt;
&lt;br /&gt;
Now suppose if I want to select the field Group from the table using a select statement, how will I do it?&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;InventBuyerGroup inventBuyerGroup;

select group from inventBuyerGroup;
&lt;/pre&gt;Simple, So what is the catch you may ask? Well, the above statement will &lt;b&gt;not compile and give an error&lt;i&gt;&lt;/i&gt;&lt;/b&gt;. That is because the field name &lt;b&gt;group&lt;/b&gt; is also a keyword in Dynamics AX. So, the compiler gets confused and cant understand that it is the field name that we are trying to refer here.&lt;br /&gt;
&lt;br /&gt;
I&#39;m not aware of any way of getting this work. Of course, there are workarounds like using a map but is that really needed? We can avoid a whole lot of this by just ensuring that we dont end up using any Dynamics AX keywords as object names.&lt;br /&gt;
&lt;br /&gt;
Thats all for today. Check back soon for more.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;P.S. By the way, does anyone know how we can get the above select statement to work? Don&#39;t lose too much sleep on it though... :)&lt;/b&gt;</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/7729594403015949955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/7729594403015949955' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7729594403015949955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7729594403015949955'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/keyword-usage-in-dynamics-ax.html' title='Problem caused by using keyword as object name in Dynamics AX'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7716755659072720629</id><published>2011-08-24T22:29:00.000+05:30</published><updated>2011-08-24T22:29:05.426+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="number sequence"/><category scheme="http://www.blogger.com/atom/ns#" term="NumberSeqApplicationModule::loadall"/><category scheme="http://www.blogger.com/atom/ns#" term="NumberSeqModule"/><title type='text'>New number sequence not visible in Dynamics AX 2012. How to fix it?</title><content type='html'>&lt;br /&gt;
Hello readers,&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX 4.0 and Dynamics AX 2009, if you created a new number sequence reference, you would restart the AOS to see the new number sequence reference in the parameters form of your module. That was all you had to do to get the new reference reflected.&lt;br /&gt;
&lt;br /&gt;
Try the same in Dynamics AX 2012 and you will be pleasantly suprised(or maybe bewildered) to not find the number sequence reference showing in the parameters form. This is because the numberSequence tables are no longer populated when you restart the AOS. This was an additional task that was done in Dynamics AX 4.0 and Dynamics AX 2009 everytime you restarted the AOS. In Dynamics AX 2012, the number sequence tables are populated when you select the appropriate task in the initialization checklist.&lt;br /&gt;
&lt;br /&gt;
So, how do we work around this issue?&lt;br /&gt;
&lt;br /&gt;
Simple. Just call the &lt;b&gt;load()&lt;/b&gt; method on your module&#39;s number sequence class.&lt;br /&gt;
&lt;br /&gt;
For example, suppose I&#39;ve added a new number sequence to the Sales and Marketing module(CRM).&lt;br /&gt;
&lt;br /&gt;
So my code will be,&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;    NumberSeqModuleCRM module;
    module = new NumberSeqModuleCRM();
    module.load();
&lt;/pre&gt;If you have added multiple number sequences to multiple modules, you can simply call the &lt;b&gt;NumberSeqApplicationModule::loadall()&lt;/b&gt; method and it will create all the number sequences.&lt;br /&gt;
&lt;br /&gt;
Be aware that when reinitializing all number sequence references, there should be no existing number sequences already defined in the system or you will get a duplicate record exception.&lt;br /&gt;
&lt;br /&gt;
Thats all for today. Do check back soon as we keep learning.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/7716755659072720629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/7716755659072720629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7716755659072720629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7716755659072720629'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/new-number-sequence-not-visible-in.html' title='New number sequence not visible in Dynamics AX 2012. How to fix it?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-2490429004476882468</id><published>2011-08-23T00:24:00.003+05:30</published><updated>2011-08-23T00:45:59.153+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="DateTimeUtil"/><category scheme="http://www.blogger.com/atom/ns#" term="DateTimeUtil::addDays"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="Futures"/><title type='text'>Futures class in Dynamics AX</title><content type='html'>In Dynamics AX, if you want to find a date in a period, chances are you would be using the &lt;b&gt;DateTimeUtil&lt;/b&gt; class.&lt;br /&gt;
&lt;br /&gt;
Say, I want to find the date 3 months exactly from today. Assuming a month is of 30 days, I can call the &lt;b&gt;DateTimeUtil::addDays()&lt;/b&gt; method.&lt;br /&gt;
&lt;br /&gt;
So my code to get that will be,&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;print DateTimeUtil::date(DateTimeUtil::addDays (DateTimeUtil::utcNow(), 3 * 30));
&lt;/pre&gt;&lt;br /&gt;
There is another application class in Dynamics AX, which does exactly this. This is the &lt;b&gt;Futures&lt;/b&gt; class.&lt;br /&gt;
&lt;br /&gt;
Let us see this class in action.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;static void FuturesClass(Args _args)
{
    Futures     future;
    int         i;
    
    // Setup a future class object with 365 days as a period
    future = new Futures(systemDateGet(), 365, PeriodUnit::Day);

    future.next();    
    
    info(strFmt(&quot;Future date after 3 months from today is %1&quot;,future.transDate()));
    
    // Setup a future class object with 1 year as a period
    future = new Futures(systemDateGet(), 1, PeriodUnit::Year);
    
    for (i=1; i&lt;=3; i++)
    {
        future.next();
    }
    
    info(strFmt(&quot;Future date after 3 years from today is %1&quot;,future.transDate()));
    
    // Setup a future class object with 1 month as a period    
    future = new Futures(systemDateGet(), 1, PeriodUnit::Month);
    
    for (i=1; i&lt;=3; i++)
    {
        future.next();
    }
    
    info(strFmt(&quot;Future date after 3 months from today is %1&quot;,future.transDate()));    
}
&lt;/pre&gt;
The output is
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtb2uwglTzWtorgb7wfvfd9ZihFibQx2V0Z1pDJbVO6aHZItNPnOKkibM6hXZlYcbBGgiY6FPbwBbbjSOyINZCzUhHDTQ3y40CKbqc-tfypiooRP-eXCDD-UPHIvCu1G_kvGfFHn1-qrA/s1600/Dynamics+AX_Futures.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;129&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtb2uwglTzWtorgb7wfvfd9ZihFibQx2V0Z1pDJbVO6aHZItNPnOKkibM6hXZlYcbBGgiY6FPbwBbbjSOyINZCzUhHDTQ3y40CKbqc-tfypiooRP-eXCDD-UPHIvCu1G_kvGfFHn1-qrA/s320/Dynamics+AX_Futures.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;The Futures class is initialized by passing three values. The start date of the period, length of the period and the Period unit. The Period unit can be day, month or year.

So when we create a new object specifying today&#39;s date as the start date, 15 as the period and day as the unit, it means each period in this instance will be 15 days long. So if I call the &lt;b&gt;future.next()&lt;/b&gt; method, I will get a date exactly 15 days from now.&lt;br /&gt;
&lt;br /&gt;
So what are the advantages of this over the DateTimeUtil class? Well, the readibility of the code is obvious. Apart from this, you dont have to worry about missing days in a period and the extra calculation needed.&lt;br /&gt;
&lt;br /&gt;
For example, lets say today is 23rd August. August has 31 days, September 30 and October 31 days. So we need to add 92 days in total, which gives us 22nd November. But if I need to use the DateTimeUtil class for that, I have to do the days calculation myself whereas the Future&#39;s class handles this automatically.&lt;br /&gt;
&lt;br /&gt;
The Futures class is a nice little helper class which can be helpful when calculating periods of given length in days, months or years.&lt;br /&gt;
&lt;br /&gt;
I hope this post was helpful. Do send me your comments.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, do check back soon.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/2490429004476882468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/2490429004476882468' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2490429004476882468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/2490429004476882468'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/futures-class-in-dynamics-ax.html' title='Futures class in Dynamics AX'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtb2uwglTzWtorgb7wfvfd9ZihFibQx2V0Z1pDJbVO6aHZItNPnOKkibM6hXZlYcbBGgiY6FPbwBbbjSOyINZCzUhHDTQ3y40CKbqc-tfypiooRP-eXCDD-UPHIvCu1G_kvGfFHn1-qrA/s72-c/Dynamics+AX_Futures.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-6225655900926135109</id><published>2011-08-19T23:46:00.002+05:30</published><updated>2011-08-19T23:48:46.855+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Budget control"/><category scheme="http://www.blogger.com/atom/ns#" term="controlId"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="formControlStr"/><title type='text'>How to refer to form controls in code without setting the AutoDeclaration property in Dynamics AX?</title><content type='html'>Hello readers,&lt;br /&gt;
&lt;br /&gt;
On a Dynamics AX form, if you want to refer to a particular control in code, the surest way you would take is to set the &lt;b&gt;AutoDeclaration&lt;/b&gt; property to Yes. This will let you refer the control in code. There is nothing wrong with this approach and it is quite common in standard Dynamics AX codebase.&lt;br /&gt;
&lt;br /&gt;
But in some cases, it is preferred not to use this approach. So what is this case?&lt;br /&gt;
&lt;br /&gt;
Consider a scenario where you are customizing a standard form. You want to disable a particular field based on a field value.&lt;br /&gt;
&lt;br /&gt;
To achieve this,&lt;br /&gt;
&lt;br /&gt;
- You will set the AutoDeclaration property of the control to Yes&lt;br /&gt;
- In the active method of the datasource, you will disable the control based on a condition.&lt;br /&gt;
&lt;br /&gt;
Now, the active() method&#39;s modification can be easily seen in the AOT but the change in property isn&#39;t readily noticed unless you perform a layer compare.&lt;br /&gt;
&lt;br /&gt;
Normally, in cuztomization it is a best practise to add customization tags to show what part is customized code and what is standard. But there is no way we can add a customization tag to properties that have changed.&lt;br /&gt;
&lt;br /&gt;
Coming back to the main topic, so how do we refer to a control in code without setting AutoDeclaration to Yes.&lt;br /&gt;
&lt;br /&gt;
The answer lies in the control() method of formRun class.&lt;br /&gt;
&lt;br /&gt;
So let us say my control name is AccountNum and form name is Address. So my code will look something like this,&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;element.control(control::AccountNum).enabled(false);
&lt;/pre&gt;The &lt;b&gt;control::&lt;/b&gt; enum enumerates all controls on the given form. The only problem is that you wont get an intellisense on the control names. Just type it and then compile.&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX 2012, we have a new method &lt;b&gt;controlId()&lt;/b&gt; on the formRun class. This in conjunction with the new intrinsic method &lt;b&gt;formControlStr()&lt;/b&gt; can be used to get the control id.&lt;br /&gt;
&lt;br /&gt;
So the above line of code will be written as following in Dynamics AX 2012&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;// This is the line in Dynamics AX 2009
element.control(control::AccountNum).enabled(false);

// And this is how it should be written in Dynamics AX 2012
element.control(element.controlId(formControlStr(Address, AccountNum))).enabled(false);
&lt;/pre&gt;Although, there is nothing wrong in setting AutoDeclaration to Yes for customization, it is a cleaner approach to just reference the control in code using the above method.&lt;br /&gt;
&lt;br /&gt;
I hope this post was helpful. Please leave your comments &lt;a href=&quot;http://www.blogger.com/comment.g?blogID=2484495037532005022&amp;postID=6225655900926135109&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thats all for today. Do check back soon as we have lots of new things coming up.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/6225655900926135109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/6225655900926135109' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6225655900926135109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6225655900926135109'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/control-in-code-in-dynamics-ax.html' title='How to refer to form controls in code without setting the AutoDeclaration property in Dynamics AX?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-6649587514148147914</id><published>2011-08-15T09:57:00.002+05:30</published><updated>2011-08-15T10:00:05.591+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="caller"/><category scheme="http://www.blogger.com/atom/ns#" term="document handling"/><category scheme="http://www.blogger.com/atom/ns#" term="DocuView caller"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="parmLastActivatedForm"/><title type='text'>What is the parmLastActivatedForm method used for in Dynamics AX?</title><content type='html'>Hello readers,&lt;br /&gt;
&lt;br /&gt;
In my earlier post, &lt;a href=&quot;http://daxline.blogspot.com/2011/08/forms-caller-in-dynamics-ax.html&quot;&gt;we had seen how to get all of a form&#39;s callers in Dynamics AX&lt;/a&gt;. One of my readers brought up a very good and interesting question around this.&lt;br /&gt;
&lt;br /&gt;
Some action forms opened like the &lt;b&gt;Document handling form&lt;/b&gt; will not show the caller. Is there a way to find the caller for these forms?&lt;br /&gt;
&lt;br /&gt;
This is indeed correct. If you open the document handling form from any form, and look for the caller name, it will be empty. See the below image to understand what I mean.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL9j2deFZ3TOeY7KMJu2MAsZE42Y6X1vDynSwrjAO6fzJdH-u-FgwjAG44D8dSOM4U19dQd9OAmauzPpB0f4vVW9CzJf5yhwIAEeH1LJIOs6ttvfWqt2j3dAHiMEV0DOoxbpv_zMfk8iI/s1600/Dynamics+AX_no+caller+form.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;136&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL9j2deFZ3TOeY7KMJu2MAsZE42Y6X1vDynSwrjAO6fzJdH-u-FgwjAG44D8dSOM4U19dQd9OAmauzPpB0f4vVW9CzJf5yhwIAEeH1LJIOs6ttvfWqt2j3dAHiMEV0DOoxbpv_zMfk8iI/s320/Dynamics+AX_no+caller+form.png&quot; alt=&quot;Dynamics AX_no caller form&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Well, this shouldn&#39;t stop us Dynamics AX developers from getting our way. In this post we will learn how to get the caller in such scenarios.&lt;br /&gt;
&lt;br /&gt;
The answer lies in a method in the Info class - &lt;b&gt;parmLastActivatedForm()&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Basically, the &lt;b&gt;parmLastActivatedForm()&lt;/b&gt; method returns the last form that was activated.&lt;br /&gt;
&lt;br /&gt;
So let us see all this in action.&lt;br /&gt;
&lt;br /&gt;
My code is in Dynamics AX 2012, but you can easily apply it in Dynamics AX 2009 as well.&lt;br /&gt;
&lt;br /&gt;
Let us modify the &lt;b&gt;init()&lt;/b&gt; method of the DocuView form. This is the document handling form.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;    formRun                             callerForm;
    FormDataSource                      formDataSource;
    InventTable                         inventTable;
    
    callerForm = infolog.parmLastActivatedForm().object();
    
    info(strFmt(&quot;Caller form name is %1&quot;, callerForm.name()));
    
    formDataSource = callerForm.dataSource(1);
    if (formDataSource &amp;&amp; formDataSource.cursor().TableId == tableNum(inventTable))
    {
        inventTable = formDataSource.cursor();
    }
    
    info(strFmt(&quot;Selected item on the list page is %1&quot;,inventTable.ItemId));
&lt;/pre&gt;&lt;br /&gt;
Now I&#39;ll open the document handling form from the Released Products list page after selecting a record where item name is &lt;b&gt;Pack-Ribbon&lt;/b&gt;. This is the output.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK4ngcbijr9F0CcTyPaRpxUbblOp-4jwQk5Huw6ksRO0OkpCu3ruabC9aoRdWfMELwHylkskSmOC7EPIpya0pfkBDfDseFunKoRANoSl77RgGMmEQeOnvoN9IIV4BCjeOxZ3DpirS7Gvs/s1600/Dynamics+AX_caller+form+and+selected+record.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;218&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK4ngcbijr9F0CcTyPaRpxUbblOp-4jwQk5Huw6ksRO0OkpCu3ruabC9aoRdWfMELwHylkskSmOC7EPIpya0pfkBDfDseFunKoRANoSl77RgGMmEQeOnvoN9IIV4BCjeOxZ3DpirS7Gvs/s320/Dynamics+AX_caller+form+and+selected+record.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;As you can see from the image, we extracted not only the form&#39;s name but also the exact record which was selected.&lt;br /&gt;
&lt;br /&gt;
How did I get the selected record with out using &lt;b&gt;args().record()&lt;/b&gt;? Let us look closely at the changes we have made.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;    formDataSource = callerForm.dataSource(1);
    if (formDataSource &amp;&amp; formDataSource.cursor().TableId == tableNum(InventTable))
    {
        inventTable = formDataSource.cursor();
    }
&lt;/pre&gt;&lt;br /&gt;
The &lt;b&gt;callerForm.dataSource(1)&lt;/b&gt; call will return me the first datasource on callerForm. I then check if a datasource was indeed returned and if it is for InventTable. If yes, I just cast it to an InventTable buffer and print it.&lt;br /&gt;
&lt;br /&gt;
Now some of you may have a nagging question in your mind due to a statement I made.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Basically, the parmLastActivatedForm() method returns the last form that was activated.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
If &lt;b&gt;parmLastActivatedForm()&lt;/b&gt; method returns the last activated form, shouldn&#39;t it return DocuView as the name because that was the name of the last active form. Well? your doubt is absolutely correct, it should return that. But it doesnt because there is a check in code in the activate() method of Info class to stop that.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;void activate(FormRun   formRun)
{
    if (formRun.name() != formstr(DocuView) &amp;&amp;
        formRun.name() != formstr(sysFormSearch)                
       )
    {
        this.setLastActivatedForm(formRun);
    }
}
&lt;/pre&gt;&lt;br /&gt;
As you can see from the above code, if the form name is DocuView or sysFormSearch, it is not stored. This is standard code. So this is the reason, whenever you open the DocuView form, a call to parmLastActivatedForm will return the name of the form that called the DocuView form.&lt;br /&gt;
&lt;br /&gt;
In this post we learnt how to find caller and caller record for forms which are opened through the toolbar. I hope this post was useful and informative.&lt;br /&gt;
&lt;br /&gt;
Thanks for all the response. Please continue to send me questions, feedback using the &lt;a href=&quot;http://daxline.blogspot.com/p/contact-me.html&quot;&gt;Contact me form&lt;/a&gt;. You can also leave me &lt;a href=&quot;https://www.blogger.com/comment.g?blogID=2484495037532005022&amp;postID=6649587514148147914&quot;&gt;comments&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, but do check back again as we keep learning.</content><link rel='replies' type='application/atom+xml' href='http://daxline.blogspot.com/feeds/6649587514148147914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2484495037532005022/6649587514148147914' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6649587514148147914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/6649587514148147914'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/parmlastactivatedform-method-in.html' title='What is the parmLastActivatedForm method used for in Dynamics AX?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL9j2deFZ3TOeY7KMJu2MAsZE42Y6X1vDynSwrjAO6fzJdH-u-FgwjAG44D8dSOM4U19dQd9OAmauzPpB0f4vVW9CzJf5yhwIAEeH1LJIOs6ttvfWqt2j3dAHiMEV0DOoxbpv_zMfk8iI/s72-c/Dynamics+AX_no+caller+form.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-4898051665579919494</id><published>2011-08-13T00:00:00.000+05:30</published><updated>2011-08-13T00:00:32.150+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="price list"/><title type='text'>Dynamics AX 2012 price list</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;br /&gt;
Hi readers,&lt;br /&gt;
&lt;br /&gt;
For all of you who were interested in knowing the cost of a Dynamics AX 2012 license, well, the wait is over. Microsoft has provided a nice little Excel sheet which can help you estimate the cost of your implementation.&lt;br /&gt;
&lt;br /&gt;
You just need to enter the quantity of components you wish to procure and the sheet will calculate the cost for you.&lt;br /&gt;
&lt;br /&gt;
You can download the sheet from &lt;a href=&quot;https://mbs.microsoft.com/downloads/partner/pricing/axapta/Microsoft_Dynamics_AX_2012_Price_List.xlsm&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div closure_uid_offex6=&quot;203&quot;&gt;&lt;span style=&quot;color: red;&quot;&gt;Note: PartnerSource login required.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4898051665579919494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4898051665579919494'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/dynamics-ax-2012-price-list.html' title='Dynamics AX 2012 price list'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-5252929180009353975</id><published>2011-08-10T23:36:00.002+05:30</published><updated>2011-08-10T23:39:19.740+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="args"/><category scheme="http://www.blogger.com/atom/ns#" term="caller"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="formHasMethod"/><title type='text'>How to get Form&#39;s caller in Dynamics AX?</title><content type='html'>&lt;br /&gt;
Hello readers,&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX, when we need to find the parent of a form, we call the caller() method on the args object of the formRun object of the form. The syntax is,&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FormRun callerForm = element.args().caller();&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the same way, we can find the parent of the caller form as well. &lt;br /&gt;
Something like,&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FormRun callerForm = element.args().caller().args().caller();&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Try that and Dynamics AX will throw an error that &quot;&lt;b&gt;The variable is not of the type CLASS.&lt;/b&gt;&quot;&lt;br /&gt;
&lt;br /&gt;
We can call only upto the 3rd method after which the AX compiler fails to return an object.&lt;br /&gt;
&lt;br /&gt;
We will have to first store the args() object in a seperate variable and then call the caller() method.&lt;br /&gt;
&lt;br /&gt;
Let us look at an example of getting all the ancestors for a form.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve a simple form, with just two methods - init() and parmFormName()&lt;br /&gt;
&lt;br /&gt;
Declare a variable formName of type Name in the classDeclaration.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public Name parmFormName(Name _formName = formName)
{
    formName = _formName;

    return formName;
}
&lt;/pre&gt;&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public void init()
{
    Object  caller;    
    Args    args;

    super();

    info(element.parmFormName());

    caller = element.args().caller();

    while (caller)
    {

        info(caller.parmFormName());
        args = caller.args();
        caller = args.caller();
    }
}
&lt;/pre&gt;Thats the form. No extra design. Just a plain vanilla form.&lt;br /&gt;
&lt;br /&gt;
Now I&#39;ll call this form from a job, but only after ensuring it has a great grand parent.&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;static void callForm(Args _args)
{
    Args        args;
    Object      formRun;
    int i;

    args = new Args(formStr(SampleForm));
    formRun = classFactory.formRunClass(args);
    if (formHasMethod(formRun, identifierStr(parmFormName)))
    {
        formRun.parmFormName(&quot;Form number 1&quot;);
    }

    for (i=2; i&lt;=4; i++)
    {
        args = new Args(formStr(SampleForm));
        
		// Set the form&#39;s caller or parent
		args.caller(formRun);
        formRun = classFactory.formRunClass(args);
        
		// It is a best practice to first check if the method exists on the form before calling it.
		if (formHasMethod(formRun, identifierStr(parmFormName)))
        {
            // Sets the form&#39;s name variable
			formRun.parmFormName(strFmt(&quot;Form number %1&quot;,i));
        }
    }

    formRun.run();    
}
&lt;/pre&gt;
What I have done is first initialized a formRun object for our SampleForm. Next I&#39;m running a loop 3 times to create three more instances of SampleForm and setting the form&#39;s parent to the previous instance. Then I run the form.

Lets run the job now. Here is the output.

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibsf2k16eSvKeuJEtaPRHemYk-0MwUATIkdIy7ufspYFJyIznDlIMKBMsbJDNgi6IQhl1CKeUawZG_AWrZcWlKfUlaY2dcKHRU0i4_OROgNbSV1zZYpPP_5Y72C4WaFxBnQq0w8QThauU/s1600/Dynamics+AX_infolog.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;312&quot; width=&quot;244&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibsf2k16eSvKeuJEtaPRHemYk-0MwUATIkdIy7ufspYFJyIznDlIMKBMsbJDNgi6IQhl1CKeUawZG_AWrZcWlKfUlaY2dcKHRU0i4_OROgNbSV1zZYpPP_5Y72C4WaFxBnQq0w8QThauU/s320/Dynamics+AX_infolog.png&quot; alt=&quot;Dynamics AX infolog&quot;/&gt;&lt;/a&gt;&lt;/div&gt;The code in the SampleForm&#39;s init() method iterates through the callers until it reaches the first instance of the form. It calls the parmFormName() method on the form to print the form&#39;s name. The order is Form 4 is child of Form 3, Form 3 is child of Form 2 and Form 2 is the child of Form 1.

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_z0C4AgBfSmvDfqa0Rc6jtNZhNnXfZQvXsn4dPsDd5lRJu06oLDHXk9qOla0gn2kI4GOo67SpHLg2HCaOG4kSkucG12wW5d1iA4H9Syo_TkkMFpdscjiAIYUi47WSCa-Y7IulJiJFu9M/s1600/Dynamics+AX_args+caller+form.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;112&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_z0C4AgBfSmvDfqa0Rc6jtNZhNnXfZQvXsn4dPsDd5lRJu06oLDHXk9qOla0gn2kI4GOo67SpHLg2HCaOG4kSkucG12wW5d1iA4H9Syo_TkkMFpdscjiAIYUi47WSCa-Y7IulJiJFu9M/s320/Dynamics+AX_args+caller+form.png&quot; alt=&quot;Dynamics AX caller form&quot;/&gt;&lt;/a&gt;&lt;/div&gt;When calling methods on forms or classes, using their generic form like formRun, always declare the variable as Object. This way you will not get a compilation error. Ofcourse, it is the developer&#39;s responsibility to ensure that there is no runtime error as well. For this purpose, use the intrinsic method formHasMethod() to make sure that the method indeed exists on the form. If you do not perform this check, and the method has been deleted or renamed, then you will recieve a runtime error.

I hope this post was helpful. Please feel free to send me your questions, comments or any feedback using the &lt;a href=&quot;http://daxline.blogspot.com/p/contact-me.html&quot;&gt;Contact me form&lt;/a&gt;.

You can download the project used from &lt;a href=&quot;http://www.axaptapedia.com/images/2/29/PrivateProject_FormCaller.xpo&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thats all for today folks, but do check back soon as we continue to learn more.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5252929180009353975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5252929180009353975'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/forms-caller-in-dynamics-ax.html' title='How to get Form&#39;s caller in Dynamics AX?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibsf2k16eSvKeuJEtaPRHemYk-0MwUATIkdIy7ufspYFJyIznDlIMKBMsbJDNgi6IQhl1CKeUawZG_AWrZcWlKfUlaY2dcKHRU0i4_OROgNbSV1zZYpPP_5Y72C4WaFxBnQq0w8QThauU/s72-c/Dynamics+AX_infolog.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-5692483677038855304</id><published>2011-08-08T21:27:00.007+05:30</published><updated>2011-08-08T23:55:28.466+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="hide enum values"/><category scheme="http://www.blogger.com/atom/ns#" term="remove enum values"/><title type='text'>How to remove enum values from dialogs in Dynamics AX?</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;br /&gt;
Hello readers,&lt;br /&gt;
&lt;br /&gt;
A common requirement which I have come across from time to time is the ability to hide certain enum elements on a form. There has been various solutions to the problem. The easiest one I saw was where the developer had created two enums, one with all the values and another one with the unwanted elements dropped. This approach has many problems as comparing the enum values in code isn&#39;t possible.&lt;br /&gt;
In Dynamics AX 2009, the &lt;strong&gt;SysFormEnumComboBox&lt;/strong&gt; class was provided to solve this issue. You pass it the combo box control&#39;s id, the enum to be used and a set of allowed values that need to be shown and it works as a charm. This approach can be used effortlessly on forms.&lt;br /&gt;
&lt;br /&gt;
Recently, I was posed if this can be done on a dialog. Well, its not as simple to use this on a dialog but I have another solution for the problem. Let us see this in more detail here.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve a very simple dialog with just the SysDimension enum showing up. The requirement is to remove the Purpose element. For that, we need to first get the combo box control, and then remove the element.&lt;br /&gt;
We cannot write this code in the dialog() method because the formRun object of the dialog isn&#39;t created yet.&lt;br /&gt;
We should put this code in dialogPostRun()&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public void dialogPostRun(DialogRunbase _dialog)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; FormRun&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formRun;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysDictEnum&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i, enumCount;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Set&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ;
&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues = new Set(Types::String);
&amp;nbsp;&amp;nbsp;&amp;nbsp; // A set with the values that have to be removed
&amp;nbsp;removeValues.add(&quot;Department&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues.add(&quot;Purpose&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum = new SysDictEnum(enumNum(SysDimension));
&amp;nbsp;&amp;nbsp;&amp;nbsp; enumCount = dictEnum.values();
&amp;nbsp;&amp;nbsp;&amp;nbsp; super(_dialog);
&amp;nbsp;&amp;nbsp;&amp;nbsp; formRun = _dialog.formRun();
&amp;nbsp;// Get the combo box control&#39;s instance
&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl = formRun.design().controlName(dimension.name());
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;// Clear all the combo box items.
&amp;nbsp;formComboBoxControl.clear();
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (i=0; i&amp;lt;enumCount; i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;// If the current enum element is present in the set of elements to be removed,
&amp;nbsp;&amp;nbsp;// dont bother adding it to the combobox.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (removeValues.in(dictEnum.index2Label(i)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl.add(dictEnum.index2Label(i));
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;// Select the first item in the combo box.
&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl.selection(0);
}
&lt;/pre&gt;That is it. Run the dialog now and you will only see Cost center in the dialog.&lt;br /&gt;
&lt;br /&gt;
But this solution isnt complete yet. You may be wondering why? Well, try to get the value of the combo box. You will end up getting wrong index values.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that when we added the combo box control onto the for, we specified SysDimension as the typeId. So the kernel will always tro to return an element from thisenum based on the selected index. Since in our case, we have only one element in our combo box, i.e., Cost center, the return index is zero (indexes are zero based). But zero is the value of Department in SysDimension and that is what the user will get.&lt;br /&gt;
So to fix this issue, we need to first store the values being added in the combo box and the actual values compared to the SysDimension enum in a map. A map is a key-value pair container and is suited for our purpose here.&lt;br /&gt;
Update the code in the dialogPostRun method as shown below. &lt;br /&gt;
&lt;div closure_uid_t2gkp7=&quot;204&quot;&gt;&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public void dialogPostRun(DialogRunbase _dialog)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; FormRun&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formRun;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysDictEnum&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i, j, enumCount;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Set&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ;
&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues = new Set(Types::String);
&amp;nbsp;&amp;nbsp;&amp;nbsp; // A set with the values that have to be removed
&amp;nbsp;removeValues.add(&quot;Department&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; removeValues.add(&quot;Purpose&quot;);
// Add this line to initialize the map to store the correct enum values.
&amp;nbsp;&amp;nbsp;&amp;nbsp; dimensionAcceptedValues = new Map(Types::Integer, Types::Enum);
&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum = new SysDictEnum(enumNum(SysDimension));
&amp;nbsp;&amp;nbsp;&amp;nbsp; enumCount = dictEnum.values();
&amp;nbsp;&amp;nbsp;&amp;nbsp; super(_dialog);
&amp;nbsp;&amp;nbsp;&amp;nbsp; formRun = _dialog.formRun();
&amp;nbsp;// Get the combo box control&#39;s instance
&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl = formRun.design().controlName(dimension.name());
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;// Clear all the combo box items.
&amp;nbsp;formComboBoxControl.clear();
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (i=0; i&amp;lt;enumCount; i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;// If the current enum element is present in the set of elements to be removed,
&amp;nbsp;&amp;nbsp;// dont bother adding it to the combobox.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (removeValues.in(dictEnum.index2Label(i)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl.add(dictEnum.index2Label(i));
// Add this line to store the correct enum value
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dimensionAcceptedValues.insert(j, dictEnum.index2Value(i));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; j++;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;// Select the first item in the combo box.
&amp;nbsp;&amp;nbsp;&amp;nbsp; formComboBoxControl.selection(0);
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div closure_uid_t2gkp7=&quot;207&quot;&gt;Declare a map object named &lt;span style=&quot;background-color: white;&quot;&gt;dimensionAcceptedValues in the classDeclaration.&lt;/span&gt;&lt;/div&gt;&lt;div closure_uid_t2gkp7=&quot;207&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div closure_uid_t2gkp7=&quot;210&quot;&gt;Now add this code in &lt;strong&gt;getFromDialog()&lt;/strong&gt; method&lt;/div&gt;&lt;div closure_uid_t2gkp7=&quot;210&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;brush: c-sharp;&quot;&gt;public boolean getFromDialog()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; SysDictEnum&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum;
&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean ret;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = super();
&amp;nbsp;&amp;nbsp;&amp;nbsp; dictEnum = new SysDictEnum(enumNum(SysDimension));
&amp;nbsp;&amp;nbsp;&amp;nbsp; info(strfmt(&quot;You selected %1&quot;,dictEnum.index2Label(dimensionAcceptedValues.lookup(formComboBoxControl.selection()))));
&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;
}
&lt;/pre&gt;Run the class and press the OK button. See if you get the correct result. Test it with some other enum to see if it is working as expected.&lt;br /&gt;
&lt;br /&gt;
I hope this post was helpful. You can donwload the xpo for the project from &lt;a href=&quot;http://www.axaptapedia.com/images/1/11/PrivateProject_RemoveDimensionInDialog.xpo&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thats all for today. Do check back again as we continue to learn.&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5692483677038855304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/5692483677038855304'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/remove-enum-values-from-dialogs-in.html' title='How to remove enum values from dialogs in Dynamics AX?'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7741453160456287849</id><published>2011-08-05T23:04:00.000+05:30</published><updated>2011-08-05T23:04:21.762+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cumulative Update"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><title type='text'>Cumulative Update pack 1 for Microsoft Dynamics AX 2012 released</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Just days after the general availability of Microsoft Dynamics AX 2012, a cumulative update pack has been released for Microsoft Dynamics AX 2012.&lt;br /&gt;
&lt;br /&gt;
&lt;div closure_uid_687eyk=&quot;85&quot;&gt;
This pack contains close to 80 fixes to various&amp;nbsp;bugs. You can download the pack and read more about the fixes in the pack &lt;a href=&quot;https://mbs2.microsoft.com/knowledgebase/KbDisplay.aspx?scid=kb;en-us;2579565&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div closure_uid_687eyk=&quot;85&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div closure_uid_687eyk=&quot;85&quot;&gt;
&lt;strong&gt;&lt;span style=&quot;color: red;&quot;&gt;Note: PartnerSource credentials required.&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7741453160456287849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7741453160456287849'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/cumulative-update-pack-1-for-microsoft.html' title='Cumulative Update pack 1 for Microsoft Dynamics AX 2012 released'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-4822295358345564012</id><published>2011-08-03T23:05:00.001+05:30</published><updated>2011-08-03T23:05:46.428+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX 2012"/><category scheme="http://www.blogger.com/atom/ns#" term="Label files"/><category scheme="http://www.blogger.com/atom/ns#" term="model"/><title type='text'>How to add or delete a label file in Dynamics AX 2012</title><content type='html'>By now, you all must be aware that we are done with AOD files in Dynamics AX 2012. Model is the new deployment option for deploying AX objects on various installations. If you want to learn more about models, MFP has an excellent three part series on it which you can read &lt;a href=&quot;http://blogs.msdn.com/b/mfp/archive/2009/10/08/introducing-ax-models-part-3.aspx&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
In this post we will look at how label files are contained within models in Dynamics AX 2012.&lt;br /&gt;
&lt;br /&gt;
We now have a new node in AOT - &lt;b&gt;Label Files&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtkWz01r4So_R2_km2TKfrAYXPmuJ6JONSmkDpA_IVTdQsiHB-1WaZGjgPNyvRRAgsMRnOKwiVxMnWiB7IDflrd6WMHLp4TGGoYA51Vr_gZk0IN5X_pXwoBlaXn-s1k7nBObfPdJYul4/s1600/Dynamics+AX+2012+Label+File+Node.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;125&quot; width=&quot;175&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtkWz01r4So_R2_km2TKfrAYXPmuJ6JONSmkDpA_IVTdQsiHB-1WaZGjgPNyvRRAgsMRnOKwiVxMnWiB7IDflrd6WMHLp4TGGoYA51Vr_gZk0IN5X_pXwoBlaXn-s1k7nBObfPdJYul4/s320/Dynamics+AX+2012+Label+File+Node.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
All labels in the system are grouped under this node.&lt;br /&gt;
&lt;br /&gt;
Now suppose we have a label from another installation which we want to bring in to our system. Right click on the Label Files node and select &lt;b&gt;Create from File&lt;/b&gt;. Browse and selct your .ald file. Once you select the file and hit OK, a new node is added under the Label Files node corresponding to the label file imported. You will get an info message saying &quot;&lt;b&gt;Imported label file:C:\Users\Administrator\Desktop\MyLabelen-us.ald&lt;/b&gt;&quot;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwgisKKgWEQ7aITrbQPmpMRIAGTZqTZUEaPyA2wGfreanSU1BAtPdhe1F_lUxhk31NofOp8tgEaeTgzcS46Jt9iFew_VTiP-QrAbgEYj7tTNz_RKSCm2L0dXMIN9G_hIa9IaDemlkAkGo/s1600/Dynamics+AX+2012+Create+Label+File.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;197&quot; width=&quot;262&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwgisKKgWEQ7aITrbQPmpMRIAGTZqTZUEaPyA2wGfreanSU1BAtPdhe1F_lUxhk31NofOp8tgEaeTgzcS46Jt9iFew_VTiP-QrAbgEYj7tTNz_RKSCm2L0dXMIN9G_hIa9IaDemlkAkGo/s320/Dynamics+AX+2012+Create+Label+File.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
In AX 2009, after placing a label file, we needed to restart the AOS so that the label index was build. This isn&#39;t required in Dynamics AX 2012. Just try using the label somewhere, and you will see that it is immediately referenced.&lt;br /&gt;
&lt;br /&gt;
If you search in your application folder, you wont find the label file there. The application folder is located here C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\Application\Appl\Standard&lt;br /&gt;
&lt;br /&gt;
In Dynamics AX 2012, the label file is imported in your current model.&lt;br /&gt;
&lt;br /&gt;
Now let us restart the AOS and see what happens. After restarting the AOS, go back to your application folder and try to find the label file again. This time the label file will be found.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Point to remember&lt;/b&gt;, on every AOS restart, all label files will be copied to the application folder from the model store. So your label files are contained in your models but they are stored in your application folder as well.&lt;br /&gt;
&lt;br /&gt;
Now let us try to delete the label file. Right click on your label file. Do you see a delete/remove option?&lt;br /&gt;
&lt;br /&gt;
The answer is no. So how do we delete the label file then? The solution which I figured out was,&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;To create a temporary model&lt;/li&gt;
&lt;li&gt;Move our label file to the temporary model&lt;/li&gt;
&lt;li&gt;Stop the AOS&lt;/li&gt;
&lt;li&gt;Delete the temporary model&lt;/li&gt;
&lt;li&gt;Start the AOS&lt;/li&gt;
&lt;/ol&gt;Let us get about with these tasks&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Go to Tools -&gt; Model management -&gt; Create model&lt;/li&gt;
&lt;li&gt;Enter name as TemporaryModel. Press OK. You will recieve an info message saying &quot;&lt;b&gt;The model TemporaryModel was created successfully in layer var.&lt;/b&gt;&quot;&lt;/li&gt;
&lt;li&gt;Right click on your label file and select &quot;&lt;b&gt;Move to model&lt;/b&gt;&quot;&lt;/li&gt;
&lt;li&gt;Select the TemporaryModel checkbox and press OK.&lt;/li&gt;
&lt;li&gt;Stop the AOS.&lt;/li&gt;
&lt;li&gt;Open a command prompt. We will be using the command line utility AXUTIL to delete the model.&lt;/li&gt;
&lt;li&gt;Issue the following command in the command prompt&lt;/li&gt;
&lt;b&gt;AXUTIL delete /model:TemporaryModel&lt;/b&gt;
&lt;li&gt;You will be prompted if you want to delete the model or not. Press Y&lt;/li&gt;
&lt;li&gt;Start the AOS&lt;/li&gt;
&lt;li&gt;Delete the label file from your application folder as well.&lt;/li&gt;
&lt;/ol&gt;When you open AX now, you will get a dialog saying that &quot;&lt;b&gt;Your model store has been modified.&lt;/b&gt;&quot; This is normal because each time you perform an operation on a model, you will get this dialog. Depending on your operation, you should select one of the option. Since we just deleted a model which just had a label file, select Skip.&lt;br /&gt;
Open AOT and notice that the label file is deleted now.&lt;br /&gt;
Check if the references of the label work. I bet they wont be.&lt;br /&gt;
&lt;br /&gt;
In this post we learnt how label files are managed in Dynamics AX 2012, how to import a label file and how to delete them.&lt;br /&gt;
&lt;br /&gt;
Thats all for today, but do check back soon as we continue learning.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4822295358345564012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/4822295358345564012'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/label-files-in-dynamics-ax-2012.html' title='How to add or delete a label file in Dynamics AX 2012'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDtkWz01r4So_R2_km2TKfrAYXPmuJ6JONSmkDpA_IVTdQsiHB-1WaZGjgPNyvRRAgsMRnOKwiVxMnWiB7IDflrd6WMHLp4TGGoYA51Vr_gZk0IN5X_pXwoBlaXn-s1k7nBObfPdJYul4/s72-c/Dynamics+AX+2012+Label+File+Node.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-2484495037532005022.post-7327179346605318128</id><published>2011-08-02T23:25:00.000+05:30</published><updated>2011-08-02T23:25:11.157+05:30</updated><title type='text'>General announcement - Change in blog layout</title><content type='html'>Dear readers,&lt;br /&gt;
&lt;br /&gt;
Over the couple of days, I&#39;ve been working on changing the layout of the blog. I&#39;ll roll out the new layout in a couple of weeks. Don&#39;t be surprised if you come back and see a completely new color or layout. It will be the same blog and the same old me :).&lt;br /&gt;
&lt;br /&gt;
Thank you all.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7327179346605318128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2484495037532005022/posts/default/7327179346605318128'/><link rel='alternate' type='text/html' href='http://daxline.blogspot.com/2011/08/general-announcement-change-in-blog.html' title='General announcement - Change in blog layout'/><author><name>Zubair Ahmed</name><uri>http://www.blogger.com/profile/07681728648792046083</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='12' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghtmX7c4TDWQh0iGfQUuWWPUrd0HL0IGT_DSWYcEUdDbQreE2mL5VtTe7YYHSrZrq2LplKRgGbB7dgL5xao96QgMZZidubs0XK7WwXVrXaO639jbuf1fS-4qKJZI16Yg/s220/Mail.png'/></author></entry></feed>