{"id":16,"date":"2016-01-19T17:35:58","date_gmt":"2016-01-19T16:35:58","guid":{"rendered":"https:\/\/kerms.hobby-site.org\/?p=16"},"modified":"2016-01-31T13:10:25","modified_gmt":"2016-01-31T12:10:25","slug":"creating-a-batch-class-in-dynamics-ax-2009","status":"publish","type":"post","link":"https:\/\/kerms.hobby-site.org\/?p=16","title":{"rendered":"Creating a batch class in Dynamics AX 2009"},"content":{"rendered":"<p>For creating a batch class in Dynamics AX we can start from the Tutorial_RunbaseBatch class,<br \/>\nbut here is the explanation for understanding all its methods:<\/p>\n<p>In the\u00a0<em>classDeclaration<\/em>, we declare any variable that contains user&#8217;s selection or preferences<br \/>\n(for example, the customer account for launch a customer report). Also, we declare other<br \/>\nvariables like dialog fields, auxiliar variables, etc. But, the most important feature here, is the\u00a0<em>#localmacro.CurrentList<\/em>\u00a0declaration. This macro helps you to define which variables you want<br \/>\nto save for running the class in batch mode (when not user interaction is available).<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">class<\/span> Tutorial_RunbaseBatch extends RunBaseBatch\r\n{\r\n    <span class=\"rem\">\/\/ Packed variables<\/span>\r\n    TransDate       transDate;\r\n    CustAccount     custAccount;\r\n\r\n    <span class=\"rem\">\/\/ Dialog fields<\/span>\r\n    DialogField     dlgCustAccount;\r\n    DialogField     dlgTransDate;\r\n\r\n    <span class=\"rem\">\/\/ Current version<\/span>\r\n    <span class=\"rem\">\/\/ We can have different versions for different purposes<\/span>\r\n    #define.CurrentVersion(1)\r\n    #define.Version1(1)\r\n    #localmacro.CurrentList  <span class=\"rem\">\/\/ Our current variable list for save user's selected values<\/span>\r\n        transDate,\r\n        custAccount\r\n    #endmacro\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>The macro\u00a0<em>#define.CurrentVersion(1)<\/em>\u00a0and\u00a0<em>#define.Version1(1)<\/em>\u00a0are useful for scaling our class<br \/>\nwhen we need to change\/upgrade it preserving compatibility.<\/p>\n<p>Now two methods:\u00a0<em>pack<\/em>\u00a0and\u00a0<em>unpack<\/em>. These methods are used for store and retrieve user&#8217;s<br \/>\npreferences and perform the batch operation when none user are available (in batch mode).<br \/>\nHere is the point where we use the macro defined previously:<\/p>\n<div><\/div>\n<pre class=\"csharpcode\"><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">container<\/span> pack()\r\n{\r\n    <span class=\"kwrd\">return<\/span> [#CurrentVersion,#CurrentList];\r\n}\r\n\r\n<span class=\"kwrd\">public<\/span> boolean unpack(<span class=\"kwrd\">container<\/span> packedClass)\r\n{\r\n    Version version = RunBase::getVersion(packedClass);\r\n;\r\n    <span class=\"kwrd\">switch<\/span> (version)\r\n    {\r\n        <span class=\"kwrd\">case<\/span> #CurrentVersion:\r\n            [version,#CurrentList] = packedClass;\r\n            <span class=\"kwrd\">break<\/span>;\r\n        <span class=\"rem\">\/\/case #otherVersion:<\/span>\r\n            <span class=\"rem\">\/\/[version,#CurrentList, #otherList] = packedClass;<\/span>\r\n            <span class=\"rem\">\/\/break;<\/span>\r\n        <span class=\"kwrd\">default<\/span>:\r\n            <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">false<\/span>;\r\n    }\r\n\r\n    <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">true<\/span>;\r\n}<\/pre>\n<div><\/div>\n<div><\/div>\n<div>Bacause we need to ask the user about preferences for run this object (report,<\/div>\n<div>\u00a0process, query, etc.), we must implement some methods:<\/div>\n<div><\/div>\n<div>&#8211;\u00a0<em>dialog<\/em>: for build the custom dialog for prompting user&#8217;s preferences.<\/div>\n<div>&#8211;\u00a0<em>dialogPostRun<\/em>: after dialog was created, you can perform other UI tasks here.<\/div>\n<div>&#8211;\u00a0<em>getFromDialog<\/em>: used for retrive user&#8217;s preferences (dialog values).<\/div>\n<div>&#8211;\u00a0<em>validate<\/em>: here, you can perform a validation for any data entered by the user.<\/div>\n<div><\/div>\n<pre class=\"csharpcode\"><span class=\"kwrd\">public<\/span> Object dialog()\r\n{\r\n    DialogRunbase       dialog = super();\r\n    ;\r\n \r\n    <span class=\"rem\">\/\/ Creation of our custom dialog fields\/controls to ask user for preferences<\/span>\r\n    dlgTransDate = dialog.addFieldValue(typeid(TransDate),transDate);\r\n    dlgCustAccount = dialog.addFieldValue(typeid(CustAccount),custAccount);\r\n\r\n    <span class=\"kwrd\">return<\/span> dialog;\r\n}\r\n\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> dialogPostRun(DialogRunbase dialog)\r\n{\r\n;\r\n    super(dialog);\r\n}\r\n\r\n<span class=\"kwrd\">public<\/span> boolean getFromDialog()\r\n{\r\n    ;\r\n\r\n    <span class=\"rem\">\/\/ Retrieving user's preferences<\/span>\r\n    transDate   = dlgTransDate.<span class=\"kwrd\">value<\/span>();\r\n    custAccount = dlgCustAccount.<span class=\"kwrd\">value<\/span>();\r\n\r\n    <span class=\"kwrd\">return<\/span> super();\r\n}\r\n\r\n<span class=\"kwrd\">public<\/span> boolean validate()\r\n{\r\n    <span class=\"rem\">\/\/ We can perform some validations here<\/span>\r\n    <span class=\"kwrd\">if<\/span> (<span class=\"kwrd\">false<\/span>)\r\n        <span class=\"kwrd\">return<\/span> checkFailed(<span class=\"str\">\"\"<\/span>);\r\n\r\n    <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">true<\/span>;\r\n}\r\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div>Finally, the\u00a0<em>main<\/em>\u00a0method\u00a0<em>constructs<\/em>\u00a0the object from this batch class, and after<\/div>\n<div>\u00a0prompting user and validation was successful, the\u00a0<em>run<\/em>\u00a0method is called to perform<\/div>\n<div>some task (in batch mode if it was selected):<\/div>\n<div><\/div>\n<pre class=\"csharpcode\">server <span class=\"kwrd\">static<\/span> Tutorial_RunbaseBatch construct()\r\n{\r\n    <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">new<\/span> Tutorial_RunbaseBatch();\r\n}\r\n\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> run()\r\n{\r\n    <span class=\"kwrd\">try<\/span>\r\n    {\r\n        <span class=\"rem\">\/\/ Obviously, this code is silly, why show something to nobody?<\/span>\r\n        <span class=\"rem\">\/\/ remember, this code is running in batch without user interaction<\/span>\r\n        info(strfmt(<span class=\"str\">\"Parameters: %1 for %2\"<\/span>, transDate, custAccount));\r\n    }\r\n    <span class=\"kwrd\">catch<\/span>(Exception::Deadlock)\r\n    {\r\n        retry;\r\n    }\r\n    <span class=\"kwrd\">catch<\/span>(Exception::UpdateConflict)\r\n    {\r\n        <span class=\"kwrd\">throw<\/span> Exception::UpdateConflict;\r\n    }\r\n    <span class=\"kwrd\">catch<\/span>\r\n    {\r\n        <span class=\"kwrd\">throw<\/span> Exception::Error;\r\n    }\r\n}\r\n\r\n<span class=\"kwrd\">static<\/span> <span class=\"kwrd\">void<\/span> main(Args args)\r\n{\r\n    Tutorial_RunbaseBatch    tutorial_RunBase;\r\n    ;\r\n\r\n    <span class=\"rem\">\/\/ Instanciating this batch class<\/span>\r\n    tutorial_RunBase = Tutorial_RunbaseBatch::construct();\r\n\r\n    <span class=\"rem\">\/\/ Prompting user and run if all is ok<\/span>\r\n    <span class=\"kwrd\">if<\/span> (tutorial_RunBase.prompt())\r\n        tutorial_RunBase.run();\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>For creating a batch class in Dynamics AX we can start from the Tutorial_RunbaseBatch class, but here is the explanation for understanding all its methods: In the\u00a0classDeclaration, we declare any variable that contains user&#8217;s selection or preferences (for example, the &hellip; <a href=\"https:\/\/kerms.hobby-site.org\/?p=16\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-16","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/posts\/16"}],"collection":[{"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":5,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":23,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions\/23"}],"wp:attachment":[{"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kerms.hobby-site.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}