Search code examples
daxdimensional-modelingazure-analysis-services

DAX Default to last value with data


Presently my data returns:

enter image description here

What I need it to do is if the current month has 0's, it will default to the last months value with data:

enter image description here

I know this can be done with nested IF statements, but is there a better way?

UPDATED WITH @TPD SUGGESTION

The results from @TPD suggestion yield:

enter image description here

With measure defined as:

 IF([Land Dev Alloc] = 0, CALCULATE([Land Dev Alloc],TOPN(1, CALCULATETABLE(Hyperion,FILTER(ALL(Hyperion), [Land Dev Alloc]>0)),Hyperion[DimDateID],DESC)),[Land Dev Alloc])

Where Hyperion is the main fact table that measure Land Dev Alloc pulls from


Solution

  • I'm not sure if this is the best way but I've recently solved a similar problem like this, assuming you have a Date table and a Value table joined with a relationship:

    CurrentOrLastValue:=
    CALCULATE (
    
        -- EXTRACT VALUE FROM ROW
        FIRSTNONBLANK( 'value'[value], 1 ),
    
        -- FIRST ROW FROM YOUR 'VALUES' TABLE REDUCED TO THOSE BEFORE THE CURRENT CELL DATE
        -- ORDERED BY DATE DESC
        TOPN (
            1,
            CALCULATETABLE (
                'value',
                FILTER
                ( 
                    ALL( 'date'[date] ), 
                    'date'[date] <= MAX( 'date'[date] )
                )
            ),
            'value'[date],
            DESC
        )
    )
    

    Data tables and Pivot Table

    Data tables and Pivot Table

    Measure

    Measure

    Relationships

    Relationships

    UPDATE TO SHOW MEASURE RESULT NOT RAW VALUE

    Add a new core measure (doubling values to show a difference):

    TotalValue:=SUM('value'[value]) * 2
    

    Add a new measure to show desired output:

    CurrentOrLastValueMeasure:=CALCULATE (
        [TotalValue],
        TOPN(
            1,
            CALCULATETABLE(
                'value',
                FILTER(
                    ALL( 'date'[date] ),
                    'date'[date] <= MAX( 'date'[date] )
                )
            ),
            'value'[date],
            DESC
        )
    )
    

    New measure in pivot table:

    enter image description here

    UPDATE TO SHOW LAST NON-ZERO VALUE WHEN MEASURE RETURNS ZERO

    LastNonZeroMeasure:=
    IF( [TotalValue] = 0,
        CALCULATE (
            [TotalValue],
            TOPN(
                1,
                CALCULATETABLE(
                    'value',
                    FILTER(
                        ALL( 'value' ),
                        [TotalValue] > 0
                    )
                ),
                'value'[date],
                DESC
            )
        ),
        [TotalValue]
    )
    

    TotalValue not being doubled anymore. Two data points for 4th Jan to show the measure's aggregation working.

    last non zero measure

    UPDATE TO IGNORE DATES AHEAD OF CELL DATE

    Try filtering the dates also...

    LastNonZeroMeasure:=IF( [TotalValue] = 0,
        CALCULATE (
            [TotalValue],
            TOPN(
                1,
                CALCULATETABLE(
                    'value',
                    FILTER(
                        ALL( 'value' ),
                        [TotalValue] > 0
                    ),
                    FILTER(
                        ALL( 'date' ),
                        'date'[date] < max( 'date'[date] )
                    )
                ),
                'value'[date],
                DESC
            )
        ),
        [TotalValue]
    )
    

    enter image description here