Related
I am trying to arrange patient's journey based on first regimen then second regimen and so on.
However, after sorting data based on date:
I tried using IF formula as follow but it does not work correctly ( it worked for ID with three rows without having A5 in the formula):
=IF(AND(A2=A3,A3=A4,A4=A5,(C5-C4<=30),(C4-C3<=30),D3>(C4+30),D2>(C3+30)),B2&", "&B3&", "&B4&", "&B5,
IF(AND(A2=A3,A3=A4,A4=A5,(C4-C3<=30),D2>(C3+30)),B2&", "&B3&", "&B4,
IF(AND(A2=A3,A3=A4,A4=A5,(C4-C3<=30),D2<(C3+30)),B3&", "&B4,
IF(AND(A2=A3,A3=A4,A4=A5,(C4-C3>30),D2<(C3+30)), B3, "N")
I need to have similar results as follow:
Is there any way to have a formula helping to do so, or any other way to have similar results.
I had been working on Power Query code so I will present that first.
You can adapt the same algorithm to use in VBA, if you prefer. I would probably be using nested dictionaries and/or a class module to accomplish it effectively
To use Power Query
Select some cell in your Data Table
Data => Get&Transform => from Table/Range or from within sheet
When the PQ Editor opens: Home => Advanced Editor
Make note of the Table Name in Line 2
Paste the M Code below in place of what you see
Change the Table name in line 2 back to what was generated originally.
Read the comments and explore the Applied Steps to understand the algorithm
M Code
let
//Change next line to reflect your data source
Source = Excel.CurrentWorkbook(){[Name="Drugs"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"CATEGORY", type text},
{"F.DATE", type date}, {"L.DATE", type date}}),
//Group by ID, then run fnJourney custom function on each subtable to return results
#"Grouped Rows" = Table.Group(#"Changed Type", {"ID"}, {
{"Count", each fnJourney(_)}}),
//Expand results
#"Expanded Count" = Table.ExpandListColumn(#"Grouped Rows", "Count"),
#"Expanded Count1" = Table.ExpandRecordColumn(#"Expanded Count", "Count", {"Year", "Reg"}),
//Pivot on Year column with no aggregation
#"Year Headers" = List.Sort(List.Distinct(Table.TransformColumnTypes(#"Expanded Count1", {{"Year", type text}}, "en-US")[Year])),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expanded Count1", {{"Year", type text}}, "en-US"),
#"Year Headers", "Year", "Reg"),
#"Changed Type1" = Table.TransformColumnTypes(#"Pivoted Column", List.Transform(#"Year Headers", each {_, type text})),
//Join with original table
join = Table.NestedJoin(#"Changed Type", "ID", #"Changed Type1","ID", "Joined", JoinKind.LeftOuter),
//add shifted ID column to decide if the joined table should be retained or deleted
#"Shifted ID" = Table.FromColumns(Table.ToColumns(join) & {{null} & List.RemoveLastN(join[ID])},
type table[ID=Int64.Type, CATEGORY=text, F.DATE=date, L.DATE=date, joined=table, shiftedID=Int64.Type]),
#"Added Custom" = Table.AddColumn(#"Shifted ID", "Custom", each if [shiftedID] <> [ID] then [joined] else null, type nullable table),
//Remove shifted and Joined columns
//Then expand the tables in the Custom Column
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"joined", "shiftedID"}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Columns", "Custom", #"Year Headers"),
#"Changed Type2" = Table.TransformColumnTypes(#"Expanded Custom", List.Transform(#"Year Headers", each {_, type text}))
in
#"Changed Type2"
Custom Function CodeCreate new Blank query and paste code below
//Rename this query fnJourney
(tbl as table) =>
let
//Source = Drugs,
Source = tbl,
Years = {List.Min(List.Transform(Source[F.DATE], each Date.Year(_)))..
List.Max(List.Transform(Source[L.DATE], each Date.Year(_)))},
inJourney = List.Generate(
()=>[yr=Years{0},
reg=Text.Combine(Table.SelectRows(Source,
each Years{0} >= Date.Year([F.DATE])
and Years{0} <= Date.Year([L.DATE]))[CATEGORY],", "),
idx=0],
each [idx] < List.Count(Years),
each [yr=Years{[idx]+1},
reg=Text.Combine(Table.SelectRows(Source,
(r)=>Years{[idx]+1} >= Date.Year(r[F.DATE])
and Years{[idx]+1} <= Date.Year(r[L.DATE]))[CATEGORY],", "),
idx=[idx]+1],
each Record.FromList({[yr], [reg]},{"Year","Reg"})
)
in
inJourney
Before
After
I have an Excel table with data organized such that each row is a sample and each column has a different property of that sample. However, I need to reorganize it so that it works with GraphPad Prism.
Currently the data is organized like this:
Sample ID
Exposure Level
Drug
Score 1
…
Score 22
101
1
A
0.675815
0.17351
102
1
B
0.276413
0.677079
103
2
A
0.914725
0.387529
104
3
A
0.504221
0.135295
105
3
B
0.963684
0.710081
106
2
B
0.964099
0.146872
And I want to make a box and whisker plot showing the score of each exposure level, like this:
I need to do this including all the samples and then again for just drug A and just drug B.
However, in order to do that in Prism, to my knowledge, each combination of variables you want needs to have in own column, like this:
Score 1 Exposure 1
Score 1 Exposure 2
Score 1 Exposure 3
Score 1 Exposure 1 (Just Drug A)
Score 1 Exposure 2 (Just Drug A)
Score 1 Exposure 3 (Just Drug A)
etc.
0.675815
0.914725
0.504221
0.675815
0.914725
0.504221
0.276413
0.964099
0.963684
This would be easy enough to do manually if there were just one score column, but there are twenty-two, so I'd rather not. Is there some automated way I can reorganize the data table like this?
To create a Box & Whiskers graph similar to what you show,
merely use the Exposure Level for the x-axis and the Score 1 column for the y-axis
To create a table similar to the results you show, you can use Power Query.
I created it as a single table, with each row representing a drug. You can then filter it by drug for your drug specific results.
The MCode is commented so by reading the comments, and also looking at the Applied Steps window, I hope I was clear in what was going on.
Most of the MCode is generated from the UI, but, especially, the colNames and ExpandTableColumns steps near the end are manually entered. Otherwise the number of columns in the expansion would not be flexible.
MCode
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//Won't need ID column so get rid of it
#"Removed Columns2" = Table.RemoveColumns(Source,{"Sample ID"}),
//Unpivot the Score columns to put them in a single column
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Removed Columns2", {"Exposure Level", "Drug"}, "Attribute", "Value"),
//sort by Score, Attribute, Drug so the results will be properly ordered
#"Sorted Rows" = Table.Sort(#"Unpivoted Columns",{{"Attribute", Order.Ascending}, {"Exposure Level", Order.Ascending}, {"Drug", Order.Ascending}}),
//Create what will become a two line header column
// and remove the originals
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "Headers", each "Exposure " & Text.From([Exposure Level]) & "#(lf)" & [Attribute]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Exposure Level", "Attribute"}),
//Move headers to first column
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"Headers", "Drug", "Value"}),
//Group by Drug
#"Grouped Rows" = Table.Group(#"Reordered Columns", {"Drug"}, {{"Grouped", each _, type table [Headers=text, Drug=text, Value=number]}}),
//Add an Index column
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "Index", 0, 1, Int64.Type),
/*From each grouped table, remove Drug Column
and remove Header column EXCEPT fromk the first table
then Transpose each grouped table*/
#"Added Custom1" = Table.AddColumn(#"Added Index", "Custom", each
Table.Transpose(
if [Index] = 0 then
Table.RemoveColumns([Grouped],"Drug")
else
Table.RemoveColumns([Grouped],{"Headers","Drug"}))),
//Remove no longer needed Grouped and Index columns
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom1",{"Grouped", "Index"}),
//Expand the table columns, promote headers, and rename the drug column to get final results
colNames = Table.ColumnNames(#"Removed Columns1"[Custom]{0}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Columns1", "Custom", colNames),
#"Promoted Headers" = Table.PromoteHeaders(#"Expanded Custom", [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"A", type text}, {"Exposure 1#(lf)Score 1", type number}, {"Exposure 2#(lf)Score 1", type number}, {"Exposure 3#(lf)Score 1", type number}, {"Exposure 1#(lf)Score 22", type number}, {"Exposure 2#(lf)Score 22", type number}, {"Exposure 3#(lf)Score 22", type number}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type",{{"A", "Drug"}})
in
#"Renamed Columns"
EDIT
#user3316549 commented below that he might have multiple entries for the same drug for the same Score/Exposure and wanted the results for each shown separately.
A Pivot table would be useful here, except a classic pivot table will only have a single entry for each intersection of Drug with Score/Exposure.
This problem is solved with a custom function for the pivot that adds an extra row when needed. The credits for that function are included and you can examine the link for a detailed explanation of the algorithm used for that part of the code.
The custom function is added as a blank query. You can name it what you choose and call it that way in your main code.
M Code
Main Query
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//Unpivot the Score columns to put them in a single column
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {"Sample ID","Exposure Level", "Drug"}, "Attribute", "Value"),
//sort by multiple columns so the results will be properly ordered to our liking
#"Sorted Rows" = Table.Sort(#"Unpivoted Columns",{{"Attribute", Order.Ascending}, {"Exposure Level", Order.Ascending}, {"Drug", Order.Ascending},{"Sample ID", Order.Ascending}}),
//Create what will become a two line header column
// and remove the originals
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "Headers", each [Attribute] & "#(lf)" & "Exposure " & Text.From([Exposure Level])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Sample ID","Exposure Level", "Attribute"}),
//custom pivot function for non-aggregation
pivotAll = fnPivotAll(#"Removed Columns","Headers","Value")
in
pivotAll
M Code
Custom Function named fnPivotAll
//credit: Cam Wallace https://www.dingbatdata.com/2018/03/08/non-aggregate-pivot-with-multiple-rows-in-powerquery/
(Source as table,
ColToPivot as text,
ColForValues as text)=>
let
PivotColNames = List.Buffer(List.Distinct(Table.Column(Source,ColToPivot))),
#"Pivoted Column" = Table.Pivot(Source, PivotColNames, ColToPivot, ColForValues, each _),
TableFromRecordOfLists = (rec as record, fieldnames as list) =>
let
PartialRecord = Record.SelectFields(rec,fieldnames),
RecordToList = Record.ToList(PartialRecord),
Table = Table.FromColumns(RecordToList,fieldnames)
in
Table,
#"Added Custom" = Table.AddColumn(#"Pivoted Column", "Values", each TableFromRecordOfLists(_,PivotColNames)),
#"Removed Other Columns" = Table.RemoveColumns(#"Added Custom",PivotColNames),
#"Expanded Values" = Table.ExpandTableColumn(#"Removed Other Columns", "Values", PivotColNames)
in
#"Expanded Values"
I have data in this form:
In PowerBI, I added another column where I keep only code combinations that consist of one single code. I did this with something like IF(LEN(Code > 1), "", Code). Result:
This enables me to create a slicer that contains only single codes. I also added a table that shows Codes.
Now, when I select codes in the slicer, I want the table to show these codes, plus the exact combination of it.
For example, when I select A and B, the table should show me A and B and A, B. I don't want it to show A, B, C although it contains A and B.
If I filter for A and B and C, however, I want it to show A and B and C and A, B, C - but not A, B.
How can I achieve that?
All entries in Codes are saved as strings.
You need a disconnected (not connected to the base table) table for your slicer. Now, if I consider your base table name is - your_table_name, you can create the new slicer table with this below code-
slicer =
SELECTCOLUMNS(
FILTER(
your_table_name_8,
LEN(your_table_name_8[codes]) = 1
),
"code",your_table_name_8[codes]
)
After creating the new slicer table, check in the model is there any auto relation detected between 2 tables or not. If you find any relation, just Remove the relation.
Now, create your slicer from the newly created table and create this below measure in your base table your_table_name-
show_or_hide =
VAR current_code = MIN(your_table_name_8[codes])
VAR comma_separated_list =
CALCULATE (
CONCATENATEX (
VALUES(slicer[code]),
slicer[code],
","
)
)
RETURN
IF(
current_code = comma_separated_list || (LEN(current_code) = 1 && CONTAINSSTRING(comma_separated_list,current_code)),
1,
0
)
lets see the outcome-
Finally, you can apply a visual level filter using the new measure show_or_hide and apply a filter so that value with True only shown in the visual.
Reorder Combination
Let we have this following table-
Now this following code from Advanced Query Editor will give the the expected output-
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WctRx0nFWitUBsZx1nJRiYwE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
#"Reordered Columns" = Table.ReorderColumns(#"Added Index",{"Index", "Column1"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Reordered Columns", "Column1", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Column1.1", "Column1.2", "Column1.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Column1.1", type text}, {"Column1.2", type text}, {"Column1.3", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Index"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "column_name", each "Column-" & [Value]),
#"Changed Type2" = Table.TransformColumnTypes(#"Added Custom",{{"column_name", type text}}),
#"Removed Columns" = Table.RemoveColumns(#"Changed Type2",{"Attribute"}),
#"Reordered Columns1" = Table.ReorderColumns(#"Removed Columns",{"Index", "column_name", "Value"}),
#"Sorted Rows" = Table.Sort(#"Reordered Columns1",{{"Index", Order.Ascending}, {"column_name", Order.Ascending}}),
#"Pivoted Column" = Table.Pivot(#"Sorted Rows", List.Distinct(#"Sorted Rows"[column_name]), "column_name", "Value", List.Min),
#"Merged Columns" = Table.CombineColumns(#"Pivoted Column",{"Column-A", "Column-B", "Column-C"},Combiner.CombineTextByDelimiter(",", QuoteStyle.None),"Merged")
in
#"Merged Columns"
Please check what applied in steps one by one for better understanding. Here is the output with ascending order in the combination-
Index column added for keep tracking the row from start to end. If you have already a similar column, you can use that column as well.
I am currently working on converting an excel table with >100 calculated columns into a DAX table with similar calculated columns.
Excel formula refers to the columns by their column coordinates, e.g. sum = A2+B2
whereas DAX refers the column name in the formula, e.g. sum = Principal +Interest
Now, when I am trying to convert excel version of sum=A2+B2, is there any clever way for me to find out A=Principal and B= Interest in the spreadsheet.
I am talking about a table which has >50 non calculated columns and >100 calculated columns to be converted to comparable DAX model. Every time I look into a formula for the calculated columns in excel,
e.g.
Interest = =IF(AND(AR7="Pending",OR(V7="Completed",V7="Approved", LEFT(V7,4)="OPEN")),IF(U7*1>0,U7*1,N7)/VLOOKUP(F7,Tax!A:B,2,0),0)
I need to go back and forth in the table to find out what are the corresponding column for each coordinate in this.
Is there any clever way for me to find out what column names correspond to which column coordinate in the above formula, for example AR=Status, V=Application, U=Amount.....
Thank you in advance.
Thanks everyone. I think I managed to solve it using Power query. The following generates a table for an excel table with columns from A-ZZ and their corresponding coordinates.
Table Name - Query1
let
Source = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"},
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Added Custom" = Table.AddColumn(#"Converted to Table", "Custom", each {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom", "Custom"),
#"Inserted Merged Column" = Table.AddColumn(#"Expanded Custom", "Merged", each Text.Combine({[Column1], [Custom]}, ""), type text),
#"Removed Columns" = Table.RemoveColumns(#"Inserted Merged Column",{"Column1", "Custom"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Merged", "Column1"}}),
Custom1 = #"Converted to Table"&#"Renamed Columns",
#"Added Index" = Table.AddIndexColumn(Custom1, "Index", 1, 1) in
#"Added Index"
Now if I have a table like following, I run COLUMN syntax on my data source columns which produces the column number and I can use the previous PQWRY table to this to get the names
then
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WUtLBQLE60UoupcnZCkCOe35+cSqQds4vB3EDMtNT8/OADI/8ouJUqAiIcs7ITM5OzQPrNQTyjYDYGIhNgNgUiM2A2FwpNhYA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t, Column5 = _t, Column6 = _t, Column7 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}, {"Column7", type text}}),
#"Removed Top Rows" = Table.Skip(#"Changed Type",1),
#"Transposed Table" = Table.Transpose(#"Removed Top Rows"),
#"Changed Type1" = Table.TransformColumnTypes(#"Transposed Table",{{"Column2", Int64.Type}}),
#"Merged Queries" = Table.NestedJoin(#"Changed Type1", {"Column2"}, Query1, {"Index"}, "Query1", JoinKind.LeftOuter),
#"Expanded Query1" = Table.ExpandTableColumn(#"Merged Queries", "Query1", {"Column1"}, {"Column1.1"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Query1",{"Column2"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Column1.1", "Alphabetical_Coordinate"}}) in
#"Renamed Columns"
which gives me this
You can use VBA and the precedents member of the range object to get this. It will work for everything on the current sheet. I was not able to pick up the Tax!A:B and didn't have time to look further. Although, slightly incomplete, I at least wanted to provide this answer as a very good start
Sub formulaByField()
Dim formula As String
formula = Selection.formula
Debug.Print formula
Dim p As Range
For Each p In Selection.Precedents
'Debug.Print p.Address(False, False)
'Debug.Print Selection.Parent.Cells(1, p.Column).Value
formula = Replace(formula, p.Address(False, False), Selection.Parent.Cells(1, p.Column).Value)
Next
Debug.Print formula
End Sub
Code based on this setup:
Output
=IF(AND(A7="Pending",OR(B7="Completed",C7="Approved", LEFT(C7,4)="OPEN")),IF(D7*1>0,U7*1,E7)/VLOOKUP(F7,Tax!A:B,2,0),0)
=IF(AND(Duck="Pending",OR(Goose="Completed",Cow="Approved", LEFT(Cow,4)="OPEN")),IF(Pigeon*1>0,*1,Horse)/VLOOKUP(Pig,Tax!A:B,2,0),0)
Given the following time series of cashflow, how can I aggreate them into a cumulative time series of cashflow in Excel, ideally by using array formula only and without VBA macro?
Specifically, I was given this time series of cashflow for each transaction:
Given the inputs (in column F) for the number of transactions in each period, I would like to be able to calculate the aggregated time series of total cashflow (in column G, highlighted in yellow), ideally by using array formula only and without VBA macro?
Note: Column H to J are for illustrations only to show how column G should be calculated, I don't want to have them in my final spreadsheet.
Thank you very much for your help!
I believe you can do it by formula - most easily by reversing the cash flows and multiplying by the current and previous 5 transactions:
=SUMPRODUCT(INDEX(F:F,MAX(ROW()-5,3)):F16*INDEX(C:C,MAX(11-ROW(),3)):$C$8)
in G3.
This is an ordinary non-array formula.
OK Put this array formula in G3:
=IFERROR(SUMPRODUCT(INDEX($B$2:$B$7,N(IF({1},MODE.MULT(IF(INDEX(F:F,MAX(ROW()-5,3)):F3>0,(ROW()-ROW(INDEX(F:F,MAX(ROW()-5,3)):F3)+1)*{1,1}))))),INDEX(INDEX(F:F,MAX(ROW()-5,3)):F3,N(IF({1},MODE.MULT(IF(INDEX(F:F,MAX(ROW()-5,3)):F3>0,(ROW(INDEX(F:F,MAX(ROW()-5,3)):F3)-MIN(ROW(INDEX(F:F,MAX(ROW()-5,3)):F3))+1)*{1,1})))))),0)
Being an array formula it must be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode. Then copy down.
Once Microsoft relaeases FILTER and SEQUENCE it can be shortened:
=IFERROR(SUMPRODUCT(INDEX($B$2:$B$7,FILTER(SEQUENCE(ROW()-MAX(ROW()-5,3)+1,,ROW()-MAX(ROW()-5,3)+1,-1),INDEX(F:F,MAX(ROW()-5,3)):F3>0)),FILTER(INDEX(F:F,MAX(ROW()-5,3)):F3,INDEX(F:F,MAX(ROW()-5,3)):F3>0)),0)
This can also be done in Power Query.
Please refer to this article to find out how to use Power Query on your version of Excel. It is available in Excel 2010 Professional Plus and later versions. My demonstration is using Excel 2016.
Steps are:
Load both tables being the time series of cash-flow and your 2-column output table to the power query editor, then you should have:
For the first table, merged the Period column with Cashflow column with semicolon ; as the delimiter;
Transpose the column/table, then merge the columns with comma , as the delimiter;
Add a custom column use this formula ="Connector" which will fill the column with the word Connector, then you should have:
For the second table, also add a custom column use the same formula ="Connector" which will fill the column with the word Connector;
Merge the second table with the first table using the Custom column as the connection, then expand the new column to show the Merged column from the first table, then you should have:
Remove the Custom column, then split the Merged column by delimiter comma , and put the results into Rows;
Split the Merged column again by delimiter semicolon ; to separate the Period and Cashflow from the first table;
Add a custom column to calculate the New Period being =[Period]+[Merged.1];
Add another custom column to calculate the Cashflow being =[#"# Tran"]*[Merged.2], then you should have something like the following:
Group/sum the Cashflow column by New Period.
Once done you can Close & Load the result to a new worksheet (by default). If you want to show the # Trans column in the final output, you can make a duplicate of your second table before making any changes, and then merge it with the final output table by the Period column to show the corresponding number of transactions.
Here are the power query M codes for the first table:
let
Source = Excel.CurrentWorkbook(){[Name="Tbl_CFS"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Period", Int64.Type}, {"Cashflow", Int64.Type}}),
#"Merged Columns1" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"Period", type text}, {"Cashflow", type text}}, "en-AU"),{"Period", "Cashflow"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged"),
#"Transposed Table" = Table.Transpose(#"Merged Columns1"),
#"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Transposed Table", {{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}}, "en-AU"),{"Column1", "Column2", "Column3", "Column4", "Column5", "Column6"},Combiner.CombineTextByDelimiter(",", QuoteStyle.None),"Merged"),
#"Added Custom" = Table.AddColumn(#"Merged Columns", "Custom", each "Connector")
in
#"Added Custom"
And here are the codes for the second table:
let
Source = Excel.CurrentWorkbook(){[Name="Tbl_Total"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Period", Int64.Type}, {"# Tran", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each "Connector"),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Custom"}, Tbl_CFS, {"Custom"}, "Tbl_CFS", JoinKind.LeftOuter),
#"Expanded Tbl_CFS" = Table.ExpandTableColumn(#"Merged Queries", "Tbl_CFS", {"Merged"}, {"Merged"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Tbl_CFS",{"Custom"}),
#"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Removed Columns", {{"Merged", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Merged"),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Merged", type text}}),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "Merged", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Merged.1", "Merged.2"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Merged.1", Int64.Type}, {"Merged.2", Int64.Type}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type2", "New Period", each [Period]+[Merged.1]),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Cashflow", each [#"# Tran"]*[Merged.2]),
#"Grouped Rows" = Table.Group(#"Added Custom2", {"New Period"}, {{"Sum", each List.Sum([Cashflow]), type number}})
in
#"Grouped Rows"
All steps are using built-in functions so should be straight forward and easy to execute. Let me know if there is any question. Cheers :)