-->
Showing posts with label AX. Show all posts
Showing posts with label AX. Show all posts

AX 2012 R2: Prevent startup of checklists

maqk® by Maqk | 3:31 PM

AX 2012 R2: Model upgrade check list does not disappear



Subject

This post discusses a scenario when the ModelStore gets updated after applying KB hot fix. However the checklist keeps coming after it is fully completed and there is no way to make it disappear permanently.


Audience

Dynamics AX 2012 (FP, R2 R3) X++ Developers, Technical consultants, Functional consultants, and advanced users.


Background

Hot fix implementations are a regular task for developers and technical personnel alike. After any hot fix, a checklist is presented to the user mainly to recompile the whole application and synchronize. The checklist depends on the type of upgrade and can be of the following type



Problem

Sometimes however, hot fix implementation fails which can have any reason. In our scenario we faced a similar situation where we had to undo the hot fix. We simply restored the model store database. However the model upgrade checklist would keep coming.


Checklist Framework

There is a solution provided by the framework. It is the menu item provided in the Checklist section. The full navigation is: /System administration/Area page/Setup/Checklists/Prevent startup of checklists


What it does ?


Points to Action menu item: SysCheckList_InitNoUpdate
Which then calls the SysCheckList class with the base enum: SysCheckListType and SetDB as selected value. 
The main method for this base enum value provided runs the following
                case SysCheckListType::SetDB :
                    SysCheckList::initNoUpdate(true);
                    return; //mark upgrade and setup as finished



This method fires the SysSetupLog::saveEx() and SysSetupPartitionLog::saveEx() methods which updates the SysSetupLog and SysSetuppartitionLog tables with values representing the completed status for each type of checklist. These methods are called for each checklist type. This is achieved by sending the name of the class specialized for each checklist type to the save methods. Hence for each type, a complete record is maintained in the database. This gives the hint that this table is read at the client startup to evaluate if any checklist remains to be updated. See image below

SysCheckList::initNoUpdate() method body


A failed attempt


I marked all such records as completed. Nothing happened. Checklist kept coming. There is definitely more to the doings of the mentioned method which I would have missed in my update query.

The focus of this post is not to understand the SysCheckList class and its internals, neither was it my focus when trying to get rid of the checklist. So... I googled :D


Solution


SysCheckList_Update::finalizeMinorUpgrade();

The link shared in the following section provided the solution to this problem. This is why for every such problem, we should try to searching for relevant API provided in the framework.

This method actually does similar things discussed above along with deleting unwanted records from SysSetupLog table and updating the ReleaseUpdateConfiguration table. However, it does it fully and bring results.

Links


  • http://dynamicsuser.net/forums/p/76421/421256.aspx 

AX 2012 X++: Add N working days to a date

maqk® by Maqk | 5:04 PM

AX 2012 X++: Add N working days to a date

This post provides a few tips, specially focusing the working calendar and working days


Audience: Dynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users


Date operations are every day common tasks for any developer working on a business application. Any good programming language, platform or framework would provide well designed library(ies) with sufficient functionality abstracted in various helper classes and methods to achieve the common and extended date operations. After all, what we want to achieve is re-usability and not reinventing the wheel every now and then.

AX also has alot of such reusable method to save time and keep consistency. A few are listed below;


  • DateTimeUtil: A date time manipulation utility class. Some of its methods are referenced below too
  • DateTimeUtil::getSystemDateTime(): Works like a Now() method
  • DateTimeUtil::addMonths(): Add n months to the provided date
  • dayOfMth(date): Calculates the number of the day in the month for the specified date.
  • mkDate(int month, day, year)- Creates a date based on three integers, which indicate the day, month, and year, respectively.
  • prevYr(date) - Retrieves the date in the previous year that corresponds most closely to the specified date. Similar functions include prevMth() and prevQtr()
  • dateMthFwd(date, int qty): Adds the specified number of months to a date.

These all methods are so useful and handy while there are much more to mention. See links section for more.

We are more interested in the working calendar. I recently got a scenario in which I had to validate the date from calendar. Then I had to decide the ending date (the famous 'To' date). The resulting date must be a valid date on a calendar. So should I write some algo for it. Experience says such a thing should be available in the library / framework somewhere. Yes this is what is to be shared with all.


WorkCalendarSched.schedDate Method

This sweet method in short takes from date, no of days to add, scheduling direction, calendar id to process against and calendar days flag to schedule the resulting date, awesome. Exactly what I was looking for. Hence using this method, we can add N working days (excluding holidays, weekEnds, etc) to any date. The resulting date is guaranteed to be a working date. Just keep your calendar tight and updated

Code sample


