Forum Discussion

o0llied2's avatar
o0llied2
Frequent Visitor
8 months ago
Solved

Determining best or worst project

Dear Power BI community,

 

First of all i want to wish you all the best in 2026 and thank you for possibility attempting to help resolve my issue.

 

For a dashboard, i am trying to determine the best and worst project in a selected period. The dashboard shows various other data and has everything displayed twice, once to shown on a week level and once on a year level.

The determination of the best / worst project is done with the following dax formula:

Beste Project Nummer = 
VAR SelectedDates = 
    VALUES ( Datum[Datum] ) 
    
VAR Projects = 
    FILTER( 
            SUMMARIZE( 
                Opdracht, 
                Opdracht[DimOpdrachtId], 
                Opdracht[Projectnummer], 
                Opdracht[Korte tekst], 
                Opdracht[Opleveringsdatum], 
                "BrutomargePct", 
                CALCULATE( 
                    [Brutomarge %], 
                    TREATAS( 
                        SelectedDates, Opdracht[Opleveringsdatum] ), 
                        USERELATIONSHIP(Opdracht[Opleveringsdatum], Datum[Datum]) 
                ), 
                "Omzet", 
                CALCULATE( 
                    SUM(Opbrengsten[zBedrag]), 
                    TREATAS( SelectedDates, Opdracht[Opleveringsdatum] 
                    ), 
                    USERELATIONSHIP(Opdracht[Opleveringsdatum], Datum[Datum]) 
                ) 
            ), 
        NOT ISBLANK ( Opdracht[Opleveringsdatum] ) 
        && [Omzet] >= 1000 -- later finetunen 
    ) 
VAR Result =
    MAXX( TOPN(1, Projects, [BrutomargePct], DESC), Opdracht[Projectnummer] )

RETURN
    IF ( ISBLANK ( Result ), "Geen afgesloten projecten", Result )

*determination of worst project is the same but uses ASC instead of DESC in the Result Variable.

 

In this measure, we determine the best project within the selecteddates (according to date filter in the page using the date table) by calculating the gross margin (brutomargePct) in percentage. This comes from the measure [Brutomarge %] which simply divides two other measures, [Brutomarge] (gross margin) and [Project omzet] (project revenue):

Brutomarge % = 
DIVIDE(
    [Brutomarge],
    [Project Omzet]
)
Brutomarge = 
CALCULATE(
    SUM ( Opbrengsten[zBedrag] ) - SUM ( Kosten[zBedrag] )
)
Project Omzet = 
CALCULATE(
    SUM ( Opbrengsten[zBedrag] )
)

 

The problem i am facing is as follows:

To determine which projects to use in this summary of projects, the project should be ended within the selected week or year. The project end date comes from Opdracht[Opleveringsdatum]. However, on the dashboard the user filters using the date table (Datum[Datum]). The Date table and Opdracht table have a active relationship, but this is connected to another column and can not have a active relationship to the 'Opleveringsdatum' column because it would break many other things.

 

When i test in a test dashboarding and filter directly with the 'Opleveringsdatum' instead of using the Date table in the slicer, the result and calculations are correct. However when i move it to the live dashboard where it filters using the date table, none of the values are correct anymore. The Project Revenue, The Gross Margin and Gross Margin % are all correct, causing a incorrectly chosing best/worst project. It does mostly display the correct projects however, so almost always are the actual project numbers correct in both cases.

 

I tried solving this using the USERELATIONSHIP or TREATAS within the measures, but none of this has worked.

I am very curious to hear your thoughts!

 

Thanks again,

 

Olivier

  • The issue was not the ranking logic itself, but how the data was being filtered and grouped.

    1. We removed DimProjectId from the calculation
      Even though it is the technical key, all reporting is done on Projectnummer.
      Including DimProjectId caused the calculation to run at a lower grain, which resulted in the wrong project being selected.
      Once we removed it, the correct project was ranked as best/worst.

    2. We fixed the date filtering in the margin measures
      The active calendar relationship interfered with filtering by Opdracht[Opleveringsdatum].
      We solved this by clearing the calendar filter and explicitly applying the date filter to Opleveringsdatum.

    After these changes, the correct best and worst projects are selected, and the result is consistent across weeks and years.

