Forum Discussion

BradAF's avatar
BradAF
Icon for Helper I rankHelper I
6 years ago
Solved

Can't use SELECTEDVALUE alternate value with Filter

Hello,

 

I have a table that contains inventory items with a name column, and a scanned column.

 

I have a graph and table visualization I would like to default to the latest scan date, but the graph can be clicked on any date to see the results for just that scan date.

 

I thought I had it figured out by creating the Following SelectedOrMaxDate measure to return the MAX date from the scanned volume if nothing is selected:

MEASURE calculated_filtered[SelectedOrMaxDate] =
    SELECTEDVALUE (
        calculated_filtered[scanned],
        MAX ( calculated_filtered[scanned] )
    )

 

Then, I would get a count based on the selected/alternate date:

MEASURE calculated_filtered[LastScanFindings] =
    CALCULATE (
        COUNT ( calculated_filtered[taskid] ),
        FILTER (
            calculated_filtered,
            calculated_filtered[scanned] = 'calculated_filtered'[SelectedOrMaxDate]
        )
    )

 

It actually works perfectly IF a date is selected on the graph. If no date is selected, it just gives a count of ALL items in the database.

 

I set up a card to verify the alternate date is showing up correctly, tried manually converting and specifying the data type but all looks good. Filter just does not seem to want to use the alternate date:

 


Any thoughts? Is this perhaps a bug?

  • Hi BradAF  - for reasons that someone smarter than I can explain, the context in which the SELECTEDVALUE measure is calculated changes when you create it as its own measure.  However, if you write your counting measure as this

     

    MEASURE calculated_filtered[LastScanFindings] =
        CALCULATE (
            COUNT ( calculated_filtered[taskid] ),
            FILTER (
                calculated_filtered,
                calculated_filtered[scanned] = 
                      SELECTEDVALUE(calculated_filtered[scanned], MAX(calculated_filtered[scanned]))
            )
        )

    or even this

     

    MEASURE calculated_filtered[LastScanFindings] =
    var __myDate = SELECTEDVALUE(calculated_filtered[scanned], MAX(calculated_filtered[scanned]))
    return
        CALCULATE (
            COUNT ( calculated_filtered[taskid] ),
            FILTER (
                calculated_filtered,
                calculated_filtered[scanned] = __myDate 
            )
        )

    You should get the results you are looking for, both with and without a date being selected.  DAX is funny that way in that splitting up the work into multiple measures does not always yield the right results.

     

    Last date (RecCnt2 mirrors the code in this post)

    Other Date

     

    No Date

     

    Hope this helps

    David

  • AlexisOlson's avatar
    AlexisOlson
    6 years ago

    dedelman_clng Is correct. When you call a measure inside an iterator, it performs a context transition that converts the row context inside FILTER to filter context for the measure. In each row inside the FILTER, there is only one date, so it just selects that value each time, which means the FILTER condition is true for each row.

     

    Declaring it as a variable is a nice way of avoiding this problem since the variable is treated as a fixed value after it has been defined (i.e. it doesn't change depending on context later in the measure).

  • Hi BradAF  - every time CALCULATE or FILTER is called, the context gets swtiched. So your last CALCULATE(FILTER)) is called and evaluated for every row in your first FILTER. Not only would that make the calculation slower over larger data sets, but as you see you are getting incorrect results.

     

    Best practice is to use variables to both keep the code more readable, and to keep from a value getting re-calculated inside an iterator of an iterator.  Also, by putting calculations that involve min/max into variables, you can use the built in filter functionality of CALCULATE and not have to write explicit FILTER commands.

     

    LastWeekChange = 
        var __myDate = 
           SELECTEDVALUE(calculated_filtered[scanned], MAX(calculated_filtered[scanned]))
        var __LastWeek = 
            CALCULATE (
                      MAX(calculated_filtered[scanned]),
                      FILTER (                //You can also try removing this FILTER
                        calculated_filtered,  //and just having the < as a condition on CALCULATE
                        calculated_filtered[scanned] < __myDate
                             )
                       )
    return
        calculated_filtered[LastScanFindings]
            - CALCULATE (
                COUNT(calculated_filtered[task]),
                    calculated_filtered[scanned] = __LastWeek
              )

     

    Hope this helps

    David

      

9 Replies

  • dedelman_clng's avatar
    dedelman_clng
    Icon for Community Champion rankCommunity Champion

    Hi BradAF  - do all of the values for calculated_filtered[scanned], for a particular day, have the exact same datetime down to the millisecond? If not, that is why you are always getting max(calculated_filtered[scanned]), because SELECTEDVALUE() is returing more than one value even when you are selecting just a Date from the graph.

     

    Reference here: https://dax.guide/selectedvalue/ and look at "alternateresult"

     

    Hope this helps

    David

    • BradAF's avatar
      BradAF
      Icon for Helper I rankHelper I

      Hi David - thanks for the reply!

      Yes, sorry, the datetime is set once at the very beginning of the collection script so all 'scanned' values for a day are identical.

      If I create a card as shown in the pictures, the date does change if I select a different scan date in the graph. The three screenshots should show this:
      * Nothing selected - shows a count for ALL items but date is correct for last scan in card
      * Manually selecting the last scan date - shows a correct count for just the items from the last scan AND the date is correct in the card (this is how it should also look when nothing is selected)
      * an older scan date is selected - shows a correct count for just the items in that selected scan AND the date is correct in the card

      • dedelman_clng's avatar
        dedelman_clng
        Icon for Community Champion rankCommunity Champion

        Hi BradAF  - for reasons that someone smarter than I can explain, the context in which the SELECTEDVALUE measure is calculated changes when you create it as its own measure.  However, if you write your counting measure as this

         

        MEASURE calculated_filtered[LastScanFindings] =
            CALCULATE (
                COUNT ( calculated_filtered[taskid] ),
                FILTER (
                    calculated_filtered,
                    calculated_filtered[scanned] = 
                          SELECTEDVALUE(calculated_filtered[scanned], MAX(calculated_filtered[scanned]))
                )
            )

        or even this

         

        MEASURE calculated_filtered[LastScanFindings] =
        var __myDate = SELECTEDVALUE(calculated_filtered[scanned], MAX(calculated_filtered[scanned]))
        return
            CALCULATE (
                COUNT ( calculated_filtered[taskid] ),
                FILTER (
                    calculated_filtered,
                    calculated_filtered[scanned] = __myDate 
                )
            )

        You should get the results you are looking for, both with and without a date being selected.  DAX is funny that way in that splitting up the work into multiple measures does not always yield the right results.

         

        Last date (RecCnt2 mirrors the code in this post)

        Other Date

         

        No Date

         

        Hope this helps

        David