static void job_testSchedDate(Args _args)
{
    WorkCalendarSched       workCalendarSched;
    SchedDate               schedDateFrom, resultantTODate;
    Days                    noOfDays;
    CalendarId              primCalendar, secCalendar;

    workCalendarSched = new workCalendarSched();

    noOfDays            = 30;     
    primCalendar        = "Default";    secCalendar         = "Default";
    schedDateFrom       = str2Date("21.6.2016", 123);    // dd.mm.yyyy

    info(strfmt("From date: %1", 
        date2str(schedDateFrom, 123, DateDay::Digits2, DateSeparator::Slash, DateMonth::Short, DateSeparator::Slash, DateYear::Digits4)    )); 
    // sequence (int) 123 means 1=dd 2=mm 3=yyyy
    
    info(strFmt("Adding %1 days [Working days]", noOfDays)); 
    resultantTODate = workCalendarSched.schedDate(  SchedDirection::Forward,    // Selecting backward will minus the noOfDays
                                                    schedDateFrom,  
                                                    noOfDays,                   // number of days to add
                                                    NoYes::Yes,                 // Yes mean bring WorkDays (exclude weekEnds and other configured holidays in between)
                                                    primCalendar, secCalendar); // which calendar to be used for date calculation and verification
     info(strfmt("Resultant TO date: %1", 
        date2str(resultantTODate, 123, DateDay::Digits2, DateSeparator::Slash, DateMonth::Short, DateSeparator::Slash, DateYear::Digits4)    ));  
}


Output is shared as follows


 Links

ProjUnpostedTransView-Field WorkerName is not compatible with field WorkerName

Subject


This post provides insight about a synchronize error received during full AOT for AOT view 'ProjUnpostedTransView' and its resolution.

Error

ProjUnpostedTransView: Synchronize database There is a field mismatch in the union query. Field WorkerName is not compatible with field WorkerName.

Audience:  Dynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users

Background

We have been facing this issue since day one of our installation of AX 2012 R3 (RTM). Build numbers are as follows;

Microsoft Dynamics AX 2012 R3 (RTM)
Kernel version: 6.3.164.0
Application version: 6.3.164.0

Problem

When synchronizing the full AOT, the following errors come






followed by...

Solution(s)

As per mentioned in the synchronize database error (1), all the errors have come in the View, 'ProjUnpostedTransView'. Exploring the same yields the composition of the view on following sub views.


  1. ProjLedgerJournalTransUnpostedView
  2. TrvExpTransDistributionsUnposted
  3. ProjJournalTransFeeUnpostedView
  4. projCustInvoiceLineDistsUnpostedView
  5. ProjJournalTransHourUnpostedView
  6. ProjProdJournalRouteUnpostedView
  7. InventJournalTransUnpostedView
  8. ProjProdJournalBOMUnpostedView
  9. VendInvoiceInfoLineDistributionsUnposted
  10. ProjOnAccTransUnpostedView
  11. ProjIntercompanyUnpostedExpView
  12. TSUnpostedTimesheetLinesAllView
  13. ProjIntercompanyUnpostedTSView
  14. ProjIntercompanyUnpostedVendInvLineView
Data sources (Views) with mismatching EDTs in their field, WorkerName




Each of these views comprise of one or more tables. And each of these views as a data source has the HCMWorker data source with in further relating to DirPartyTable to fetch the worker name. Closely monitoring each of them reveals that the following four data sources were returning null for the worker name. Obviously the logic implemented would have required the field (since a union query) to have a consistent schema returned. Further to returning null, the fields were provided the extended type, "Name" which was different from what is returned from DirPartyTable > Name field which extends "DirPartyName" extended type.  

Data sources with inconsistent extended types

  1. projCustInvoiceLineDistsUnpostedView
  2. ProjProdJournalBOMUnpostedView
  3. ProjInventJournalTransUnpostedView
  4. ProjOnAccTransUnpostedView

Due to this EDT mismatch, the AOT framework was giving errors.

Providing the correct extended type of DirPartyName to the WorkerName fields for each of these views made the schema fully consistent, hence error removed.

NOTE: These corrections are to be made in each view used as a datsource and in the field section

I am unable to find if its a R3 RTM original issue or what, cause i have not been able to find any corresponding hotfix. If any of the readers have any idea, kindly share it with me.

Thanks :)

AX 2012: FormRun.createRecord Method with example

maqk® by Maqk | 10:24 AM

AX 2012: FormRun.createRecord Method with example

This post provides a tutorial about the FormRun.createRecord Method which is override able at form level for custom implementation

AudienceDynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users

Background

Recently I came through a scenario where I had to use a base table (supporting inheritance) as a Form data source. I needed to ensure which child table's instance is being created. Due to not being totally aware of the table inheritance implementation (and sorry for Microsoft documentation, such things are not specified anywhere) I was relying on my intelligent (or semi intelligent perhaps :D ) guesses. 

Question: Where is the InstanceRelationType field set to identify the record belonging to a child table.

