How to add totals row to excel power query? - excel

I have produced a table like the one below by using 'group' function in excel power query
score 1 score 2 score 3
A 6 25 50
B 8 30 20
C 15 15 30
D 20 0 10
I want to add a totals row (equivalent to "show totals for column" in a normal pivot table), so result would be like this
score 1 score 2 score 3
A 6 25 50
B 8 30 20
C 15 15 30
D 20 0 10
Total 49 70 110
Anyone knows if there is a simple way to do this? Thank you, RY

Another way:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
group = Table.Group(Source, {}, {{"letter", each "Total"},
{"score 1", each List.Sum([score 1])},
{"score 2", each List.Sum([score 2])},
{"score 3", each List.Sum([score 3])}}),
append = Table.Combine({Source, group})
in
append
Or:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
cols = Table.ColumnNames(Source),
group = Table.Group(Source, {}, List.Zip({cols, {each "Total"}&
List.Transform(List.Skip(cols),
(x)=>each List.Sum(Table.Column(_,x)))})),
append = Table.Combine({Source, group})
in
append
Or:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
group = Table.Group(Source, {}, List.TransformMany(Table.ColumnNames(Source),
(x)=>{each if x = "letter" then "Total"
else List.Sum(Table.Column(_,x))}, (x,y)=>{x,y})),
append = Table.Combine({Source, group})
in
append

I don't know why you would do this in PowerQuery rather than a pivottable but the only way I can think of is to duplicate the table, unpivot the columns and then repivot it using sum as an aggregation. Then you could append the table to your orginal query.
Your code would look something like for the table you want to create the totals in.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {}, "Attribute", "Value"),
#"Pivoted Column" = Table.Pivot(#"Unpivoted Columns", List.Distinct(#"Unpivoted Columns"[Attribute]), "Attribute", "Value", List.Sum)
in
#"Pivoted Column"
Note you may have to choose to aggregate by count but you can change the code to sum (On the #"Pivot Column" line change List.Count to List.Sum.
You will get an error for the A,B,C,D col - you can replace this with Total if you would like by using the Replace Errors function.

If you are wanting to add a total row to a Power Query that was loaded to a table. Just skip a row and add a total row. This seems to work for me. Just make sure you lock the first cell in your sum formulas. ex =SUM($C$2:C25)
Example 1
Example 2

Related

Hi everyone. Could anyone help me with this Power query problem

I have a table as indicated below where the Category column could have multiple categories each with its own scale which is shown in the Value column. I would like to create a new column that multiplies all the values where the item column does not equal 'scale' by the corresponding scale value that matches its category.
In the example below: if Category = A then multiply the value by 10
I've been stuck with this for a while and would truly appreciate any help.
Note - there are hundreds of categories and each one could have a different value. In the actual data, the category is a date and for each of those dates, there is a corresponding scale value that the remainder of the data that matches that date will need to be multiplied by.
Original Table
Item
Category
Value
Scale
A
10
Scale
B
5
Scale
C
2
Apples
A
100
Fruit
B
10
Car
C
15
Pear
A
20
Lemon
B
5
New Column added
Item
Category
Value
Calc_Val
Scale
A
10
null
Scale
B
5
null
Scale
C
2
null
Apples
A
100
1000
Fruit
B
10
50
Car
C
15
30
Pear
A
20
200
Lemon
B
5
25
Assuming your first table is named Table1, create a new table, Table2, via
let
Source = Table1,
#"Filtered Rows" = Table.SelectRows(Source, each ([Item] = "Scale"))
in
#"Filtered Rows"
Then create a third table, via
let
Source = Table.NestedJoin(
Table1,
{"Category"},
Table2,
{"Category"},
"Table2",
JoinKind.LeftOuter
),
#"Expanded Table2" = Table.ExpandTableColumn(Source, "Table2", {"Value"}, {"Table2.Value"}),
#"Added Custom" = Table.AddColumn(
#"Expanded Table2",
"Custom",
each if [Item] = "Scale" then null else [Value] * [Table2.Value]
)
in
#"Added Custom"
Have a lookup table with each category and the matching multiplication factor, then use the following formula:
=C2*INDEX(H$2:H$5,MATCH(A2,G$2:G$5,0))

Add Custom and Dynamic columns

