Forum Discussion
Converting Excel Formulas to DAX
- 10 years ago
Didn't have time to read the whole thread, but your WHB is impossible in DAX as you've got it defined. Luckily we can redefine it in a much more reasonable way (in terms of fields being accessed). Here are all the measures in clean DAX for you. It should be a good exercise in observing row vs filter context.
DAX isn't really the tool of choice for this, though. This sort of data munging should be done before the model is loaded. Unless you want these as measures, in which case, most of the ALL()s should be replaced with ALLSELECTED(), and the raw column references will have to be wrapped in SUM()s.
Steve = DIVIDE( SomeDamnTable[Fred], SomeDamnTable[Allen] ) // All row context Sysco = DIVIDE( SomeDamnTable[Fred] + SomeDamnTable[X] // All row context ,SomeDamnTable[Allen] ) Mary = IF( SomeDamnTable[Fred] >= SomeDamnTable[Allen] // All row context ,0 ,SomeDamnTable[Allen] - SomeDamnTable[Fred] ) Impact = CALCULATE( // Do this whole thing in a filter context made up of the entire table DIVIDE( SUM( SomeDamnTable[Fred] ) ,SUM( SomeDamnTable[Allen] ) ) ,ALL( SomeDamnTable ) ) - DIVIDE( CALCULATE( // this CALCULATE is in a filter context of the entire table SUM( SomeDamnTable[Fred] ) ,ALL( SomeDamnTable ) ) + SomeDamnTable[Mary] // This is row context ,CALCULATE( // this calculate is in the filter context of the whole table SUM( SomeDamnTable[Allen] ) ,ALL( SomeDamnTable ) ) ) Bob = IF( // all row context ( SomeDamnTable[Fred] + SomeDamnTable[X] ) >= SomeDamnTable[Allen] ,0 ,SomeDamnTable[Allen] - SomeDamnTable[Fred] - SomeDamnTable[X] ) WHB =
CALCULATE(
DIVIDE(
SUM( SomeDamnTable[Fred] )
,SUM( SomeDamnTable[Allen] )
)
,ALL( SomeDamnTable )
) - CALCULATE(
SUM( SomeDamnTable[Impact] )
,FILTER(
ALL( SomeDamnTable )
,SomeDamnTable[Index] <= EARLIER( SomeDamnTable[Index] )
)
)You should try to do this sort of thing before your data hits your model. Here's some Power Query to get you there. You can examine all this in the .pbix here.
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSAWMDMI7ViVYywhAxxhAxwRAxxRAxwxAxxxCxwBCxxBAxNIAKGSKEDFGFYgE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Product = _t, Allen = _t, Fred = _t, X = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Product", Int64.Type}, {"Allen", Int64.Type}, {"Fred", Int64.Type}, {"X", Int64.Type}}), Steve = Table.AddColumn(#"Changed Type", "Steve", each [Fred] / [Allen]), Sysco = Table.AddColumn(Steve, "Sysco", each ( [Fred] + [X] ) / [Allen]), Mary = Table.AddColumn(Sysco, "Mary", each if [Fred] >= [Allen] then 0 else [Allen] - [Fred]), Impact = Table.AddColumn(Mary, "Impact", each ( List.Sum( Mary[Fred] ) / List.Sum( Mary[Allen] ) ) - ( ( List.Sum( Mary[Fred] ) + [Mary] ) / List.Sum( Mary[Allen] ) )), Bob = Table.AddColumn(Impact, "Bob", each if ( [Fred] + [X] ) >= [Allen] then 0 else [Allen] - [Fred] - [X]), Index = Table.AddIndexColumn(Bob, "Index", 1, 1), WHB = Table.AddColumn(Index, "WHB", each let CurrentRow = [Index] ,Base = ( List.Sum( Index[Fred] ) / List.Sum( Index[Allen] ) ) ,SumImpact = List.Sum( Table.Column( Table.SelectRows( Index , each [Index] <= CurrentRow ) ,"Impact" ) ) ,WHB = Base - SumImpact in WHB), #"Removed Columns" = Table.RemoveColumns(WHB,{"Index"}), #"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Impact", Currency.Type}, {"WHB", type number}, {"Mary", Int64.Type}, {"Sysco", Int64.Type}, {"Steve", Int64.Type}, {"X", Int64.Type}, {"Fred", Int64.Type}, {"Allen", Int64.Type}, {"Product", Int64.Type}, {"Bob", Int64.Type}}) in #"Changed Type1"
Is it just a single table in your model or do you have links?
It is just a single table that I condensed down to show in this post. My data actually lives in Access and I created connection to this workbook so relationships are not an issue. I am simply trying to change the formulas into measures. I am getting pretty close but somewhere along the lines, I don't think it likes changing the end result into a percent data type from a whole number/decimal.
I broke out the individual formulas one by one and created measures. The individual measures work until I get to the final measure which subtracts a number that resulted from the divide function. Instead of getting -9.09%, I receive -900.00%. Also, I converted the result to a decimal to get around it but it gets -900.00. Multiplying the result by 100 getts -9.00 which is still .09 off.
Thanks
- Greg_Deckler10 years agoCommunity Champion
Honestly, this is pretty much impossible to troubleshoot without some kind of sample data to play with.
- GTR10 years agoHelper III
Here is the data
Product Allen Fred X Steve Sysco Mary Impact Bob WHB 1 1 0 0 0% 0% 1 -9.09% 1 27.27% 2 1 0 0 0% 0% 1 -9.09% 1 36.36% 3 1 0 0 0% 0% 1 -9.09% 1 45.45% 4 1 0 0 0% 0% 1 -9.09% 1 54.55% 5 1 0 0 0% 0% 1 -9.09% 1 63.64% 6 1 0 0 0% 0% 1 -9.09% 1 72.73% 7 1 0 0 0% 0% 1 -9.09% 1 81.82% 8 1 0 0 0% 0% 1 -9.09% 1 90.91% 9 1 0 0 0% 0% 1 -9.09% 1 100.00% 10 1 1 0 100% 100% 0 0.00% 0 100.00% 11 1 1 0 100% 100% 0 0.00% 0 100.00% Total 11.00 2 0 18.18% 18.18% 9.00 Here's the formulas I am trying to turn into measures in the data model:
The IMPACT and WHB are the two measures I am having troubles with. The measures for Steve, Sysco, Mary, and Bob are already done with no problem. WHB reflects on the IMPACT column being correct.
Let me know if you need any additional information. Keep in mind that this table has over 500,00 rows, I condensed it down for testing purposes.
Thanks
- itchyeyeballs10 years agoImpactful IndividualHow about generating a totals table on import then linking to the original table via a common products lookup table? Turns this into a granularity problem and there are plenty of examples for that out there.