Thanks to Nasheet Siddiqui | blog a close friend of mine, who guided me in the right direction. As per him, such a thing should be decided by the system at record creation method. And that is the FormRun class method: createRecord().

Example

One of the example is the PurchAgreement form, where the system decides at runtime if the agreement line is quantity based or volume based (depending on Comitment type field inrespective helper class instance). This is implemented in PurchAgreementr Form's CreateRecord method. 

createRecord() implementation at PurchAgreement form

There they have used the FormDataSource's method createType to specify exactly which child table is to be instantiated. Evaluating the commitment type member, a map is instantiated with a value pair of data source name and child table id are set. The map is then sent as parameter to 
FormDataSource > createTypes() method which takes a map in params. This method internally decides the fate of the record i.e which child table the record will belong too. Setting the instancerelationtype members are probably internal to this method.

For even better understanding of concepts, I am attaching this valuable excerpt

An excerpt from Inside Dynamics AX 2012

Traditionally, to create a record in X++ code you only had to call the FormDataSource.create method. However, that method does not let you specify the type. To support the polymorphic creation scenario, use the following method: FormRun.createRecord(str _formDataSourceName [, boolean _append = false]) All create actions performed by the kernel are routed through this method. You should use this method as well instead of the create method. The first parameter specifies the name of the form data source in which to create the record, and the second parameter contains the same append value that is passed to the create method. You can override this to put in conditional code that depends on the type being created. The call to the super of the method executes the correct logic depending on the type.

Links

AX 2012 R3 SSRS: publishreportcommand network name cannot be found


SSRS report deployment gives error, "The network name cannot be found."


Audience

Dynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users

Background

When deploying a SSRS report, you may come across the error. This error will occur while deploying report(s) through AOT as well as using PowerShell scripts.


Experience tells us that such issues may occur if service accounts (AOS, BC proxy, Workflow) are wrongly configured. In our scenario, we had to reconfigure and put the newly provided service accounts. As a result, the reporting services crashed. We made sure all the practices related to configuring system service accounts are met. However we kept getting this error. report deployment were attempted both using AOT and PowerShell

Solution(s)
Thanks to sharing, the coolest caring. we cam to know the following link that clearly mentioned the reason of this issue.

https://blogs.msdn.microsoft.com/axsupport/2013/03/13/deploying-reports-in-ax2012-you-need-access-to-the-administrative-share-c/ 

In the post, the user uses the verbose modifier in the publish command in PowerShell to get more details. That yields that a network shared location access is attempted by the script. Now the question is, if such access is available or not. As a resolution, providing the C drive (reporting services server) as network shared resource resolved the issue.

Links

AX 2012 Workflow: Function run has been incorrectly called.

maqk® by Maqk | 6:06 PM

AX 2012 Workflow: Function run has been incorrectly called.

Workflow submit ends in error notification when submitting to workflow from code

AX 2012 Workflow: Function run has been incorrectly called.

Audience

Dynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users


Background

At the point of submitting a workflow, the comment dilog box appears. The class, is constructed needing a table buffer. The tupple must contain a row for the active workflow. This is usually passed by the statement
args.caller().getActiveWorkflowConfiguration()
The following  listing provides a detailed context

    workflowSubmitDialog = WorkflowSubmitDialog::construct    (args.caller().getActiveWorkflowConfiguration());
    workflowSubmitDialog.run();


Problem

Our working form stopped to resolve a particular configuration for the workflow. This was pretty strange behavior as a lot of records completed different scenarios of the workflow in success. we refreshed AOT items, generated incremental and FULL CIL, restarted the service, cleared the cache, but nothing worked.

Solution(s)

This must be a configuration or framework issue as a working workflow stopped being not able to find a particular version row (which exists in the table). Several investigatory steps were carried as mentioned in the problems section but none resolved the issue.

Alternatives

The solution should be a framework refresh. The only quick alternative for us was to write an alternative i.e fetch the existing version row our self and provide it to the WorkflowSubmitDialog[C] object. We did as follows;

  • Write a custom method in [T]WorkFlowVersion that returns the buffer. The following query does the job
select firstOnly1 *
   from
workflowVersionTblBfr
    join workflowTblBfr
    where
