Forum Discussion

YO_CO's avatar
YO_CO
Frequent Visitor
1 year ago
Solved

Custom subtotals with sort order

Hi all,

I ask for your assistance in this issue:

tried to attach sample dataset but can't...

 

I have multiple sources, bringing in several tables of similar structure:

  1. Activity – these can vary. Some will be shared across the sources, some will only come from one source.
  2. Attribute – is the cost direct / indirect. Each activity has two lines in the data reflecting this.
  3. Costs columns – same number of columns for all source tables.

 

Simple dataset.

After a bit of transformation I append all the tables and get one Data table which is a Cartesian product of all activities and attributes with their relevant costs.

 

ActivityAttributeStaffSoftwareD&A
BIDirect543313
BIIndirect20021654
CFODirect2536
CFOIndirect3436
AccountingDirect4225443
AccountingIndirect139864
TPDirect764375
TPIndirect473
ESGDirect7565
ESGIndirect548743
BIDirect211413
BIIndirect20054654
CFODirect453421
CFOIndirect345673
16xDirect422515
16xIndirect133112
21yDirect334275
21yIndirect6544376

 

The stakeholders want a resulting report showing a single visual in the below format, with custom subtotals for attribute. These can be before or after the grand total row, whatever is easier (however totals and subtotals should be bold).

ActivityStaffSoftwareD&A%
16x5556273%
21y9848515117%
Accounting5512350716%
BI475122133445%
CFO115981368%
ESG61921086%
TP8050785%
Total93910262341 
Direct32222675630%
Indirect617800158570%

 

 

 

I managed this with custom table for the sub/total with sort and appending it to the values of "attributes":
Display Table =

UNION(
    ADDCOLUMNS(
        VALUES( 'Appended Table'[Activity] ),
        "Sort", 0
    ),
    'Total Display'
)
 

a staff measure would then look like this:

Sum of Staff =
SWITCH(
    SELECTEDVALUE( 'Display Table'[Activity] ),
    "Direct", CALCULATE( SUM( 'Appended Table'[Staff] ), 'Appended Table'[Attribute] = "Direct" ),
    "Indirect", CALCULATE( SUM( 'Appended Table'[Staff] ), 'Appended Table'[Attribute] = "Indirect" ),
    "Total", SUM( 'Appended Table'[Staff] ),
    --for all other categories
    CALCULATE(
        SUM( 'Appended Table'[Staff] ),
        'Appended Table'[Activity] = SELECTEDVALUE( 'Display Table'[Activity] )
    )
)
   

 

 

, my questions are:

  1. Is my solution scalable? Eventually I’ll have tens of millions of rows, not sure the implicit calculations are viable (and I absolutely hate working with calculation groups).
  2. My solution only works with a sort order for the subtotals and totals.
    If the users sort the end visual by any other value, the totals are getting lost on in the middle.
    How do I keep them at the bottom when sorting by value?
  3. As “Activity” is dynamic and can change between files, added or removed, is there a way to handle sorting order there as well somehow?

 

How would you approach this?
I think this is possible with Inforiver matrix, but no one is going to give me a budget for this per user 😞

Thanks!

  • Hi YO_CO  - Rather than using SWITCH, use a SUMX that adjusts behavior based on the current row label

     

    Sum of Staff =
    VAR CurrentRow = SELECTEDVALUE('Display Table'[DisplayActivity])
    RETURN
    SWITCH(
    TRUE(),
    CurrentRow = "Total", SUM('Appended Table'[Staff]),
    CurrentRow = "Direct", CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Attribute] = "Direct"),
    CurrentRow = "Indirect", CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Attribute] = "Indirect"),
    -- Regular activity row
    CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Activity] = CurrentRow)
    )

     

    coming to total positions,Power BI’s biggest visual limitation: it doesn’t keep totals “sticky” when you sort by a column like Staff. you can try with sort by column approach. 

     

    you can compute total once and divide as like below:

    Total_Staff = CALCULATE(SUM('Appended Table'[Staff]))

    % Staff =
    DIVIDE(
    [Sum of Staff],
    [Total_Staff]
    )

     

    I hope the above approach works in your scenerio

     

4 Replies

  • Hi YO_CO  - Rather than using SWITCH, use a SUMX that adjusts behavior based on the current row label

     

    Sum of Staff =
    VAR CurrentRow = SELECTEDVALUE('Display Table'[DisplayActivity])
    RETURN
    SWITCH(
    TRUE(),
    CurrentRow = "Total", SUM('Appended Table'[Staff]),
    CurrentRow = "Direct", CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Attribute] = "Direct"),
    CurrentRow = "Indirect", CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Attribute] = "Indirect"),
    -- Regular activity row
    CALCULATE(SUM('Appended Table'[Staff]), 'Appended Table'[Activity] = CurrentRow)
    )

     

    coming to total positions,Power BI’s biggest visual limitation: it doesn’t keep totals “sticky” when you sort by a column like Staff. you can try with sort by column approach. 

     

    you can compute total once and divide as like below:

    Total_Staff = CALCULATE(SUM('Appended Table'[Staff]))

    % Staff =
    DIVIDE(
    [Sum of Staff],
    [Total_Staff]
    )

     

    I hope the above approach works in your scenerio

     

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi YO_CO 

    May I ask if you have resolved this issue? If so, please mark the helpful reply and accept it as the solution. This will be helpful for other community members who have similar problems to solve it faster.

    Thank you.

     

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi YO_CO 
    I wanted to check if you had the opportunity to review the information provided by rajendraongole1 . Please feel free to contact us if you have any further questions. If his response has addressed your query, please accept it as a solution and give a 'Kudos' so other members can easily find it.
    Thank you.

  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi YO_CO 
    I hope this information is helpful. Please let me know if you have any further questions or if you'd like to discuss this further. If this answers your question, please Accept it as a solution and give it a 'Kudos' so others can find it easily.
    Thank you.