cloud
cloud

Reputation: 11

Visual has exceeded the available resources

I try to develop a dax code which calculates my companies obsolete stock. On the way to achieve this I had to derive some own measures (Please note that I am not the owner of the Datamart and cannot adjust something from there). In the final step it seems to be that one of my formulas (see 2nd below) requires too much processing power as I get the error message:Visual has exceeded the available resources. Since I am not an expert in PowerBI/DAX I am wondering whether the structure of my code is maybe causing those performance issue and whether I could make it smarter so that it finally works?

The measures I have created are following one:

1) Inventory Reach: This works fine and does not create any error message even though I run it on lowest level

Inv Reach = 
    CALCULATE (
        DIVIDE ( SUM ( dimMaterialPlantSpecific[StockQTY] ), [Avg cons 5y] * -1, 9.01 ),
        FILTER (
            dimMaterialBasic,
            dimMaterialBasic[CrossPlantMaterialStatusID] <> "BI"
        ),
        FILTER (
            dimMaterialBasic,
            dimMaterialBasic[CrossPlantMaterialStatusID] <> "BO"
        )
    ) +

        CALCULATE (
            DIVIDE (
                SUM ( dimMaterialPlantSpecific[StockQTY] ),
                [Consumption QTY Last 3 Years] * -1,
                9.01
            ),
            FILTER ( dimMaterialBasic, dimMaterialBasic[CrossPlantMaterialStatusID] = "BO" )
        )

2) Devaluation class: Here the trouble starts. When I add this measure to my visual it crashes and I get the error message mentioned in the header. So do you see any possibility for optimizations?

Dev Class = 
SUMX (
    dimMaterialBasic,
    IF (
        AND ( dimMaterialBasic[CrossPlantMaterialStatusID] = "BB", [Inv Reach] > 9 ),
        1,
        IF (
            AND ( [Inv Reach] > 1, [Inv Reach] <= 2 ),
            0.05,
            IF (
                AND ( [Inv Reach] > 2, [Inv Reach] <= 3 ),
                0.15,
                IF (
                    AND ( [Inv Reach] > 3, [Inv Reach] <= 4 ),
                    0.25,
                    IF (
                        AND ( [Inv Reach] > 4, [Inv Reach] <= 5 ),
                        0.35,
                        IF (
                            AND ( [Inv Reach] > 5, [Inv Reach] <= 6 ),
                            0.45,
                            IF (
                                AND ( [Inv Reach] > 6, [Inv Reach] <= 7 ),
                                0.55,
                                IF (
                                    AND ( [Inv Reach] > 7, [Inv Reach] <= 8 ),
                                    0.65,
                                    IF (
                                        AND ( [Inv Reach] > 8, [Inv Reach] <= 9 ),
                                        0.75,
                                        IF ( [Inv Reach] > 9, 0.85, 0 )
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)

Your help is much appreciated.

Thank you in advance

Upvotes: 0

Views: 3642

Answers (1)

RADO
RADO

Reputation: 8148

There are a lot of issues with the code... I'll make some suggestions but keep in mind I have no way of testing them, and some key information is missing (data model and formulas for [Avg cons 5y] and [Consumption QTY Last 3 Years] measures).

First, create a basic measure for stock quantity to avoid writing it multiple times:

Stock Quantity = SUM ( dimMaterialPlantSpecific[StockQTY])

Then

Inventory Reach =
    VAR Stock_Quantity = [Stock Quantity]
    VAR Consumption_5Y = - [Avg cons 5y]
    VAR Consumption_3Y = - [Consumption QTY Last 3 Years]
    VAR Default_Reach = 9.01
    RETURN
    CALCULATE (
        DIVIDE ( Stock_Quantity, Consumption_5Y, Default_Reach ),
        NOT dimMaterialBasic[CrossPlantMaterialStatusID] IN { "BI", "BO" }) 
    + 
    CALCULATE (
        DIVIDE ( Stock_Quantity, Consumption_3Y, Default_Reach),
        dimMaterialBasic[CrossPlantMaterialStatusID]="BO")

Here, we stored calculations in variables to avoid calculating them multiple times. I also removed multiple filtration. Default_Reach is stored in VAR to make code easier to understand and maintain.

Second measure can be simplified as follows:

Dev Class =
SUMX (
    dimMaterialBasic,
    VAR Inventory_Reach = MAX ( TRUNC ( [Inv Reach] ), 9 )
    RETURN
        IF (
            dimMaterialBasic[CrossPlantMaterialStatusID] = "BB" && Inventory_Reach = 9,
            1,
            0.1 * Inventory_Reach - 0.05
        )
)

SUMX is essentially a loop. The key problem with the original code is that it calculates measure [Inv Reach] many times, and it does it in a loop. To fix this, we can use a few techniques:

  • Store [Inv Reach] in a variable. This insures that it will be calculated only once for each iteration of the loop;
  • Then, your if conditions can be simplified if you notice that your results can be computed with a simple formula that depends on the integer part of Inv Reach (i.e, it's 0.85 - 0.1*(9 - [Inv Reach]), which you can simplify algebraically to 0.1*[Inv Reach] - 0.05. So, I calculated the integer part by truncating fractions, and also capped it at 9 because all levels above 9 are treated the same way. The calculation then becomes a simple IF;
  • Please notice that you have not defined results for Inv Reach < 1, so I did not handle the situation.

Upvotes: 3

Related Questions