10 Replies

  • o0llied2's avatar
    o0llied2
    Frequent Visitor

    The issue was not the ranking logic itself, but how the data was being filtered and grouped.

    1. We removed DimProjectId from the calculation
      Even though it is the technical key, all reporting is done on Projectnummer.
      Including DimProjectId caused the calculation to run at a lower grain, which resulted in the wrong project being selected.
      Once we removed it, the correct project was ranked as best/worst.

    2. We fixed the date filtering in the margin measures
      The active calendar relationship interfered with filtering by Opdracht[Opleveringsdatum].
      We solved this by clearing the calendar filter and explicitly applying the date filter to Opleveringsdatum.

    After these changes, the correct best and worst projects are selected, and the result is consistent across weeks and years.

    • Anonymous's avatar
      Anonymous
      Not applicable

      Hi o0llied2 ,

      We really appreciate your efforts and for letting us know the update on the issue. Glad to know the issue has been resolved

      Please continue using fabric community forum for your further assistance.

      Thank you

  • - define a numerical calculation for the values behind "best" and "worst"

    - calculate that value for each project

    - find the maximum and minimum value

    - identify the projects that match one of the two values  (note there can be multiple projects!)

     

    Please provide sample data that covers your issue or question completely, in a usable format (not as a screenshot).
    Do not include sensitive information. Do not include anything that is unrelated to the issue or question.
    Please show the expected outcome based on the sample data you provided.

    Need help uploading data? https://community.fabric.microsoft.com/t5/Community-Blog/How-to-provide-sample-data-in-the-Power-BI-Forum/ba-p/963216
    Want faster answers? https://community.fabric.microsoft.com/t5/Desktop/How-to-Get-Your-Question-Answered-Quickly/m-p/1447523

    • o0llied2's avatar
      o0llied2
      Frequent Visitor

      Hello lbendlin ,

       

      thank you for your reply. Please see below some sample data to get started.

      Below are the 4 tables you need with the minimum amount of information required to replicate the issue. I have taken 3 random weeks and 3 random projects within these weeks. The projects are found in the table 'Opdracht', their revenue is in table 'Opbrengsten' and their costs are in table 'Kosten'. Besides these three there should also be a seperate Date table, it only needs all the dates in 2025 to work. The Data model is also shown in a screenshot below. 

       

      The information in these tables is also enough to copy paste the DAX formulas shared before. 

      To recreate the issue, simply create a new page and add a table with the following data:

      'Opdracht'[Projectnummer] - 'Opdracht'[Opleveringsdatum] - [Project omzet] - [Brutomarge] - [Brutomarge %] - 'Opdracht'[Korte tekst]

      Now add a slicer using 'Opdracht'[Opleveringsdatum] and filter on one of the three dates. A screenshot below with an example for you to check if the data is the same:

       This data is 100% correct.

       

      Now add a new page with the same table, but add a slicer using the Date column in the date table. Now select the same day, for example 15-12-2025 and you will see the results are vastly different. Same projects, but different numbers.

       

      This is exactly the problem i am trying to solve. Thanks again for taking the time for my issue...

       

      Data model:

       

      Table Opdracht:

      ProjectnummerOpleveringsdatumBoekdatumDimOpdrachtIdKorte Tekst
      25186115-12-202519-11-20251-OP251861.1Werkplaats alino, CVI Lelystad
      25225615-12-20258-12-20251-OP252256.1SAR - Coatingvloer Waalwijk
      25220015-12-202519-11-20251-OP252200.1Unit Eindhoven - opslag + serverruimte
      2517798-12-202526-9-20251-OP251779.1Marel Poultry BV Boxmeer - proefkeuken
      2521878-12-202517-11-20251-OP252187.1Alexander poort Capelle a/d IJssel
      2508698-12-202523-10-20251-OP250869.1Sporthal Grote Beek Eindhoven
      24191416-6-20256-6-20251-OP241914.1VVE Bellevue buitentrap
      24222116-6-202526-5-20251-OP242221.1StayOkey Hostel Eindhoven
      23062416-6-202528-5-20251-OP230624.1Kamp Coating, Vianen

       

      Table Opbrengsten:

      zBedragDimOpdrachtIdBoekdatum
      16081-OP251861.115-12-2025
      201,91-OP251861.115-12-2025
      5201-OP251861.115-12-2025
      01-OP252256.115-12-2025
      01-OP252256.115-12-2025
      19251-OP252256.115-12-2025
      01-OP252200.115-12-2025
      21001-OP252200.115-12-2025
      4434,661-OP251779.18-12-2025
      1383,471-OP251779.18-12-2025
      9,61-OP251779.18-12-2025
      27701-OP251779.18-12-2025
      47941-OP252187.18-12-2025
      141001-OP252187.126-11-2025
      118441-OP252187.11-12-2025
      2829,51-OP252187.18-12-2025
      4202,731-OP250869.18-12-2025
      152,081-OP250869.18-12-2025
      € 4.333,001-OP241914.119-6-2025
      € 10.224,931-OP242221.116-6-2025
      € 4.460,501-OP230624.116-6-2025

       

      Table kosten:

      DimOpdrachtIdBoekdatumzBedrag
      1-OP252256.112-12-2025 00:00569,72
      1-OP252256.111-12-2025 00:001263,35
      1-OP252256.115-12-2025 00:00-402,92
      1-OP252200.130-12-2025 00:00152,8
      1-OP252200.112-12-2025 00:0020
      1-OP252200.111-12-2025 00:0020
      1-OP252200.110-12-2025 00:0020
      1-OP252200.19-12-2025 00:0020
      1-OP252200.115-12-2025 00:001120
      1-OP252200.18-12-2025 00:00313,56
      1-OP252200.123-12-2025 00:00128,81
      1-OP251779.11-12-2025 00:00529,01
      1-OP251779.13-12-2025 00:00388,98
      1-OP251779.15-12-2025 00:00862,57
      1-OP251779.14-12-2025 00:00395,07
      1-OP251779.125-11-2025 00:002308,64
      1-OP251779.18-12-2025 00:00-1509,49
      1-OP252187.119-11-2025 00:0020
      1-OP252187.120-11-2025 00:001148,93
      1-OP252187.15-12-2025 00:0093,5
      1-OP252187.126-11-2025 00:001527,68
      1-OP252187.124-11-2025 00:00886,33
      1-OP252187.127-11-2025 00:001408,94
      1-OP252187.125-11-2025 00:003103,47
      1-OP252187.121-11-2025 00:004047,8
      1-OP252187.118-11-2025 00:00312,3
      1-OP252187.14-12-2025 00:000
      1-OP252187.117-11-2025 00:002706,9
      1-OP252187.13-12-2025 00:000
      1-OP252187.12-12-2025 00:00742,18
      1-OP252187.117-12-2025 00:00450
      1-OP252187.11-12-2025 00:002262,51
      1-OP252187.128-11-2025 00:00450
      1-OP252187.19-12-2025 00:002500
      1-OP252187.114-11-2025 00:002704,85
      1-OP252187.18-12-2025 00:00-1460,03
      1-OP252187.122-11-2025 00:00-386,2
      1-OP252187.123-12-2025 00:003250
      1-OP250869.15-12-2025 00:0020
      1-OP250869.112-11-2025 00:0079,82
      1-OP250869.12-12-2025 00:000
      1-OP250869.11-12-2025 00:00110,12
      1-OP250869.16-12-2025 00:000
      1-OP250869.14-12-2025 00:001850
      1-OP250869.18-12-2025 00:00280
      1-OP250869.110-11-2025 00:00471,15
      1-OP250869.11-10-2025 00:0023,74
      1-OP250869.117-11-2025 00:001008,85
      1-OP241914.110-6-2025 00:002057,49
      1-OP241914.111-6-2025 00:00-599,5
      1-OP241914.116-6-2025 00:00960
      1-OP241914.112-6-2025 00:00-632,72
      1-OP242221.129-5-2025 00:0040
      1-OP242221.130-5-2025 00:0020
      1-OP242221.12-6-2025 00:001629,52
      1-OP242221.13-6-2025 00:0010
      1-OP242221.131-5-2025 00:0051,36
      1-OP242221.11-6-2025 00:0043,8
      1-OP242221.19-6-2025 00:00360
      1-OP242221.127-5-2025 00:001499,91
      1-OP242221.128-5-2025 00:002075,9
      1-OP242221.110-6-2025 00:00-368,9
      1-OP242221.15-6-2025 00:00-379,72
      1-OP230624.130-5-2025 00:00931,67
      1-OP230624.15-6-2025 00:001852,32
      • Anonymous's avatar
        Anonymous
        Not applicable

        Hi o0llied2 ,

        Try using this DAX function 

        Beste Project Nummer2 = 
        VAR SelectedDates =
            VALUES ( Datum[Datum] )
        
        VAR Projects =
            FILTER (
                ADDCOLUMNS (
                    Opdracht,
                    "Omzet", [Project Omzet],
                    "BrutomargePct", [Brutomarge %]
                ),
                NOT ISBLANK ( Opdracht[Opleveringsdatum] )
                    && Opdracht[Opleveringsdatum] IN SelectedDates
                    && [Omzet] >= 1000
            )
        
        RETURN
        IF (
            ISEMPTY ( Projects ),
            "Geen afgesloten projecten",
            MAXX (
                TOPN ( 1, Projects, [BrutomargePct], DESC ),
                Opdracht[Projectnummer]
            )
        )

         

         

        I hope this information helps. Please do let us know if you have any further queries.
        Thank you

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi o0llied2 

    I wanted to check if you had the opportunity to review the information requested by lbendlin . Please feel free to contact us if you have any further questions.


    Thank you.

    • o0llied2's avatar
      o0llied2
      Frequent Visitor

      Hello,

       

      I received the message and am currently working on providing sample data, expect to come today!

      Thank you very much for checking up on this thread 😄

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

        o0llied2 , Better use the index function, which allows partition by and order by  

        example 
        calculate([Meausre], index(1, allselected(Table[Device], Table[Last Update Date]), orderby(Table[Last Update Date],desc),,partitionBy(Table[Device]) ) )

        Power BI Index: Top/Bottom Performer by name and valuehttps://youtu.be/HPhzzCwe10U