вторник, 30 июля 2019 г.

How to filter record by dimension values in D365


Hi all,

It's been a long time I wrote the post in my blog. But today I will fresh it by writing the new one.

I got a task - to filter the query on worker's default dimension fields. This was quite challenging for me.
First I did it via DimensionAttributeValueSetStorage class.  It didn't feet the requirement because the functionality has to have a possibility to filter records via any of the dimensions (Division, Location, CostCenter, Department, etc).
Next, I found an article about DimensionsProvider class which has some sort of abilities that I was needed. And I used it.

It worked as expected and as required!

So, below I provided a piece of code which you can interpret for your requirements, but I believe the general concept will be clear:

private void filterResourcesByDimensions(Query _q)
    {
        Counter                             i;
        DimensionAttribute                  dimensionAttribute;
        str                                 dimValue;
        container                           workerDefaultDimension, workerDefaultDimensionVal;
        QueryBuildDataSource                qbdsResource;
        
        DimensionProvider                   dimProvider = new DimensionProvider();

        workerDefaultDimension = ['Division', 'Location', 'Region', 'ServiceLine', 'SubService'];

        workerDefaultDimensionVal = [_context.division(),
                                    _context.location(),
                                    _context.region(),
                                    _context.serviceLine(),
                                    _context.subService()
                                    ]; //Dimensions values (any)

        qbdsResource = _q.dataSourceTable(tableNum(ResCompanyResourceView));
   
        for (i = 1; i <= conLen(workerDefaultDimension); i++)
        {
            dimensionAttribute = dimensionAttribute::findByName(conPeek(workerDefaultDimension,i));
       
            if (dimensionAttribute.RecId == 0 && conpeek(workerDefaultDimensionVal, i) == '')
            {
                continue;
            }
       
            dimValue = conPeek(workerDefaultDimensionVal,i);
       
            if (dimValue != "")
            {
                dimProvider.addAttributeRangeToQuery(_q, qbdsResource.name(), identifierStr(DefaultDimension), DimensionComponent::DimensionAttribute, dimValue, dimensionAttribute.Name);
            }
        }
    }

Feel free to contact if you still have any questions! I'm