I have a query that returns a dynamic number of columns. I need to dynamically add the same amount of custom columns. I have successfully gotten this far. I'm stuck creating the formulas for the custom columns. This is what I have so far. (This is not the actual query, this is simplified)
Here is the Code:
Test = List.Accumulate(MyList, Source,
(state, current) => Table.AddColumn(
state, "A Temp" & Number.ToText(current), each [A1])
)
For now, I just added [A1] as a place holder for the formula. I need the formula to accumulate as follows:
A Temp1 = [A1] / [TOTAL]
A Temp2 = [A2] / [TOTAL]
A Temp3 = [A3] / [TOTAL]
Above is not actual code. Just what I need the formulas to do for each custom column.
Is this possible? I have tried everything I could think of. I'm using power query in excel BTW.
This isn't exactly what you asked for, but I think it will help.
Test = List.Accumulate(
List.Select(Table.ColumnNames(Source), each _ <> "TOTAL"),
Source,
(state, current) => Table.AddColumn(state,
"Temp " & current,
each Record.Field(_, current) / [TOTAL]))
It's not exactly what you asked for as it gives column names like Temp A1 instead of A Temp1.
Related
I never use DAX and I find it very complicated!
I read this https://www.daxpatterns.com/abc-classification/ but I find it complicated.
My dataset is like this https://1drv.ms/x/s!AvMy-Bzzx3mqgwmKSZm6wr_W4VXr?e=Jwwbji&nav=MTVfezAwMDAwMDAwLTAwMDEtMDAwMC0wMDAwLT...
I need to sum column Value if the Name and date are the sums after doing the ABC analysis. The problem is that I can't aggregate before in transform because I need the column Name Fatt!
It is not necessary for a dynamic ABC analysis. The value for each Name and Date is the same...
I appreciate every help! Also video tutorial or something can help me. Thanks!
'Aggregazione fatturato = SUMX(UNION(VALUES(Name),VALUES(Date)),SUM(Value)
Fatturato Cumulato =
VAR CurrentProductSales = 'Misure'[Aggregazione fatturato]
VAR BetterProducts =
FILTER (
Name,
'Misure'[Aggregazione fatturato] >= CurrentProductSales
)
VAR Result =
SUMX (
BetterProducts,
'Misure'[Aggregazione fatturato]
)
RETURN
Result
Cumulated Pct =
DIVIDE (
'Misure'[Fatturato Cumulato],
SUM ('Misure'[Aggregazione fatturato])
ERROR 'Misure'[Aggregazione fatturato] not found
Since two days I'm on a problem and I can't solve it so I come here to ask some help...
I have that bit of dax that basically take the path of a hierarchical table (integers) and take the string names of the 2 first in the path.
the names I use:
'HIERARCHY' the hierarchical table with names, id, path, nbrItems, string
mytable / addedcolumn1/2 the new table used to emulate the for loop
DisplayPath =
var __Path =PATH(ParentChild[id], ParentChild[parent_id])
var __P1 = PATHITEM(__Path,1) var __P2 = PATHITEM(__Path,2)
var l1 = LOOKUPVALUE(ParentChild[Place],ParentChild[id],VALUE(__P1))
var l2a = LOOKUPVALUE(ParentChild[Place],ParentChild[id],VALUE(__P2))
var l2 = if(ISBLANK(l2a), "", " -> " & l2a)
return CONCATENATE(l1,l2)
My problem is... I don't know the number of indexes in my path, can go from 0 to I guess 15...
I've tried some things but can't figure out a solution.
First I added a new column called nbrItems which calculate the number of items in the list of the path.
The two columns:
Then I added that bit of code that emulates a for loop depending on the number of items in the path list, and I'd like in it to
get name of parameters
concatenate them in one string that I can return and get
string =
var n = 'HIERARCHY'[nbrItems]
var mytable = GENERATESERIES(1, n)
var addedcolumn1 = ADDCOLUMNS(mytable, "nom", /* missing part: get name */)
var addedcolumn2 = ADDCOLUMNS(addedcolumn1, "string", /* missing part: concatenate previous concatenated and new name */)
var mymax = MAXX(addedcolumn2, [Value])
RETURN MAXX(FILTER(addedcolumn2, [Value] = mymax), [string])
Full table:
Thanks for your help in advance!
Ok, so after some research and a lot of try and error... I've came up to a nice and simple solution:
The original problem was that I had a hierarchical table ,but with all data in the same table.
like so
What I did was, adding a new "parent" column with this dax:
parent =
var a = 'HIERARCHY'[id_parent]
var b = CALCULATE(MIN('HIERARCHY'[libelle]), FILTER(ALL('HIERARCHY'), 'HIERARCHY'[id_h] = a))
RETURN b
This gets the parent name from the id_parent (ref. screen).
then I could just use the path function, not on the id's but on the names... like so:
path = PATH('HIERARCHY'[libelle], 'HIERARCHY'[parent])
It made the problem easy because I didn't need to replace the id's by there names after this...
and finally to make it look nice, I used some substitution to remove the pipes:
formated_path = SUBSTITUTE('HIERARCHY'[path], "|", " -> ")
final result
I need to split my products into a total of 120 predefined price clusters/buckets. These clusters can overlap and look somewhat like that:
As I dont want to write down all of these strings manually: Is there a convenient way to do this in M or DAX directly using a bit of code?
Thanks in advance!
Dave
With m-Query you can create a function. Open the query editor. Richt click and create empty query. Create function (ignore warning) and call it : RowGenerator.
Open advanced editor and past the following code:
let
Bron = (base as number, start as number, end as number) => let
Bron = Table.FromList(List.Generate(() => start, each _ <= end, each _ + 1), Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Aangepaste kolom toegevoegd" = Table.AddColumn(Bron, "Aangepast", each Number.ToText(base) & " - " & Number.ToText([Column1]))
in
#"Aangepaste kolom toegevoegd"
in
Bron
This function creates a table where base is your first number and start, end the range.
Add another empty query, open the advanged editor and paste:
let
Bron = List.Generate(() => 0, each _ < 5, each _ + 1),
#"Geconverteerd naar tabel" = Table.FromList(Bron, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Aangeroepen aangepaste functie" = Table.AddColumn(#"Geconverteerd naar tabel", "test", each RowGenerator(_[Column1], _[Column1] + 1, 5)),
#"test uitgevouwen" = Table.ExpandTableColumn(#"Aangeroepen aangepaste functie", "test", {"Column1", "Aangepast"}, {"Column1.1", "Price Cluster"}),
#"Kolommen verwijderd" = Table.RemoveColumns(#"test uitgevouwen",{"Column1", "Column1.1"})
in
#"Kolommen verwijderd"
This creates first a list of 5 rows, then it calls the previous made function for each row and the last step is to expend the rows and remove the not needed columns.
Enjoy:
You can create this bucket by DAX (New Table):
Table = SELECTCOLUMNS(
GENERATE(SELECTCOLUMNS(GENERATESERIES(0,10,1),"FirstPart",[Value]), SELECTCOLUMNS(GENERATESERIES(0,10,1),"SecondPart",[Value]))
,"Bucket", [FirstPart] & " - " & [SecondPart]
)
Table = SELECTCOLUMNS(
GENERATE(SELECTCOLUMNS(GENERATESERIES(0,9,1),"FirstPart",[Value]), TOPN([FirstPart], SELECTCOLUMNS(GENERATESERIES(1,9,1),"SecondPart",[Value]), [SecondPart],ASC))
,"Bucket", [FirstPart] & " - " & [SecondPart]
)
I´ve been struggling with this:
My table shows 3 records but when expanding there are like 100 columns. I used this code:
#"Expanded Data" = Table.ExpandTableColumn(#"Source", "Document", List.Union(List.Transform(#"Source"[Document]), each Table.ColumnNames(_))),
but it's not working. How can I expand simultaneously all columns? Also, inside those columns there are even more, for example I expand the first time end then those new columns have more records inside.
What could I do? Thanks in advance!
Try this ExpandAllRecords function - it recursively expands every Record-type column:
https://gist.github.com/Mike-Honey/0a252edf66c3c486b69b
This should work for Records Columns.
let
ExpandIt = (TableToExpand as table, optional ColumnName as text) =>
let
ListAllColumns = Table.ColumnNames(TableToExpand),
ColumnsTotal = Table.ColumnCount(TableToExpand),
CurrentColumnIndex = if (ColumnName = null) then 0 else List.PositionOf(ListAllColumns, ColumnName),
CurrentColumnName = ListAllColumns{CurrentColumnIndex},
CurrentColumnContent = Table.Column(TableToExpand, CurrentColumnName),
IsExpandable = if List.IsEmpty(List.Distinct(List.Select(CurrentColumnContent, each _ is record))) then false else true,
FieldsToExpand = if IsExpandable then Record.FieldNames(List.First(List.Select(CurrentColumnContent, each _ is record))) else {},
ColumnNewNames = List.Transform(FieldsToExpand, each CurrentColumnName &"."& _),
ExpandedTable = if IsExpandable then Table.ExpandRecordColumn(TableToExpand, CurrentColumnName, FieldsToExpand, ColumnNewNames) else TableToExpand,
NextColumnIndex = CurrentColumnIndex+1,
NextColumnName = ListAllColumns{NextColumnIndex},
OutputTable = if NextColumnIndex > ColumnsTotal-1 then ExpandedTable else #fx_ExpandIt(ExpandedTable, NextColumnName)
in
OutputTable
in
ExpandIt
This basically takes Table to Transform as the main argument,and then one by one checks if the Column Record is expandable (if column has "records" in it, it will expand it, otherwise move to next column and checks it again).
Then it returns the Output table once everything is expanded.
This function is calling the function from inside for each iteration.
In Power BI Desktop i have a table from an excel file and i want to split a row based on a division between the value of a specific column and a default number.
In more details lets assume tha we have a table like this :
if the default value we want to devide column Amount is 50,then the desirable result would be something like that :
Do you have any idea how can i implement that in Power query editor or with dax?
Thanks
Tested this in Power Query for Excel, but hopefully should work for you in Power BI too. If you create a function like:
divisionToList = (numberToDivide as number, numberToDivideBy as number) as list =>
let
divisionResult = numberToDivide / numberToDivideBy,
isResultValid = (divisionResult >= 0) and (Number.Mod(divisionResult, 1) = 0),
errorIfInvalid = Error.Record("Cannot create a list with " & Text.From(divisionResult) & " items", Number.ToText(numberToDivide) & " / " & Number.ToText(numberToDivideBy) & " = " & Text.From(divisionResult), null),
listOrError = if isResultValid then List.Repeat({divisionResult}, divisionResult) else error errorIfInvalid
in listOrError,
It should divide two numbers and return a list of length d in which each element is d (d is the result of the division). This list can then, in the context of a table, be expanded into new rows.
There is some basic error handling in the function for cases where the division yields a problematic number (since you can't have a list with, for example, 5.1 elements or -1 elements). You can change/remove this handling if necessary.
I think this code below takes me from your first image to your second image -- and hopefully will give you some idea on how to go about achieving this.
let
mockData = Table.FromColumns({{200, 400}, {"A", "B"}}, type table [Amount = number, Description = text]),
defaultValue = 50, // Not sure what logic is required for arriving at this figure, so have simply assigned it.
divisionToList = (numberToDivide as number, numberToDivideBy as number) as list =>
let
divisionResult = numberToDivide / numberToDivideBy,
isResultValid = (divisionResult >= 0) and (Number.Mod(divisionResult, 1) = 0),
errorIfInvalid = Error.Record("Cannot create a list with " & Text.From(divisionResult) & " items", Number.ToText(numberToDivide) & " / " & Number.ToText(numberToDivideBy) & " = " & Text.From(divisionResult), null),
listOrError = if isResultValid then List.Repeat({divisionResult}, divisionResult) else error errorIfInvalid
in listOrError,
invokeFunction = Table.TransformColumns(mockData, {{"Amount", each divisionToList(_, defaultValue), type list}}),
expanded = Table.ExpandListColumn(invokeFunction, "Amount")
in
expanded