I have two tables and am trying to figure out how to create custom code to add dynamic columns with custom names that are based off of row values in another table. I then need to use the values of rows in Table 2 to not only create the column names but also fill the new dynamic Columns with a value from another column in Table 2. Hopefully my pictures below help
Table 1 has varying amount of rows depending on what the user input.
Table 2 has varying amount of rows depending on how many values the user inputs.
Table 1 Before
Col1
Col2
Col 3
stuff 1
stuff 2
stuff 3
stuff 4
stuff 5
stuff 6
.
.
.
.
.
.
Table 2
Name
Values
Name1
100
Name2
500
.
.
NameX
Y
Table 1 After
Col1
Col2
Col 3
"Column" & Name1
"Column"& Name2
...
"Column"& NameX
stuff 1
stuff 2
stuff 3
100
500
...
Y
stuff 4
stuff 5
stuff 6
100
500
...
Y
.
.
.
100
500
...
Y
.
.
.
100
500
...
Y
The "Column" & Name1 meaning I want to concatenate Column with the values in the Name column in Table 2.
You can make this dynamic by not referring to the absolute column names, but rather using the Table.ColumnNames function to return those names.
I did assume that the column names in Table 2 are fixed. If not, that code can be changed.
Read the code comments and examine the Applied Steps window to better understand the methods used. There are examples of setting the data type, and also re-naming columns without referring to a hard-coded column name.
M Code
let
//read in the two tables and set the data types
Source1 = Excel.CurrentWorkbook(){[Name="Table_2"]}[Content],
Table2 =Table.TransformColumnTypes(Source1,
{{"Name", type text},{"Values", type any}}),
Source = Excel.CurrentWorkbook(){[Name="Table_1_Before"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,
List.Transform(Table.ColumnNames(Source), each {_, type text})),
//create the extra columns by
//Transpose Table2
// Use first row as headers
xpose = Table.Transpose(Table2),
#"Promoted Headers" = Table.PromoteHeaders(xpose, [PromoteAllScalars=true]),
#"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",
List.Transform(Table.ColumnNames(#"Promoted Headers"), each {_, type any})),
//rename the columns
renameNameCols = Table.RenameColumns(#"Changed Type1",
List.Zip(
{Table.ColumnNames(#"Changed Type1"),
List.Transform(Table.ColumnNames(#"Changed Type1"), each "Column " & _)})),
//Combine the tables
combine = Table.Combine({#"Changed Type",renameNameCols}),
//fill up the original table 2 columns and remove the blank Table 1 rows
#"Filled Up" = Table.FillUp(combine,Table.ColumnNames(renameNameCols)),
#"Filtered Rows" = Table.SelectRows(#"Filled Up", each ([Col1] <> null))
in
#"Filtered Rows"
Original Tables
Results
Note that I did NOT add logic to avoid prepending the ... with the word column, as shown in your desired output, but that is easily added if really needed
My version
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
custom = Table.FromColumns(Table.ToColumns(Source) &Table.ToColumns(Table2), List.Combine({Table.ColumnNames(Source),Table.ColumnNames(Table2)}) ),
#"Filled Down" = Table.FillDown(custom,Table.ColumnNames(Table2))
in #"Filled Down"

Find and append dates in multiple columns based on a date range

I'm looking for a way to find dates in multiple columns that fall within the past week and output those dates. Goal is to make it expandable through many more columns.
We will assume the week is 1-Sep through 7-Sep
EX:
Name
Box 1
Box 2
Bill
1-Sep-21
3-Sep-21
Bob
30-Aug-21
3-Sep-21
Jeff
31-Aug-21
4-Sep-21
Sam
31-Aug-21
29-Aug-21
Output
Name
Item Sold
Date
Bill
Box 1
1-Sep-21
Bill
Box 2
3-Sep-21
Bob
Box 2
3-Sep-21
Jeff
Box 2
4-Sep-21
My first thought would be to unpivot the date columns using Power Query and then apply a date filter to the result.
The coding in the advanced query editor would look something like:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Name"}, "Attribute", "Value"),
#"Filtered Rows" = Table.SelectRows(#"Unpivoted Other Columns", each [Value] >= #datetime(2021, 9, 1, 0, 0, 0) and [Value] <= #datetime(2021, 9, 7, 0, 0, 0))
in
#"Filtered Rows"
By using unpivot other columns, you'd be able to add as many date columns to the original table as you like.

Stacking multiple columns into one using an if statement - vba (excel)

I need to to stack multiple columns into one using an if statement as the example below
Original table looks like the following:
Type
ID
Name
State
X
Y
Pay
01
Joe
NY
-5
0
Pay
02
Ann
FL
-2
-4
Receive
03
Lee
TX
1
0
Pay
04
Ken
CA
0
-1
Receive
05
John
NY
3
2
I would like to have the columns Type, ID, X and Y to be copied from sheet1 to sheet2 using the following conditions:
if Type = "Pay" and X <> 0 then copy columns "Type", "ID" and X * (-1)
if Type = "Pay" and Y <> 0 then copy columns "Type", "ID" and Y * (-1)
if Type = "Receive" and X <> 0 then copy columns "Type", "ID" and X
if Type = "Receive" and Y <> 0 then copy columns "Type", "ID" and Y
I would Like the final result to look like the following:
Type
ID
#
Pay
01
5
X
Pay
02
2
X
Receive
03
1
X
Receive
05
3
X
Pay
02
4
Y
Pay
04
1
Y
Receive
05
2
Y
Please help me
Thanks Phil
As #ScottCraner implied, you can obtain your desired output using Power Query, available in Windows Excel 2010+ and Office 365 Excel
Select some cell in your original table
Data => Get&Transform => From Table/Range
When the PQ UI opens, navigate to Home => Advanced Editor
Make note of the Table Name in Line 2 of the code.
Replace the existing code with the M-Code below
Change the table name in line 2 of the pasted code to your "real" table name
Examine any comments, and also the Applied Steps window, to better understand the algorithm and steps
Note that your "conditions", when applied to the unPivot table, are the same as
Filter out the zero values
Multiple the "Pay" values by -1
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table33"]}[Content],
//delete unneeded columns
#"Removed Columns" = Table.RemoveColumns(Source,{"Name", "State"}),
//set data type
typeIt = Table.TransformColumnTypes(#"Removed Columns",{
{"Type", Text.Type},
{"ID", Text.Type},
{"X", Int64.Type},
{"Y", Int64.Type}
}),
//unPivot, then remove the rows with zeros's
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(typeIt, {"Type", "ID"}, "Attribute", "Value"),
#"Filtered Rows" = Table.SelectRows(#"Unpivoted Other Columns", each ([Value] <> 0)),
//add column where Pay amount are multiplied by -1
//remove unneeded Value column
//Sort and reorder the columns
#"Added Custom" = Table.AddColumn(#"Filtered Rows", "#", each if [Type]="Pay" then [Value] * -1 else [Value]),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom",{"Value"}),
#"Sorted Rows" = Table.Sort(#"Removed Columns1",{{"Attribute", Order.Ascending}, {"ID", Order.Ascending}}),
#"Reordered Columns" = Table.ReorderColumns(#"Sorted Rows",{"Type", "ID", "#", "Attribute"})
in
#"Reordered Columns"

Increment difference between cells

I'm trying to duplicate data in a sheet with increments of 12 between each cell from a sheet with 1 cell per row. Between the 12-incremented rows there's other data. This means I can't drag to extend the formula. Like this for customer numbers:
'SheetA'E3 = 'SheetB'Y2
'SheetA'E15 = 'SheetB'Y3
'SheetA'E27 = 'SheetB'Y4
..and so on. I've tried extending 12/24 cells at a time and copying but I can't make it work. Extending doesn't add +1 to one sheet, just +12/+24 to both. Doing this manually will take months. Can this be done without a VBA solution?
Any suggestions? I'm sorry if my terminology isn't on point here.
SheetA:
Try this (run as VBA code):
Sub test1()
For i01 = 0 To 100
Worksheets("SheetA").Cells(3 + 12 * i01, 5) = Worksheets("SheetB").Cells(2 + i01, 25)
Next i01
End Sub
Power Query, available in Windows Excel 2010+ and Office 365, can produce your SheetA given SheetB. Not sure about the effect of the variability you mention.
The query assumes that the correct parameters are listed as column headers in Sheet B. The column headers will get copied over as parameters to sheet A.
To use Power Query:
Select some cell in your Data Table
Data => Get&Transform => from Table/Range
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
//Read in the data
//Change table name in next line to be the "real" table name
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
//set data types based on first entry in the column
//will be independent of the column names
typeIt = Table.TransformColumnTypes(Source,
List.Transform(
Table.ColumnNames(Source), each
{_,Value.Type(Table.Column(Source,_){0})})
),
//UNpivot except for the c.number and c.name columns to create the Parameter and Level columns
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(typeIt, {"C. number", "C. name"}, "Parameter", "Level"),
//Group By C.Number
//Add the appropriate rows for each customer
//And a blank row to separate the customers
#"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"C. number"}, {
{"All", each _, type table [C. number=nullable number, C. name=nullable text, Parameter=text, Level=any]},
{"custLabel", (t)=> Table.InsertRows(t,0,{
[C. number = null, C. name=null,Parameter = null, Level = null],
[C. number = null, C. name=null, Parameter = "Customer Number", Level="Customer Name"],
[C. number = null, C. name=null,Parameter = t[C. number]{0}, Level = t[C. name]{0}],
[C. number = null, C. name=null,Parameter = "Parameter", Level = "Level"]
})}
}),
//Remove the unneeded columns and expand the remaining table
#"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"C. number", "All"}),
#"Expanded custLabel" = Table.ExpandTableColumn(#"Removed Columns", "custLabel", {"Parameter", "Level"}, {"Parameter", "Level"}),
//Remove the top blank row
//promote the new blank row to the Header location
#"Removed Top Rows" = Table.Skip(#"Expanded custLabel",1),
#"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
//data type set to text since it will look better on the report
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Customer Number", type text}, {"Customer Name", type text}})
in
#"Changed Type"```
Data
Results
[ Indirect with row() ]
Assuming 'SheetA'E3 column is the target and 'SheetB'Y2 is the source data.
In SheetA!E3 cell put:
=INDIRECT("SheetB!Y"&( ( (row()-3) / 12) + 2)
Press Enter
Then select SheetA!E3 cell, copy. Then paste in SheetA!E24. The formula will update itself.
Idea :
Find the relation between the target cell row number and the source cell row number. [ b > a : 3 > 2 , 15 > 3, 27 > 4 ] leads to a = (b-3)/12 + 2 . (The math is sort of like figuring out a straight line equation from 3 coordinate.) Then use INDIRECT() to combine the calculated row number with the column address.

Resources