I am currently working in Power Query and trying to determine a specific field to output based on multiple conditions.
I have a table as follows:
What we can see is that we have multiple rows per order und 2 status keys.
I need to determine that MAX Date based on this logic per item:
As we can see, each type has a specific key combination to get the MAX Date.
The result would be like this:
Order 100 is 04.02.2021
Is there any alternative to a very long IF Clause?
There are 7 Product types in total each with specific key combinations.
How would you do that? In Power Query.
Just Join the two tables on the relevant keys:
let
//read original data and set data types
Source = Excel.CurrentWorkbook(){[Name="Table10"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"Order", Int64.Type}, {"Product Type", type text},
{"Status Key 1", Int64.Type}, {"Status Key 2", Int64.Type},
{"Date", type date}}),
//specification table
//hard coded here but
// could read it in from Excel instead
spec = Table.FromColumns({
{"Metals","Pipes"},
{80,50},
{30,30}},
type table[Material=text, Key1 = Int64.Type, Key2=Int64.Type]),
//now just do the join and remove the unneeded columns
join = Table.Join(#"Changed Type",{"Product Type","Status Key 1","Status Key 2"}, spec,{"Material","Key1","Key2"},JoinKind.RightOuter),
#"Removed Columns" = Table.RemoveColumns(join,{"Material", "Key1", "Key2"})
in
#"Removed Columns"
Note: Depending on what you want to happen if there are specifications that are not matched at all; or if there are specifications that are matched multiple times, you may need to change the type of Join
Related
I am trying to create a forecast (single table) for departments to input their assumptions on spending in a single table. Instead of entering amounts for every single month, I would like the user to enter the amount, frequency, start date, and end date for each category. To illustrate, see below the table with some sample data.
This is the result in Power Query (or Power BI) I am trying to get, which is my understanding of how to be able to run date slicers and filters in a Power BI model when comparing against actuals.
If this can't be done with DAX and instead must be done in excel (through look up formulas), how would you structure the formula?
Here is a PQ example that creates what you show as your desired table given what you show as your input:
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 better understand the algorithm
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table9"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"G/L", Int64.Type}, {"Dimension", type text}, {"Description", type text},
{"Amount", Int64.Type}, {"Repeat Every", type text}, {"Start Date", type date}, {"End Date", type date}}),
//Last possible date as Today + 5 years (to end of month)
lastDt = Date.EndOfMonth(Date.AddYears(Date.From(DateTime.FixedLocalNow()),5)),
//Generate list of all possible dates for a given row using List.Generate function
allDates = Table.AddColumn(#"Changed Type", "allDates", each let
lastDate = List.Min({lastDt,[End Date]}),
intvl = {1,3,6}{List.PositionOf({"Monthly","Quarterly","Semi Annual"},[Repeat Every])}
in
List.Generate(
()=> [Start Date],
each _ <= lastDate,
each Date.EndOfMonth(Date.AddMonths(_,intvl)))),
//Remove unneeded columns and expand the list of dates
#"Removed Columns" = Table.RemoveColumns(allDates,{"Repeat Every", "Start Date", "End Date"}),
#"Expanded allDates" = Table.ExpandListColumn(#"Removed Columns", "allDates"),
//Sort to get desired output
// Date column MUST be sorted to ensure correct order when pivoted
// Other columns sorted alphanumerically, but could change the sort to reflect original order if preferred.
#"Sorted Rows" = Table.Sort(#"Expanded allDates",{
{"allDates", Order.Ascending},
{"G/L", Order.Ascending},
{"Dimension", Order.Ascending}}),
//Pivot the date column with no aggregation
#"Pivoted Column" = Table.Pivot(
Table.TransformColumnTypes(#"Sorted Rows", {
{"allDates", type text}}, "en-US"),
List.Distinct(Table.TransformColumnTypes(#"Sorted Rows", {{"allDates", type text}}, "en-US")[allDates]),
"allDates", "Amount")
in
#"Pivoted Column"
Original Data
Results
as an example I have created a small set of Data in B3:F20 with component, type and count list etc. I have assigned a Name "TypeP" for B24:B25.
My goal is to group the components based on the type and sum their count from Input B3:F20. To show the final goal, I have manually added the result in L3:N7. In L4, multiple(here 2) instances of Component DEF with same type PA are grouped and the count is summed.
I was able to achieve my goal partially as in H3:J11, where the data was grouped based on the TypeP, but still I should be able to group the similar types.
Formula I have used in H3 is
=FILTER(INDEX(B3:F20;SEQUENCE(ROWS(B3:F20));{1\2\3});(ISNUMBER(MATCH(C3:C20;TypeP;0))=TRUE))
How can I achieve the result as shown in L3:N7?
L3: =UNIQUE(H3:I11)
N3: =SUMIFS($J$3:$J$11,$H$3:$H$11,L3,$I$3:$I$11,M3)
Select N3 and fill down as far as needed.
You could also do this in Power Query
To use Power Query
Make your TypeP a Named Range (or a Table)
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 main table
//Change table name in next line to real name of your table in the workbook
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//set data types
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"Component", type text}, {"Type", type text}, {"Count", Int64.Type},
{"Others1", type text}, {"Others2", type any}}),
//read in the types to filter by from a "Named Range"
// Range name is `TypeP` in the workbook
typeP = Excel.CurrentWorkbook(){[Name="TypeP"]}[Content][Column1],
//Filter for the desired types
filter = Table.SelectRows(#"Changed Type", each List.Contains(typeP,[Type])),
//Group by "component and type"
//Then sum the Count column
#"Grouped Rows" = Table.Group(filter, {"Component", "Type"},
{{"Count", each List.Sum([Count]), type nullable number}})
in
#"Grouped Rows"
I have a rather large power query (35k rows but lots of columns) and I face a situation where I sometimes have a single sales order tying to multiple stock numbers where I get multiple planned dates associated with multiple factories. I need to apply the earliest planned date - along with its associated factory to all lines of that sales order. I have looked into merging the query to itself - and this does seem to be able to get to the minimum planned date. However that takes a VERY long time and I still can't seem to figure out how to also get the associated factory of that date and apply to all the rows of that sales order.
Here is some sample data:
What I need to do is apply the Planned Date and Factory information in red to all the other lines of the SO #. Is this something tht can be done in Power Query?
Here is some MCode you may be able to adapt to your real data.
It
uses the data you show as a starting point
Groups by SOP#
Determines the first date and associated factory
Re-expands the table (except for the original date/factory columns
let
Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"SO#", Int64.Type}, {"Stock #", Int64.Type}, {"Planned Date", type date}, {"Factory", type text}}),
//Group by SO#
// then return minimum date and corresonding factory
#"Grouped Rows" = Table.Group(#"Changed Type", {"SO#"}, {
{"All", each _, type table [#"SO#"=nullable number, #"Stock #"=nullable number, Planned Date=nullable date, Factory=nullable text]},
{"Planned Date", each List.Min([Planned Date]), Date.Type},
{"Factory", (t)=> List.Range(t[Factory],List.PositionOf(t[Planned Date],List.Min(t[Planned Date])),1){0}, Text.Type}
}),
//Expand the table (except for the original date and factory columns
#"Expanded All" = Table.ExpandTableColumn(#"Grouped Rows", "All", {"Stock #"}, {"Stock #"})
in
#"Expanded All"
Need some guidance, please. I have two power query tables in excel, I'm looking to add columns from table B to table A where the Customer# matches. I don't want to use vlookup formulas due to performance so I was wondering if with power query this is possible.
Here is an example:
Thanks a lot!
The M-Code for merging TableA with TableB would look like that
let
Source = Excel.CurrentWorkbook(){[Name="TableA"]}[Content],
chgType = Table.TransformColumnTypes(Source,{{"Customer Number", type text}, {"Certification", type text}}),
mergeQueries = Table.NestedJoin(chgType, {"Customer Number"}, TableB, {"Customer Number"}, "TableB", JoinKind.LeftOuter),
extendTbl = Table.ExpandTableColumn(mergeQueries, "TableB", {"Crd Limit"}, {"Crd Limit"})
in
extendTbl
You need to import TableB into Powerquery beforehand, as well.
Further reading on this
Microsoft documentation
Excel Guru Blog
I think you can get what you want by to a JoinKind.Inner.
Note that this will return customer ID's that are present in both tables. If that is not the case, and you want unmatched ID's to be returned, you'll need to do a .NestedJoin with JoinKind.FullOuter and then expand the resulting table.
eg:
let
Source1 = Excel.CurrentWorkbook(){[Name="TableA"]}[Content],
tabA = Table.TransformColumnTypes(Source1,{{"Customer Number", type text}, {"Certification", type text}}),
Source2 = Excel.CurrentWorkbook(){[Name="TableB"]}[Content],
tabB = Table.TransformColumnTypes(Source2,{{"Customer Number", type text}, {"Crd Limit", Currency.Type}}),
joinTbl = Table.Join(tabA,"Customer Number",tabB,"Customer Number",JoinKind.Inner)
in
joinTbl
So, I found a couple other solutions to similar questions I have, but not quite exact. I am interpreting survey results in Excel where the survey tool (Qualtrics) has placed responses from multiple select questions ("select all that apply") in a single cell, comma separated. I need counts of the individual responses calculated in a Pivot Table, where I will also take totals from some respondent demographics I'm going to add to the response spreadsheet. What I am trying to do is very similar to this:
Split comma separated entries to new rows
However my sheet will have multiple columns with comma separated responses, like this:
....and I need it in column format so I can Pivot and count. As I mentioned I am going to add in some attribute data (HR data, and that's why I cannot import it into Qualtrics - can't send outside the company), so I'll still need to pair up the person with the response. However, if there is a script or command that can run and split this out for me, I'm not sure how it would handle differing numbers of response from column to column to create the needed rows (Like Bill and Karen in the example). Would I need to have the column with the longest csv cell first and so on? However, it would look something like this:
Is there something I can do to accomplish this?
your desired layout is actually not fit for proper pivot tables, either. You need a really flat table structure, so you can filter on likes without simultaneously hiding dislikes.
You can easily transform your data with Power Query. Load the data into the Power Query Editor, then split each question column by the delimiter ", " (comma followed by space). This will split each answer into its own column, with the question in the header appended by .1, .2 etc.
Then select the name column and click "Unpivot other columns". The question headers will now be in the attribute column. Split that attribute column by the delimiter "." (dot) and delete the column with the split off numbers.
Finally, rename the columns to Question and Answer.
Here is the M code that is generated when doing that.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"like", type text}, {"dislike", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "dislike", Splitter.SplitTextByDelimiter(", ", QuoteStyle.Csv), {"dislike.1", "dislike.2", "dislike.3", "dislike.4", "dislike.5"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"dislike.1", type text}, {"dislike.2", type text}, {"dislike.3", type text}, {"dislike.4", type text}, {"dislike.5", type text}}),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "like", Splitter.SplitTextByDelimiter(", ", QuoteStyle.Csv), {"like.1", "like.2", "like.3", "like.4"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"like.1", type text}, {"like.2", type text}, {"like.3", type text}, {"like.4", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type2", {"Name"}, "Attribute", "Value"),
#"Split Column by Delimiter2" = Table.SplitColumn(#"Unpivoted Other Columns", "Attribute", Splitter.SplitTextByDelimiter(".", QuoteStyle.Csv), {"Attribute.1", "Attribute.2"}),
#"Changed Type3" = Table.TransformColumnTypes(#"Split Column by Delimiter2",{{"Attribute.1", type text}, {"Attribute.2", Int64.Type}}),
#"Removed Columns" = Table.RemoveColumns(#"Changed Type3",{"Attribute.2"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Attribute.1", "question"}, {"Value", "Answer"}})
in
#"Renamed Columns"
The resulting table looks like this:
If your original data receives more rows, just refresh the query.
Now you have a table that can be used in pivots without compromising any data.
Not sure exactly what do you want to achieve (may be too many things at once), at least for the first part of your question: Count of response per category you can do this:
For each response column, create a count column, for example:
Name, Response_column_a, count_a, ...
The formula for count: count of comma + 1
In excel it can be acchieved with the following formula:
You now have:
1) count of responses
2) can generate total count of responses per category, for example count of Response A for Karen.