Forum Discussion

J94's avatar
J94
Icon for Advocate II rankAdvocate II
1 month ago
Solved

Filter by Rank measure

Hi all,

 

I have a table in my report with Productline and MOdelNPIDesc and a measure Orders vs Forecast %. I only want to show the top 10 with the highest %. If I add the measure Top10 

Orders vs Forecast % TopN =
RANKX(
    ALLSELECTED(
        dim_product_attributes[ProductLine],
        dim_product_attributes[ModelNPIDesc]
    ),
    [Orders vs Forecast %],
    ,
    DESC,
    DENSE
)
 
or the measure TopN10equalTo1 
TopN10equalTo1 =
IF([Orders vs Forecast % TopN] <=10, 1, 0)
it works in the table; the results are correct. But if I want to filter in the filter pane for TopN <= 10 or TopN10equalTo1 = 1, I only see the top 3... What is going on?
 
The first screenshot shows the table without the ranking filters (but with some other necessary filters). The second table is with the RankX filter and the third one is with the TopN10equalTo10 filter. 
 
Maybe it has something to do with the blanks and I probably could solve it when I would make a calculated column where I combine Productline and ModelNPI into one column, but I prefer to prevent that. And I also want to know why it is not working. 



  • J94's avatar
    J94
    1 month ago

    Thank you danextian. This led me in the right direction. RemoveFilters was necessary for the measure. Because I already had a measure in the filter pane, the Ranking was like '7, 9, 10, 11, 13'. So it didn't start at 1 and sometimes it skipped rankings. Hence I had to make one small adjustment. This is the final working measure:

    Orders vs Forecast % TopN =
    VAR RankingTable =
        FILTER (
            CALCULATETABLE (
                ALLSELECTED (
                    'dim_product_attributes'[ProductLine],
                    'dim_product_attributes'[ModelNPIDesc]
                ),
                REMOVEFILTERS ( 'dim_product_attributes' )
            ),
            [Sales Forecast_Measure] > 50
        )
    RETURN
        RANKX (
            RankingTable,
            [Orders vs Forecast %],
            ,
            DESC,
            DENSE
        )


    As you can see, I added Filter and the [Sales Forecast_Measure] > 50 to the measure. Sales Forecast_Measure was already added in the filter pane, hence I needed to filter for it again in this measure (if I didn't include it, I had the same issue where I started with). Actually, this simplified measure is working for me as well:

    RANKX(
        FILTER(
            ALLSELECTED(
                dim_product_attributes[ProductLine],
                dim_product_attributes[ModelNPIDesc]
            ),
            [Sales Forecast_Measure] > 50
        ),
        [Orders vs Forecast %],
        ,
        DESC,
        DENSE
    )

     

7 Replies

  • Hi J94 
    Your ranking is evaluated based on the visible rows in your visual so when you visually filter it by a measure value, the rows being evaluated naturally change. Try this pattern

    Category and Model Rank by Sales 2 = 
    VAR RankingTable =
        CALCULATETABLE (
            ALLSELECTED (
                'Product'[Category],
                'Product'[Model]
            ),
            REMOVEFILTERS ( 'Product' )
        )
    RETURN
        RANKX (
            RankingTable,
            [Sales],
            ,
            DESC,
            DENSE
        )

    Notice that in the image below, the second table is filtered to show rows with sales less than 100K but Rank2 still says the same as the first table without a filter where   as Rank has changed values.

    Please see the attached pbix.

     

    • J94's avatar
      J94
      Icon for Advocate II rankAdvocate II

      Thank you danextian. This led me in the right direction. RemoveFilters was necessary for the measure. Because I already had a measure in the filter pane, the Ranking was like '7, 9, 10, 11, 13'. So it didn't start at 1 and sometimes it skipped rankings. Hence I had to make one small adjustment. This is the final working measure:

      Orders vs Forecast % TopN =
      VAR RankingTable =
          FILTER (
              CALCULATETABLE (
                  ALLSELECTED (
                      'dim_product_attributes'[ProductLine],
                      'dim_product_attributes'[ModelNPIDesc]
                  ),
                  REMOVEFILTERS ( 'dim_product_attributes' )
              ),
              [Sales Forecast_Measure] > 50
          )
      RETURN
          RANKX (
              RankingTable,
              [Orders vs Forecast %],
              ,
              DESC,
              DENSE
          )


      As you can see, I added Filter and the [Sales Forecast_Measure] > 50 to the measure. Sales Forecast_Measure was already added in the filter pane, hence I needed to filter for it again in this measure (if I didn't include it, I had the same issue where I started with). Actually, this simplified measure is working for me as well:

      RANKX(
          FILTER(
              ALLSELECTED(
                  dim_product_attributes[ProductLine],
                  dim_product_attributes[ModelNPIDesc]
              ),
              [Sales Forecast_Measure] > 50
          ),
          [Orders vs Forecast %],
          ,
          DESC,
          DENSE
      )

       

  • Hi User,

    The behavior you are seeing is usually related to how Power BI evaluates measure filters in the filter pane.

    Your RANKX measure is being calculated correctly inside the table visual because Power BI evaluates the ranking row by row. However, when you apply the measure as a visual filter, the filter context changes, and the ranking can be recalculated differently. This can cause only a subset of the expected Top 10 items to remain.

    A few things you can try:

    1. Create the ranking measure without changing the context too aggressively

    Try:

    Orders vs Forecast % Rank =
    RANKX(
        ALLSELECTED(dim_product_attributes),
        [Orders vs Forecast %],
        ,
        DESC,
        DENSE
    )

    Using the entire dimension table in ALLSELECTED can preserve the correct context better than specifying only two columns.

    2. Use the rank filter directly

    Instead of creating:

    TopN10equalTo1 =
    IF([Orders vs Forecast % Rank] <= 10, 1, 0)

    Add the rank measure directly to the visual filter:

    Orders vs Forecast % Rank is less than or equal to 10

    Then set the value after the visual is fully configured.

    3. Check for ties

    Because you are using:

    DENSE

    multiple products can receive the same rank. For example, if several products have the same percentage at rank 10, the result can include more than 10 rows. If you need exactly 10 rows, you may need a secondary sorting column.

    4. Validate blank values

    If [Orders vs Forecast %] returns BLANK() for some products, RANKX behavior can become unexpected. You can test with:

    Orders vs Forecast % Rank =
    IF(
        NOT ISBLANK([Orders vs Forecast %]),
        RANKX(
            ALLSELECTED(dim_product_attributes),
            [Orders vs Forecast %],
            ,
            DESC,
            DENSE
        )
    )

    Another approach is to use a Top N filter on the visual:

    • Select the ProductLine/ModelNPIDesc field

    • Filters pane → Filter type: Top N

    • Show items: Top 10

    • By value: [Orders vs Forecast %]

    This often performs better because Power BI handles the ranking internally.

    For more information:

    Could you also confirm:

    • Are ProductLine and ModelNPIDesc from the same dimension table?

    • Are there slicers affecting the visual (date, region, customer, etc.)?

    • Do you need exactly 10 rows, or should ties at rank 10 also be included?

    That will help determine the best ranking approach for your model.

     

     

    💡 Helpful? Give a Kudos 👍 — keep the community growing.

    Solved your issue? Mark this as the Accepted Solution ✔️

    Best regards,
    Prince Singh | Data Science & Microsoft Fabric Enthusiast

  • J94's avatar
    J94
    Icon for Advocate II rankAdvocate II

    Hi Prince0011 

    thanks for your suggestion. Unfortunately, it doesn't work. I did try the same calculation as your Orders vs Forecast % Rank before, but the ranking in the table isn't correct anymore (see screenshot). Maybe it has to do with the Orders vs Forecast % measure, where the RankX measure is based on:

     

    Orders vs Forecast % =
    VAR _orders = [QuantityOrder excl. IC]
    VAR _invoiced = SUM(fact_salesinvoices[QuantityInvoiced])
    VAR _forecast = Salesforecast_FTP[Sales Forecast_Measure]
     
    RETURN
    IF(
        NOT ISBLANK(_forecast),
        DIVIDE( COALESCE(_orders + _invoiced, 0), _forecast, 0 ),
        BLANK()
    )
    To be complete, here are the two other measures:
    QuantityOrder excl. IC =
    CALCULATE(
        SUM(fact_salesorderlines_open[QuantityOpenToInvoice]),
        dim_relation_master[IsInterCompanyDesc_edw] = "No"
    )
    Sales Forecast_Measure = //When there is no Forecast in the past, use SUM QuantityInvoiced 
    SUMX(
        VALUES(dim_date[YearMonthNumber_og]),
        VAR _forecast =
            CALCULATE(
                SUM(Salesforecast_FTP[Sales Forecast])
            )
        VAR _monthIndex =
            CALCULATE(
                MAX(dim_date[MonthIndex])
            )
        RETURN
            IF(
                _forecast = 0
                    || _monthIndex < 0,
                CALCULATE(
                    SUM(fact_salesinvoices[QuantityInvoiced])
                ),
                _forecast
            )
    )
     
  • The problem is likely the results returned by ALLSELECTED. When you include either of the measures in the visual then ALLSELECTED does what you expect it to, returning the values which are visible in the filter context after removing filters generated by the current visual. However, when the measure is only used as a filter, and is not included in the visual itself, the measure is calculated in a different filter context and the values returned by ALLSELECTED are not what you would expect.

    I think that the answer is to include the [Orders vs Forecast % TopN] measure in the visual but hide it. You can either temporarily add a visual calculation, hide the TopN measure and delete the visual calculation, or you could set the column width to 0 and turn word wrap off for that column.

    • J94's avatar
      J94
      Icon for Advocate II rankAdvocate II

      johnt75  I did add the measures in the visual. But when I want to filter on the measures for the top 10 in the filter pane, its iteration context or something changes. This prevents me to see the actual top 10

      • johnt75's avatar
        johnt75
        Icon for Super User rankSuper User

        How exactly are you applying the filter? I can see in your screenshot that the top visual doesn't have a filter on either Top 10 or TopN10EqualTo1.

        Can you use Performance Analyzer to get the query generated for the visual without any filters, and then get the query when you apply a filter to either measure. Please also include a screenshot showing the visual and the filters.