web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

X++ DIXF Class - idiots guide. HELP!

(0) ShareShare
ReportReport
Posted on by

Hi,

I am running AX2012 CU7 and running some migration trials. I am looking at migrating through the RouteOperations entity.

The entity populates the target field RouteOpr(RouteOpr).PropertyId for the respective route line.

I also need to populate (WrkCtrActivityRequirementSet).PropertyId. These two fields drive a modification we have implemented.

As you do, having never touched X++ before I set about modifying the dixf class. How hard can it be? It's not a straight map, but there are other fields in the WrkCtrActivityRequirementSet table that populate, so I just copy that.

I modified the class as below, copying the wrkCtrActivityRequirementSet.LoadPercent field syntax.

I compiled and ran an incremental CIL for good measure. Unfortunately my migration entity behaved no differently on the second pass. No problems, no errors, it just didn't populate as I had hoped.

I appreciate this isn't an x++ tutorial forum but I would appreciate someone looking over my code below to see if they can point me in the direction of what I did wrong.

public container GenerateRouteRequirement(boolean _stagingToTarget = true)
{
    WrkCtrActivity                          wrkCtrActivity;
    WrkCtrRouteOprActivity                  wrkCtrRouteOprActivity;
    WrkCtrActivityRequirementSet            wrkCtrActivityRequirementSet;
    WrkCtrActivityRequirement               wrkCtrActivityRequirement;
    WrkCtrActivityCapabilityRequirement     capabilityRequirement;
    HcmRatingLevel                          hcmRatingLevel;
    container                               res;
    WrkCtrId                                wrkCtrId;

    if (_stagingToTarget)
    {
        if ( target.RecId)
        {
            if(entity.UsedForOperationScheduling || entity.UsedForJobScheduling ||
            entity.RelationshipType || entity.RatingLevelId || entity.Quantity || entity.MinimumLevelNeeded ||
            entity.LoadPercent || entity.PropertyId || entity.Factor || entity.EntityType || entity.Description || entity.WrkCtrId)
            {

                wrkCtrActivity.EntityType =  WrkCtrActivityType::RouteOpr;
                wrkCtrActivity.write();

                select forUpdate firstOnly wrkCtrRouteOprActivity
                    where wrkCtrRouteOprActivity.RouteOpr == target.RecId
                        && wrkCtrRouteOprActivity.RouteOprDataAreaId == target.dataAreaId;

                wrkCtrRouteOprActivity.Activity = wrkCtrActivity.RecId;
                wrkCtrRouteOprActivity.RouteOpr =  target.RecId;
                wrkCtrRouteOprActivity.RouteOprDataAreaId = target.dataAreaId;
                wrkCtrRouteOprActivity.write();

                wrkCtrActivityRequirementSet = wrkCtrActivityRequirementSet::findActivity(wrkCtrActivity.RecId,true);
                wrkCtrActivityRequirementSet.initValue();
                wrkCtrActivityRequirementSet.Activity = wrkCtrActivity.RecId;
                wrkCtrActivityRequirementSet.Description = entity.Description;
                wrkCtrActivityRequirementSet.LoadPercent = entity.LoadPercent;
                wrkCtrActivityRequirementSet.PropertyId = entity.PropertyId;
                wrkCtrActivityRequirementSet.Quantity = entity.Quantity;
                wrkCtrActivityRequirementSet.write();

                select forUpdate firstOnly wrkCtrActivityRequirement
                    where wrkCtrActivityRequirement.ActivityRequirementSet == wrkCtrActivityRequirementSet.RecId;

                wrkCtrActivityRequirement.initValue();
                wrkCtrActivityRequirement.ActivityRequirementSet = wrkCtrActivityRequirementSet.RecId;
                wrkCtrActivityRequirement.RelationshipType = DMFEntityBase::string2Enum(entity.RelationshipType, enumNum(WrkCtrActivityRequirementType));
                wrkCtrActivityRequirement.UsedForOperationScheduling = DMFEntityBase::string2Enum(entity.UsedForOperationScheduling, enumNum(NoYes));
                wrkCtrActivityRequirement.UsedForJobScheduling = DMFEntityBase::string2Enum(entity.UsedForJobScheduling, enumNum(NoYes));
                wrkCtrActivityRequirement.write();

                select forUpdate firstOnly capabilityRequirement
                    where capabilityRequirement.ActivityRequirement == wrkCtrActivityRequirement.RecId;
                capabilityRequirement.initValue();
                capabilityRequirement.MinimumLevelNeeded = entity.MinimumLevelNeeded;
                capabilityRequirement.ActivityRequirement = wrkCtrActivityRequirement.RecId;
                capabilityRequirement.write();

                if(entity.WrkCtrId)
                {
                    this.createSubTypeRequirement(wrkCtrActivityRequirement, entity.WrkCtrId);
                }
            }
        }
    }
    else
    {
        select firstOnly wrkCtrRouteOprActivity
            where wrkCtrRouteOprActivity.RouteOpr == target.RecId
                && wrkCtrRouteOprActivity.RouteOprDataAreaId == target.dataAreaId;

        wrkCtrActivity = WrkCtrActivity::find(wrkCtrRouteOprActivity.Activity);
        wrkCtrActivityRequirementSet = wrkCtrActivityRequirementSet::findActivity(wrkCtrActivity.RecId);

        select firstOnly wrkCtrActivityRequirement
            where wrkCtrActivityRequirement.ActivityRequirementSet == wrkCtrActivityRequirementSet.RecId;

        select firstOnly MinimumLevelNeeded from capabilityRequirement
                    where capabilityRequirement.ActivityRequirement == wrkCtrActivityRequirement.RecId;

        select firstOnly1 RatingLevelId from hcmRatingLevel where hcmRatingLevel.RatingLevelId == entity.RatingLevelId;

        wrkCtrId = this.getSubTypeRequirement(wrkCtrActivityRequirement);

        res = [
            wrkCtrActivityRequirement.UsedForOperationScheduling,
            wrkCtrActivityRequirement.UsedForJobScheduling,
            enum2str(wrkCtrActivityRequirement.RelationshipType),
            hcmRatingLevel.RatingLevelId,
            wrkCtrActivityRequirementSet.Quantity,
            capabilityRequirement.MinimumLevelNeeded,
            wrkCtrActivityRequirementSet.LoadPercent,
            wrkCtrActivityRequirementSet.PropertyId,
            hcmRatingLevel.Factor,
            wrkCtrActivity.EntityType,
            wrkCtrActivityRequirementSet.Description,
            wrkCtrId];
    }
    return res;
}


