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

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.

Related

How to turn comma separated list into Venn Diagram Format in Power Query

My goal is to create a ven diagram out of database data. I am happy to achieve this in 2 ways
Using Flurish.com which requires me to solve this power query problem.
Being suggested other software that can automatically create Ven Diagrams
The database table looks like this:
Name
Shared Interests
Person 1
Camping, Road Trips, Acro, Firetwirling
Person 2
Camping
Person 3
Road Trips
Person 4
Road Trips
Person 5
Acro
Person 6
Firetwirling
Person 7
Camping, Road Trips
etc
Flurish.com requires me to get it in the format
Name
Value
Camping
3
Road Trips
4
Acro
2
Firetwirling
2
Camping-Road Trips
2
Camping-Acro
1
Camping-Firetwirling
1
Camping-Road Trips-Acro
1
Camping-Road Trips-Firetwirling
1
Camping-Road Trips-Firetwirling-Acro
1
... (etc with every possible combination separated by a -)
etc
How can this be achieved?
I have attempted to create a unique list of all 'Shared Interests' but I don't know how to add new rows of every unique combination separated by a dash -
I then don't know how to calculate the value column of these overlapping groups. I suspect using pivot functions are the way to go here but so far I have not had any luck.
In powerquery try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
// Combo algo adapted from from Bill Szysz 2017
process=(Items as list) as list =>
let AddIndex = Table.AddIndexColumn(Table.FromList(List.Sort(Items)), "Index", 0, 1),
ReverseIndeks = Table.AddIndexColumn(AddIndex, "RevIdx", Table.RowCount(AddIndex), -1),
Lists = Table.AddColumn(ReverseIndeks, "lists", each List.Repeat(List.Combine({List.Repeat({[Column1]}, Number.Power(2,[RevIdx]-1)),List.Repeat( {null}, Number.Power(2,[RevIdx]-1))}), Number.Power(2, [Index]))),
ResultTable = Table.FromColumns(Lists[lists]),
AllCombos = List.Sort(List.RemoveLastN(Table.AddColumn(ResultTable, "Custom", each Text.Combine(List.RemoveNulls(Record.ToList(_)),"-"))[Custom],1))
in AllCombos,
#"Added Custom" = Table.AddColumn(Source, "combos", each process(Text.Split([Shared Interests],", "))),
#"Expanded combos" = Table.ExpandListColumn(#"Added Custom", "combos"),
#"Grouped Rows" = Table.Group(#"Expanded combos", {"combos"}, {{"Count", each Table.RowCount(_), Int64.Type}})
in #"Grouped Rows"

IF condition met take value from row above.....Power Query

I'm new to this forum and I need your help in PowerQuery.
What I would like to do:
I have a list with expected stock changes for article. On the one hand it could be a inrease of the stock in case of incoming goods from an order which I made to my suppliers. On the other hand it could be a decrease in case of outgoing goods from a sales order. I would like to have a list which is writing the article code, the actual stock, the aamount of the decrease/increase of the change and the stock of the article after the change.
For example:
Row Column1 (A) Column2(B) Column3 (C) Column4 (D)
1 Article actual stock amount of change stock after change
2 A 5 -1 4
3 A 5 -2 2
4 A 5 -1 1
5 B 4 -1 3
The stock is always the same because the changes are expected and so for the future.
In Excel this would be a "easy"solution for me to calculate column4.
D2 = IF(A1=A2;D1+C2;B2+C2)
So I'm referencing to the value above the actual row in column4 if the arcicle is still the same. But how I have to do this in PowerQuery.
What I tried in PowerQuery? I added two index columns to the table:
Column1 (A) Column2(B) Column3 (C) Column4 (D) Index(colum5) Index.1(column6)
Article actual stock amount of change stock after change
A 5 -1 4 0 1
A 5 -2 2 1 2
A 5 -1 1 2 3
B 4 -1 3 3 4
I combined this two table by the index and added the artile again in this table.
I added a new conditional column called "Häufigkeit" where a "Doulbe" should be insert if article in column1 is equal to article1 in the new added column7, otherwise "single". To get the value from the row above I for my calculation tried this code:
"= Table.AddColumn(#"addcolum", ""ConditionalColumn", each if [Häufigkeit]="Double" then ([colum4]{-1}+[colum3]) else [colum2+colum3])"
This doesn't work.
So how I can fix this problem. Thanks in advance
See if this helps. It pulls the value from the row below if article matches
If you need the row above, change each instance of [Index]+1 to [Index]-1
Otherwise please make your question less confusing
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each try if [article]= #"Added Index"{[Index]+1}[article] then #"Added Index"{[Index]+1}[value] else null otherwise null),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index"})
in #"Removed Columns"

Aggregate multiple (many!) pair of columns (Exce)

I have table; The table consists of pairs of date and value columns
Pair Pair Pair Pair .... ..... ......
What I need is the sum of all values for the same date.
The total table has 3146 columns (so 1573 pairs of value and date)!! with up to 186 entries on row level.
Thankfully, the first column contains all possible date values.
Considering the 3146 columns I am not sure how to do that without doing massivle amount of small steps :(
This shows a different method of creating the two column table that you will group by Date and return the Sum. Might be faster than the List.Accumulate method. Certainly worth a try in view of your comment above.
Unpivot the original table
Add 0-based Index column; then IntegerDivide by 2
Group by the IntegerDivide column and extract the Date and Value to separate columns.
Then group by date and aggregate by sum
let
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
//assuming only columns are Date and Value, this will set the data types for any number of columns
Types = List.Transform(List.Alternate(Table.ColumnNames(Source),1,1,1), each {_, type date}) &
List.Transform(List.Alternate(Table.ColumnNames(Source),1,1,0), each {_, type number}),
#"Changed Type" = Table.TransformColumnTypes(Source,Types),
//Unpivot all columns to create a two column table
//The Value.1 table will alternate the related Date/Value
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {}, "Attribute", "Value.1"),
//add a column to group the pairs of values
//below two lines => a column in sequence of 0,0,1,1,2,2,3,3, ...
#"Added Index" = Table.AddIndexColumn(#"Unpivoted Other Columns", "Index", 0, 1, Int64.Type),
#"Inserted Integer-Division" = Table.AddColumn(#"Added Index", "Integer-Division", each Number.IntegerDivide([Index], 2), Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Inserted Integer-Division",{"Index"}),
// Group by the "pairing" sequence,
// Extract the Date and Value to new columns
// => a 2 column table
#"Grouped Rows" = Table.Group(#"Removed Columns", {"Integer-Division"}, {
{"Date", each [Value.1]{0}, type date},
{"Value", each [Value.1]{1}, type number}}),
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"Integer-Division"}),
//Group by Date and aggregate by Sum
#"Grouped Rows1" = Table.Group(#"Removed Columns1", {"Date"}, {{"Sum Values", each List.Sum([Value]), type number}}),
//Sort into date order
#"Sorted Rows" = Table.Sort(#"Grouped Rows1",{{"Date", Order.Ascending}})
in
#"Sorted Rows"
Quick google shows "Number of columns per table 16,384" for powerquery and 16000 for powerBI, so I'm thinking you have to split your input data somehow first, or perhaps this is not the tool for you, maybe AWK
Assuming that works, an M version of what you are looking for. It stacks the columns in groups of 2, then groups and sums them
let Source = Excel.CurrentWorkbook(){[Name="Table4"]}[Content],
Combo = List.Split(Table.ColumnNames(Source),2),
#"Added Custom" =List.Accumulate(
Combo,
#table({"Column1"}, {}),
(state,current)=> state & Table.Skip(Table.DemoteHeaders(Table.SelectColumns(Source, current)),1)
),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Column1"}, {{"Sum", each List.Sum([Column2]), type number}})
in #"Grouped Rows"
186 rows * 1573 pairs of columns = 292,578 records.
Assuming not a very old version of Excel, 293k rows is fine, so it can be done with formulae:
Insert five columns to the left, so data starts in F3.
In A3 put zero, in A4 put 1, select the two and drag down to A188.
In A189 put =A3.
In B3 put 0, and drag down to B188.
In B189 put =B3
"Drag"* down A189 and B189 to row 292580
In C3 put =OFFSET($F$3,A3,B3)
In D3 put =OFFSET($F$3,A3,B3+1)
Select those two cells and click on the cross at bottom right to copy them to the end of column B.
Then put Date and Value in A1 and B1, and use a Pivot Table to get totals, averages, or whatever you need.
Any blank cells in the original input do not matter.
to "drag" down hundred of thousands of cells:
Copy A189 and B189
Goto (F5) A292580
Paste
Pin (F8)
CTRL-up arrow
Enter
And rather than $F$3 I would name that cell Origin, and use "Origin" in the two Offset formulae, but many people seem to consider that too complicated.

Charting average sales per weekday on data composed of hours

I'm using PowerBI desktop and I'm creating a chart to display average sales per weekday:
My data is in the format below:
(sampled in Excel to remove sensitive information, added colors to facilitate visualization)
My problem is: since each day is broken in 24 rows (hours), my average is wrong by a factor of 24.
For example, if I select January-2019 in the slicer, which has five Tuesdays (weekday code: 2), I want to see on the bar number 2:
(sum of amount where weekday = 2) / 5
Instead, I'm calculating:
(sum of amount where weekday = 2) / (24 * 5)
I can think of some ways to get this right, but they involve custom columns or auxiliary tables. I'm sure there is a simpler answer using DAX and measures, but I'm still learning it.
How can I correctly calculate this?
Let's assume your table name is "Data". Create 3 DAX measures (not calculated columns):
Measure 1:
Total Amount = SUM(Data[Amount])
Measure 2:
Number of Days = DISTINCTCOUNT(Data[Date])
Measure 3:
Average Amount per Day = DIVIDE( [Total Amount], [Number of Days])
Drop the last measure into a chart, it should give you the expected result.
As I understand from your excel you are working with 3 different columns. You can better combine this to a datetime and let power-bi handle it.
Below m-language will do this for you:
let
Source = Excel.Workbook(File.Contents("C:\....\Test.xlsx"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"date", type datetime}, {"hour", type time}, {"amount", type number}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Date", each [date]+ Duration.FromText(Time.ToText([hour]))),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom",{"amount", "Date"}),
#"Filtered Rows" = Table.SelectRows(#"Removed Other Columns", each ([amount] <> 0))
in
#"Filtered Rows"
The trick is in the added column: #"Added Custom" = Table.AddColumn(#"Changed Type", "Date", each [date]+ Duration.FromText(Time.ToText([hour])))
Here I add the time to the date.
I also removed the empty (zero amount) rows, you do not need them.
I added the Date & weekday to the Axis so a user can now drill down from year, month, day to weekday.
Be aware you need to do the SUM of the amount, not the average.

Filter companies that have at least 3 specific products

I have an excel pivot table (and a table dataset behind) that has the structure like the one below. How can I filter/show only companies (Col A) with Products (Col B) 1 AND 2 AND 3? Sounds like something easy but can't find a way to do that. No problem by achieving this using Power Query (available in Power BI or Excel).
A1: Company 1 | B1: Product 1
A2: Company 1 | B2: Product 2
A3: Company 1 | B3: Product 3
A4: Company 1 | B4: Product 4
A5: Company 2 | B5: Product 1
A6: Company 3 | B6: Product 1
A7: Company 4 | B7: Product 1
A8: Company 4 | B8: Product 2
A9: Company 4 | B9: Product 3
A10: Company 4 | B9: Product 4
A11: Company 4 | B9: Product 5
Here's an approach using Power Query.
Starting with this brought into Power Query from the table in Excel:
I then group on Company (Transform > Group By):
Then I add a new custom column (Add Column > Custom Column) to flag whether each company has the 3 products included in its associated grouped table's Product column:
Then I filter out the FALSE entries from the new custom column (use button at top right of Custom column):
Then I expand the Products column from the embedded table in the AllData column (use button at top right of AllData column).
Then I remove the Custom column:
Here's the M code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Company", type text}, {"Product", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Company"}, {{"AllData", each _, type table}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each List.ContainsAll([AllData][Product], {"Product 1","Product 2","Product 3"})),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([Custom] = true)),
#"Expanded AllData" = Table.ExpandTableColumn(#"Filtered Rows", "AllData", {"Product"}, {"Product"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded AllData",{"Custom"})
in
#"Removed Columns"
Basically, you'll need to do a couple of things to do this entirely in Excel:
Add a new table that lists the products, with a column indicating whether that product is included/flagged:
Update your company/product table to have 2 helper columns: One to VLOOKUP whether the product is flagged, and one to indicate whether a company has all 3 flagged products:
The first helper column would use a formula like =VLOOKUP([#Product],tProducts,2,FALSE).
The second helper column would use a formula like =COUNTIFS([Company],[#Company],[Product Flagged],TRUE)>=3.
Rows with a TRUE in Column D have 1 each of Products 1, 2, and 3 (unless you have rows with duplicate company/product combinations, where it gets a bit trickier):
In your pivot table, you can filter by this helper column:

Resources