workflowVersionTblBfr.WorkflowTable     == workflowTblBfr.RecId &&
workflowVersionTblBfr.Enabled           == NoYes::Yes           &&
workflowTblBfr.TemplateName             == _wfTemplateName    
        ;
        return workflowVersionTblBfr;
    • Call the new method in the submit method of the WorkFlow SubmitManager class once it is verified that the workflow version is not being fetched by the framework

      Method navigation: Workflow submit manager class > Submit method > add call after workFlowSubmitDialog object is constructed
    //
        if (!workflowSubmitDialog || !workflowSubmitDialog.parmWorkflowConfiguration() )
    workflowSubmitDialog = WorkflowSubmitDialog::construct(WorkflowVersionTable::T4ED_GetWFConfig
    (workFlowTypeStr(T4EDPurchPORecWFType), tableName2id(tableStr(T4EDPOProdRecConfExtWF)), recId
    ));
    //

    Note: Since you are submitting a workflow, you don't need to look for the record specific workflow version. This would be mandatory if we are taking any action on an already submitted record. In such scenario, we will require to search for configurations that exists in WorkflowWorkItem table for specific table and record.


    AX 2012: Invalid application object name error while creating child table fields

    Error message: 

    Invalid name. The application object already exists. 

    Audience

    Dynamics AX 2012 (FP, R2, R3) X++ Developers, Functional and Technical consultants and advanced users


    Background

    Using inheritance in tables, you may receive the subject mentioned error
    "Invalid name. The application object already exists."

    Problem

    This error comes due to the fact that two tables inheriting from the same base table cannot have fields with same name. To avoid such error, you need to put distinct name among each table extending the same base table.

    Reason

    The reason is not any of the object oriented myths :) The simple reason is that, no matter how many levels of abstraction the AOT layer add to schema items like tables, a table among its extending tables exists only once at the database layer (SQL) . This is like that since child tables actually only exists at AOT layer. Physically there is one single base table. The data resides in one table physically which is abstracted at AOT as child tables.

    That means, if you have a base table with 100 child tables, there would be only one physical table for all of them at the database layer. For this reason, you cannot have same name field(s) for different child tables extending same base table.

    Conclusion

    Keep each child table's field names distinct among all sibling tables.

    AX 2012: You are not authorized to access table ‘’ (). Contact your system administrator.

    Audience

    Dynamics AX 2012 (FP, R2 R3) X++ Developers, Functional and Technical consultants and advanced users


    Background

    You may experience the subject mentioned error while opening a table / view

    Problem

    I experienced this error while creating a new view. When I accessed it to see if it is working as expected, I received this error.




    I carefully examined and found that actually no fields are added into the view.


    Solution(s)

    At this point of time, every one knows the solution, add some field dude. Adding fields to the view solves the error. However this error is quite distracting as it can take you to an American Wild Goose chase i.e. towards security and authorization implementations. so keep googling before diving straight into the deep AX sea :P


    AX 2012 - Understanding AOT Maps with an example

    maqk® by Maqk | 7:17 PM

    Understanding AOT Maps with an example

    Subject: AOT Maps

    Audience: Dynamics AX Developers

    Background

    Maps are not new concept in software development actually. They are table wrappers to achieve general behavior. However for lame dude(s) like me, these definition words have not been enough.

    Problem

    The term allotted to Maps, "Map" itself is a bit confusing. But an example can really help understanding. And Maps are used everywhere, but in comparison to tables and classes ( see these building blocks are essential for any kind of most basic development), use of maps are quite rare.

    Example

    I have been browsing PurchTableHistory table. A method came into my consideration where I see the use of Map.  

    The method, PurchTableHistory[T] >> initFromPurchTable() declares several maps based on localized buffers. Look at the following code

    // Code example

    PurchTableMap purchTableMap;
    purchTableMap.data(_purchTable.data());
    this.data(purchTableMap.data());
    First, the row from PurchTable is copied to the map variable, 'purchTableMap', and then, the history buffer gets the same row but form map, and not from the original source, purchTable buffer

    WHY ? Their must be a genuine need ? Why don't we copy from the original PurchTable buffer  ? Becuase we cannot :) becuase of schema change. See if most of the fields are same but not with exact field names, types and filed list count, we cannot copy a row from one table to another using xRecord[C].data() simply because of schema mismatch.

    Here is where map can work, since the different name same type and purpose fields are MAPPED in the MAP :). Fields with different names from different tables are mapped to consistent names in map, so that you can use them to map one row ( from one table buffer) to another table.

    Updated: Rephrasing the above in other words, map can be used to manipulate common schema among different (and having entirely different schema ) tables. It is like not knowing a buffer at runtime, expecting from it to be implementing a consistent schema with labelling issu

    One more thing, when using maps,
    field count doesn't matter since the map will only care and execute on the schema defined in the map. It simply would not care for schema defined in the mapped tables, it would only care for the schema defined in the MAP

    Happy MAPPING

    Links

    Valid length of a form field label

    maqk® by Maqk | 3:34 AM

    AX sometimes surprise you. Such surprise often make you chase a wild goes all day to reveal it was just a dead rat :@

    This just happened with me but all to reveal something I don;t think would be available on internet

    Try these:

    1. Find or create a label with 250+ length. 
    2. Assign this label to a form field (not static field or any such control)
    3. Open that form
    4. Your client just crashed
    Why am I telling this to you at all is the fact that my client wanted me to put huge texts against form fields. Weird, but sometimes we face requirements about which client donot accept any consultancy or education, and we just HAVE to implement it.

    Now can you imagine how wild those 400+ length labels made me work and search and find the clue why my client is crashing. I went through everything including full compile, sync, cache cleanup, .auc files, label file regeneration. I had to take every step due to the reason that evenvwr log was not much of a help in my scenario. I am attaching the log for your reference here;


    Application: Ax32.exe

    Framework Version: v4.0.30319
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.AccessViolationException
    Stack:
       at Microsoft.Dynamics.Kernel.Client.ActionPaneInterop.ClickEventHelper.Clicked(System.Object, System.EventArgs)
       at Microsoft.Dynamics.Framework.UI.WinForms.Controls.ActionItem.OnButtonClick()
       at Microsoft.Dynamics.Framework.UI.WinForms.Controls.ActionButton.OnMouseUp(System.Windows.Forms.MouseEventArgs)
       at System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)
       at System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
       at ._wWinMainCRTStartup()


    Conclusion
    Length for a field label (non static text control) is 250

    AX 2012 R2 - Installing new databases from setup

    maqk® by Maqk | 7:43 PM

    Their can be scenarios when you want multiple databases on the same service. For example having a separated testing environment, development environment, staging and production.

    I mentioned one such scenario in one of my previous posts in which I installed the new databases only to see the face of another error :) The 110 error code. 


    The thing is, when you install new databases from the AX 2012 R2 setup, it does install new databases quite successfully. However, it misses two critical stored procedures on the database, the CREATESERVERSESSIONS and CREATEUSERSESSIONS

    You can get these stored procedures from any dynamics ax 2012 r2 database and an apply on to your new database to fix the error.

    Dynamics AX 2012 R2 Fatal SQL condition during login

    maqk® by Maqk | 6:26 PM

    An interesting yet dangerous thing happened in my AX life today. Actually in one of our environments, we had previously upgraded to CU6. Now somehow the AX server VPC got restored to the earliest snapshot available forcing us to install a new fresh AOS service instance. The service was installed in no time but only to give the following error at each start and failing each time.

    A peep into the event log yield the following information:





    Object Server 01: Fatal SQL condition during login. Error message: "The internal time zone version number stored in the database is higher than the version supported by the Kernel (4/2). Use a newer Microsoft Dynamics AX kernel."
    I have the following roadmap for the resolution now :)

    1. Install clean databases with new names
    2. Connect installed service to new database and start AOS service
    3. Compile application code and sync database
    4. Upgrade to CU6
    5. Connect AOS service with existing CU6 compatible databases
    6. Resume from whatever we left
    To my retro suprise, the service failed to start with error code 110 after configuring to connect with new databases. This matter was resolved menrioned in another blog.

    Now resuming from point 3 :) 

    DAX 2012 R2 CU6 SYP Labels issue fix

    maqk® by Maqk | 12:26 PM

    I recently upgraded my local environment from Dynamic Ax 2012 R2 (Flat: build no# 6.2.158.0) to CU6 (6.2.1000.1437 - 2012 R2 Cumulative Update 6 (CU6)). The process was seamless however one issue arrived. The lable files. A lot of labels (in various mnodules including GL etc) started appearing as just flat label IDs 


    Info log after CU6 upgrade

    I found the solution in one of Ing. Karel Fischl's msdn blog: Missing SYP labels after upgrading to AX2012 R2 CU6 with just a minor adjustment, the two types of files to be removed from the location: are 

    • ALC files (Label description)
    • ALD files (Label data)
    And thats it, worked 100% on my production :)

    Dynamics AX 2012 - Workflow not working properly

    maqk® by Maqk | 3:56 PM

    While doing some customizations, I needed to use the purchase requisition workflow. However after submitting the purchase requisition, the workflow wont proceed and no work items would create.

    Batch job and Batch groups

    Workflow is dependent on batch groups. Perhaps all tasks appearing under the 'Periodic' heading are. The development environment I was working on had an empty named batch group. But the problem is not with a no name or empty name thing. It is the details the batch group carries, if it carries any :)

    A Batch Group represents a Batch Server (AOS Server)

    Its all about distributing workload and responsibility, for load balancing. A batch group posses no significance if it has no AOS servers associated to it. See the picture below;
    System Administration > Setup > Batch Group

    Hence if the workflow activities and tasks generated are being dependant on an empty batch, such activities wont occur / complete.

    The Story

    In my case, the empty batch group was really empty (rotfl) and I dont know for what reason it was like that. What really happened was that first I went to sys Adm > Inquiries > Batch Jobs. There I tried to tweak with multiple waiting, error status jobs. I came to find that only the With Hold status jobs are modifiable. Once that was known, I started putting the jobs on this status and doing things with them. There I saw no name appearing in the batch. This also raised the question if this empty batch associated has issues with it. Later I went to see no server is associated with the group. I associated the default and only AOS server  on the VM to the group and there you go :) Happy workflowing

    Some useful links for your reference are attached below;

    Links

    For quite some time, I was looking for this answer ? What benefit in the world does multiple models give ? I just could not figure it out from the basic definitions available at most of the places

    A model is a set of elements in a given layer. Each layer consists of one or more models. Each layer contains one system-generated model that is specific to that layer. Every element in a layer belongs to only one model. In other words, no element can belong to two models in the same layer, and every element must belong to a model.
    There we some questions that kept arising all the time

    • Is the end user suppose to switch in between the available models ?
    • If two or more models can be operational, what in the world is is the significance of the current model
    And so many more, it was all too frustrated. To my surprise, most of the available developers and consultants were even not able to clear my concept of the purpose of multiple models side by side. To my luck, I came across a convergence video about models and metadata architecture. There, the presenter cleared it all away. 

    Actually models are providing a way to export customizations (from say development or staging environment ), import them in another environment (production) without disturbing as many models already installed from n numbers of ISVs and vendors. 

    Let me explain the concept with an example. Lets suppose you being an end user have a customization deployed in your production environment from vendor A, on the form, say.... Vendor List Page. And those customizations has additional menu buttons in the Action Pane. Now you bought another solution which has other customizations on the same form. Now you already have the Vendor form customized in, say VAR layer and the new vendor is also developing customizations in VAR layer ? So how would the two different versions co exist now ? How would the same element on the same layer have 2 different versions with end user expecting to get the new customizations without disturbing the already deployed customizations. This is where models come to play :) 

    Since each layer can have multiple models, or slices if you ask the framework developers, each vendor can now produce their own model, install at the same layer, and both co exists meaning 2 different model customizations will be available at run time for the end user. This has questioned both of my questions actually since the current model is for developers and not for end users and that all models on respective layers render on runtime shadowing the layers  underneath.

    Country Region codes in Dynamics AX 2012 R2

    maqk® by Maqk | 11:51 AM

    The hierarchy of License Codes and Configuration Keys have one more far related cousin to mention here, The Country Region Code. I have just figured out this relation due to the nature of both being the same, Enable / Disable functionality. 

    License Codes toggle features. Configuration Keys toggle various functionalities inside the boundaries of those features. Country / Region Codes toggle what? The answer to this is nothing from out of the box but neither is my topic to discuss here. 

    Country / Region Codes can perhaps toggle both features and functionalities inside, but based on what ? is my topic. Again its simple so lets keep it simple. A picture worth a million words, or sometimes even more than that :)



    Country / Region Codes - Applicable at both Table and Field levels


    The question is how do they apply in AX 2012 ? Previously to toggle country region specific functionality, country region configuration keys were provided. In R2, those keys are still there, but they don't toggle any thing, because regional functionality toggle is now seperately handled at country region codes. This CountryRegionCode attribute is applicable on tables, fields, EDTs, BaseEnums, Forms (fields and controls), Menus, Menu Items etc

    From the above image, it is clear that we have a couple of country region code specific fields to apply a particular region code to an item. That means each item can have a list of country / region code on which it will be available. Now how to apply a country / region code to the running system ?  And which country / region code is currently active ? The answer to these very basic questions is the country location of the primary address of the currently active company. Let my quote Microsoft here :)

    Features that are specific to a country or region are enabled and disabled based on the primary address of the legal entity. For more information, see Create or modify a legal entity. [src]
    &
    The country/region that you select for the primary address of the legal entity controls the country/region-specific features that are available for the legal entity. [src] 

    Apart from all this, one more thing that you should know is that security keys are obsolete in AX 2012 R2. Click here for more.

    Links

    Applying Country Specific Functionality [AX 2012]


    Though it has been very boring and time consuming for me in the beginning, yet it ended quite fruitful to me in the end :)

    Without further delay, one of the most common and basic task when implementing an enterprise system is to import the legacy system setup data into the new system. The objective of this post is to share all the basic tools and scenarios you will need to import / export data.

    This post will specifically provide guidance on importing records from external sources like excel file into Microsoft Dynamics AX 2012. But first of all, lets see how much variety has Microsoft provided in the regards of data import export and migration between the AX and other system;

    http://technet.microsoft.com/en-us/library/aa548629.aspx : A worthy resource to begin with. Read the small article and get a good basic idea of all the tools provided by Microsoft and their purposes.

    Secondly lets get hands on importing a few records in some setup table of AX, say MainAccount (chart of accounts table). By the way you can import data into any AX table

    Quoting from the above mentioned post:
    Microsoft Excel Add-in: Excel import is a tool that can be used for data in an Excel format, or in a comma-separated list. You can use built-in or custom templates to help users import data. Use this tool in the following situations:
    • Minimal data cleansing by end users is required.
    • You are handling low to medium data volumes (< 10,000 records).
    • You are working with simple data structures that can easily be flattened.
    • No business logic is required outside an existing document service.
    Now since this is quite a handy and straight forward tool powerful enough to handle around 10000 records, it would be the pick for us for basic setup data import. Hence we will use excel add in for setup data imports.

    Installation
    For installation and configuration with AX, see these posts:
    http://msdax.wordpress.com/2011/05/14/office-addins-dynamics-ax-2012/

    Usage:
    The usage as far as import is concerned is fantastically straight forward. And if the tool is rightly configured (i was lucky to got it configured already at my place :) ),  its as easy as PIE literally. All you have to do is to follow the following straight points:
    • Create a new document.
    • Go to Dynamics AX tab
    • Scroll click the Action Pane > Design > Add Data command menu button
    • Click Add tables menu item
    • Select the desired table (all tables are provided, in our example we will select the MainAccount table)
    • This will enhance the excel UI with a Field chooser left bar (showing all the fields) and a few mandatory fields (typically the PK and FKs) dropped over the worksheet.
    • Select at least all the mandatory fields required to save a valid record in the selected table. In our example, we will drop the following fields;
      • Chart of accounts
      • Main account
      • Name
      • Main account type
      • Reference ID
    • To load data from the table: Close the field bar (which should enable the publish button) and hit Action Pane > Update > Publish
    • Start creating records by simple typing and tabbing to next fields and to next records.
    • To save your work back in AX, hit the publish button and you are done
    • Publish button disabled: Close the field bar on the left. You should close this bar as soon as you are done with choosing the fields. Closing the field bar may result in wiping all the newly created records. Make sure you close it as soon as you are done adding the fields
    There are quite a lot worthier posts on the internet on the topic. The goal of this post is to bring under 1 umbrella all the basic steps required to start importing data and share / reuse existing worthy resources over the internet on this topic. The most worthy of them I found are the data import series blogs here: https://community.dynamics.com/ax/b/ax2012exceldataimport/default.aspx

    Enjoy importing data into Dynamics AX like APIE :)

    Class diagram for Number Sequence Framework [partial]

    maqk® by Maqk | 3:41 PM

    In continuation to a post written several months ago [http://dotnetxperience.blogspot.com/2012/07/number-sequence-framework-in-dynamics.html ], I thought to make a class diagram in order to show all the related objects required for successfully implementing the number sequence framework. The original motive was to write one COMPLETE post depicting all aspects fo the framework however i am not satisfied from my effort. I will improve it for all of you and for myself as well.

    At the moment, I am sharing the class diagram. It s not the best of them, but for sure it will assists all of us in better understanding of the framework.


    Some tips when using Expressions in X++ Dynamics AX

    maqk® by Maqk | 2:04 AM

    Expressions come to rescue when you need to code complex joins and constraints in your queries. I always have trouble setting my larger expressions with quotations and parenthesis  It always looked perfect but they always gave error. This was due to no proper Expression specification under my observation untill I found the following (The excerpt is taken from a book on AX: Microsoft Dynamics AX 2012 Development Cookbook )


    • The expression must be enclosed within single quotes.
    • Inside, the whole expression has to be enclosed in parenthesis.
    • Each sub expression must be enclosed in parentheses too.
    • String values have to be enclosed within double quotes.
    • For enumerations use their numeric values.
    • For value formatting use various Dynamics AX functions, such as queryValue(), Date2StrXpp(), or methods from the SysQuery class.


    Lookups and drop downs in AX - Part I

    maqk® by Maqk | 9:49 PM

    Lookups are pretty straight forward, drop the related field and AX should bring a nice drop down to you. However things can get pretty nasty when you apply further behaviour, the simple drop down remains no simple.

    As i just wrote the one liner, drop the field and there u go. However there are other methods to achieve better results as well.

    Depending on the join, the behaviour and display of the lookup depends. A RecId based master child relation field will drop the RecId of the master record. Se below;


    The objects I have used to achieve the above are;

    • 2 tables named master and child. 
    • Joined child table with master as a 1 to many relations
    • Created a new form (no template), added both tables in the data sources. 
    • Dropped the relation field on the form.

    Thats it, but the result is pretty rough, not helpful to the UI at all, what does that 10 digit typical surrogate means to the end user, its a nightmare for him. The good thing is, there is no nightmare for the devs :D

    What MorphX has done is place an integer field on the form bind to the child data source's master table relation field. The existing relation provides the lookup behaviour automatically, no code to override, no nothing, pretty straight forward.

    AX is a great RAD platform, it does not give u time to do all the coding for these small repeating things, its already there, u need to know how :D

    Well the most usual practice a dev has is to copy an existing behaviour, that will do the job, but I actually went a little deeper into it and played with all the relevant features available. Lets dive in then.

    The Table's Autolookup group

    There exist a default group for each table, 'Autolookup', lets drop a field into it and see the difference if any;
    To achieve this, i placed a data field (any field u can choose) in the Autolookup group of the master table. We have edited the master table for the simple reason that the drop down or lookup is supposed to fill from there :D



    The result of this is;

    As you can see, the code field has started appearing next to the unwanted RecId. This is at least a little better than the first pure raw result. Of course we still need to remove the unwanted id, but what we learned from this step is that fields present in Autolookup group of a table starts appearing in lookups belonging to that table.

    Lets add another field to ensure what we learn is exactly what we just described :D adding 1 more field results in following;

    Hence ensured. This means we need to fill the Autolookup group for every setup / master table so that a decent user friendly lookup appears whenever a reference is made to them.

    But the unwanted rec id is still bothering, and also 1 more thing is the behaviour of the form when a particular value is selected; see below;


    After a selection is made, the same rec id is appearing about which, the user have no hint what has it actually selected.

    Lets see if adding an Index have an effect on this. An index is basically created on a table on fields so that searching gets fast. But it is also used as a means to achieve uniqueness on a particular set of fields.

    Adding an index on a third filed has no effect on the lookup (no new image required :D)
    However, removing each field from Autolookup group with an index on a third field (which was never part of the Autolookup group) brings the following result;


    This means that field(s) present in Index(es) appears in the lookup of that table. However, fields in Autolookup group overrides them. We are finding core facts here, no theories, and I really enjoy this :D

    The unwanted RecId is still appearing, lets see what another default group AutoIdentification has to do with it

    The AutoIdentification group
    By default, you can never add any field in this group by dragging your custom selection. The only way to add a field into it is to create an index.

    Adding a simple, non unique default index does nothing to the AutoIdentification group, we will need this index set as a replacement key. To do this, the index must be unique (set allow duplicates to No in the property sheet) and select this unique alternate key index as the replacement key for the desired master table. There you go, you got the index field in the AutoIdentification group :D, illustration for you for precise guidance :D



    This brings the indexed field 'code' in the AutoIdentification group.

    But how will it effect our lookup ? Well the answer is, now AX knows your master child relationship more better, so Drag the same field once again, and to your surprise, this time it wont be a simple integer field bind to the child table, its a whole new 'Reference group' control.


    Now we have 2 lookups on the form actually, the one with the previous incomplete table configuration (integer field bind to child table's master referencing field) and the new Reference group with more properties to explore :D

    This has get us rid of the unwanted RecId, now we have quite a decent lookup appearing at our screen. The user will be delighted to see this as compared to the previous ones. And as we have already learned, adding more fields in a lookup can make lookups more detailed if required.

    Scenario: Show more fields in lookup but select specific
    Yes, how can we achieve this? That is, show some filed in the lookup , but when selected, a different field gets selected in the textbox area. What I am trying  to say is a typical code description scenario in which user opens a lookup that shows code and descriptions both, but  once a selection is made, only code is selected. How to achieve that ? Well again as so many times you have read that AX is fast RAD platform, nothing takes long time here. To achieve our this goal, we need to look at some of the properties on the reference group control.

    Reference group control - Details
    The key properties of this control are as follows;

    • ReferenceField: A reference field on the bound data source to use as the physical binding. This field is not displayed to the user
      In short, this is the field which will be used behind the scenes and the record will be populated with this value. In our example, the reference field is the 'master' field in the child table, the rec id of the master table's record the user selected in the drop down.
    • ReferenceFieldGroup: A field group on the primary key table to use as the logical binding. These fields are displayed to the user.
      In our example, the group selected is the AutoIdentification group, which was populated when we created a unique index, used it as alternate key and set it as master table's replacement key.
    Other fields of course contains data source and data field, whenever dropping a lookup form master table, drag the field from the child table, not the master table since the changes are to be made in child table no the master one :D

    Now to have multiple values displayed when lookup is opened and select one of them in the drop down, we will do the following

    add multiple as many fields you want to display to the user when lookup is opened, we will add code and descr fields. And already in the AutoIdentification group, we have the code field ( the indexed field), so this will bring us the desired results. The following is the table level filed group configuration and then its result:



    This is the way to do the simple lookups in AX. To conclude all this, i have written concluding points below. For more advance topic, I will write the Part II tomorrow إن شاء الله‎ 

    Conclusion:

    1.) Autolookup overrides index
    2.) Fields from each index are fetched in lookups along with PK (RecId) when no field exists in autolookup group of primary table.
    3.) When multiple indexes used on table ( & no field in autolookup), first field of each index is brought, depends on their order in index.
    4.) Use Reference group control for better user friendly lookups. Reference group provides two properties 'ReferenceField' and 'ReferenceFieldGroup' which fetch relevant data in the lookups as required by the user



    top