I really want to get my teeth into X++ but it turns out AX implementations are pretty time consuming. Any assistance would be gratefully accepted (including any overview of what this is doing (res, container, piping || entity. , etc).

Cheers

*This post is locked for comments

I have the same question (0)
  • Mea_ Profile Picture
    60,284 on at

    Hi noooodlez,

    Without looking into it too deep, code looks ok. Are you sure that this field (PropertyId) is not empty in staging table ?

    You can easily check it from UI if you will go to execution history and check what do you have in staging table.

    If value is there but code does not work - it's time to debug!  You can go through this article msdn.microsoft.com/.../gg860898.aspx to get some idea where to start.

    If it's not clear for you, feel free to ask questions.

  • Community Member Profile Picture
    on at

    [quote user="noooodlez"]I really want to get my teeth into X++ but it turns out AX implementations are pretty time consuming. Any assistance would be gratefully accepted (including any overview of what this is doing (res, container, piping || entity. , etc).[/quote]

    “Piping” with “II” is logical disjunction (“or” operator), so in this case the whole if statement is evaluated as true if any of listed expressions (entity.UsedForOperationScheduling, entity.UsedForJobScheduling, etc.) is true.

     

    Container is a primitive type in X++ that is similar e.g. to arrays. In this case it is just used to return a set of results from a method. Advantage (as well as disadvantage) of containers is that they are not strongly typed structures, so they are often used to pass various data between methods.

     

    I wold suggest to look at some basic X++ documentation to get you started, e.g. from MSDN:

    X++ Language Programming Guide

    https://msdn.microsoft.com/en-us/library/aa867122.aspx

     

  • Suggested answer
    Community Member Profile Picture
    on at

    I presume that you added PropertyId as a custom field to WrkCtrActivityRequirementSet table (it’s not the standard field in Activity table, so it’s probably added with the relation to WrkCtrProperty table)?

    Have you stepped through the debugger to check if you’re actually getting any value passed in entity.PropertyId?

    Do you have any customization on wrkCtrActivityRequirementSet::findActivity() method? Common X++ issue with not updating field values is when the required fields are not listed in the select statement and therefore not included in a data set. E.g. when you have select forupdate FieldA, FieldB … and then try to assign a value to a non-listed (but existing in table) field FieldC. This does not trigger any runtime exception, it just fails to update any value in FieldC.

    So in case of findActivity() method (which returns the data set you are updating), I would check if select statement had been modified to include just some fields from WrkCtrActivityRequirementSet but not the PropertyId field.

    Also the following piece of code is not logical:

    wrkCtrActivityRequirementSet = wrkCtrActivityRequirementSet::findActivity(wrkCtrActivity.RecId,true);
    wrkCtrActivityRequirementSet.initValue();
    wrkCtrActivityRequirementSet.Activity = wrkCtrActivity.RecId;
    …
    wrkCtrActivityRequirementSet.write();

    Why would you be using findActivity() to find the matching Activity (which is a primary key for this table), only to overwrite it later assigning the same reference RecId value? The problem with this code is that it doesn’t do anything when matching record (wrkCtrActivity.RecId) doesn’t exists – it needs to check if findActivity() returns empty table and in that case do insert() and not write().

  • André Arnaud de Calavon Profile Picture
    300,911 Super User 2025 Season 2 on at

    Hi noooodlez,

    Can you shed some light on the new custom fields? I assume you created the new field on the staging table. Have you also included this field as part of the field group GenerateRouteRequirement? Did you regenerate the staging to target mapping from the Target entities form for this RouteOperations entity?

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#1
Priya_K Profile Picture

Priya_K 4

#3
MyDynamicsNAV Profile Picture

MyDynamicsNAV 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans