PowerBI or Excel : create columns based on unique values in column - powerquery

I have an Excel file with translations in the following format:
Field | Language | Translation
startbutton English Start
startbutton French Démarrer
stopbutton English Stop
stopbutton French Arrêter
But I would like to have it in this format:
Field | English | French
startbutton Start Démarrer
stopbutton Stop Arrêter
How can this be achieved? I already tried some things with PowerQuery but wasn't able to get the desired result...

let
Source = Table.FromRows(
Json.Document(
Binary.Decompress(
Binary.FromText(
"i45WKi5JLCpJKi0pyc9T0lFyzUvPySzOALKCQeJKsTroKtyKUvOSQQpcDq/MTSwqSi2CKsovwGpKfgGmPNwMx6Kiw6tKQEbEAgA=",
BinaryEncoding.Base64
),
Compression.Deflate
)
),
let
_t = ((type nullable text) meta [Serialized.Text = true])
in
type table [Field = _t, Language = _t, Translation = _t]
),
#"Changed Type" = Table.TransformColumnTypes(
Source,
{{"Field", type text}, {"Language", type text}, {"Translation", type text}}
),
#"Pivoted Column" = Table.Pivot(
#"Changed Type",
List.Distinct(#"Changed Type"[Language]),
"Language",
"Translation"
)
in
#"Pivoted Column"

Related

Recent call date & latest agent name

Problem statement: For a particular "Id" how can I choose first call date & name of agent who has called recently
Desired output: For Eg: here first call date for id 16468 would be 02-01-2023 & agent who has called recently would be ANGEL which is based on recent call date for that particular id
enter image description here Current scenario
enter image description here Desired output
How can I get above desired output in power query code ?
I tried to create distinct "Id" table and separate Date table with this code but I am not able to display first call date & agent name who has called recently against each distinct "Id"
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"call date", type datetime}, {"Agent name", type text}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Changed Type",{{"call date", type date}}),
Unique_Tablerows = Table.Distinct(Table.SelectColumns(#"Changed Type1", "Id")),
DateOnly_Table = Table.SelectColumns(#"Changed Type1", "call date")
in
DateOnly_Table
Try below. Next time please past samples as text not images
Note your sample output is confused based on your request, since if you are looking for an ID you cant have that repeat twice
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"call date", type date}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Id"}, {
{"call date", each List.Min([call date]), type nullable date},
{"Agent name", each Table.LastN(Table.Sort(_,{{"call date", Order.Ascending}}),1){0}[Agent name], type text}
})
in #"Grouped Rows"

Power Query - running total that resets when values change

I have been searching for a week now and cannot find a resolution to my problem. I have a table which lists the "event" and individual is in during a certain week. I want to add a column - via PowerQuery - that will count the number of weeks a person has been in that event and then resets if the event changes in the following week. For example...
Pers1
Date
Event
Weeks in Event
Pers1
12/22/2022
Consideration
1
Pers1
12/26/2022
Consideration
2
Pers1
1/05/2022
Interview
1
Pers1
1/12/2022
Consideration
1
Pers1
1/19/2022
Consideration
2
Pers1
1/26/2022
Awaiting Hire
1
Pers2
1/19/2022
Awaiting Hire
1
Pers2
1/26/2022
Awaiting Hire
2
Note how the count resets back to starting at 1 when Pers1 has their second stint of Consideration during weeks 1/12 and 1/19. Additionally, I need the solution to be smart enough to distinguish between two different individuals and uniquely count their time in an event.
This community has always come through for me. Please help!
EDIT 1: I incorporated the code provided by Ron and am receiving the following error: Expression.Error: 5 arguments were passed to function which expects between 2 and 4.
Details:
Pattern=
Arguments=List
PQ Advanced Editor Code is below:
let
Source = Excel.Workbook(File.Contents("C:\Location"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Pers1", type text}, {"Date", type date}, {"Event", type text}}),
//add an offset column for Pers and Event to do easy comparison with previous row
offsetPersonEvent=Table.FromColumns(
Table.ToColumns(#"Changed Type")
& {List.RemoveFirstN(#"Changed Type"[Pers1]) & {null}}
& {List.RemoveFirstN(#"Changed Type"[Event]) & {null}},
type table[Pers=text, Date=date,Event=text,offsetPers=text, offsetEvent=text]
),
//create "grouper" column by checking where both Pers and Event change
#"Added Index" = Table.AddIndexColumn(offsetPersonEvent, "Index", 0, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "groups",
each if [Pers]=[offsetPers] and [Event]=[offsetEvent] then null else [Index]),
//remove unneeded columns, fillUp the grouper, and group by "grouper"
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"offsetPers", "offsetEvent", "Index"}),
#"Filled Up" = Table.FillUp(#"Removed Columns",{"groups"}),
//Add Index column to each subtable
#"Grouped Rows" = Table.Group(#"Filled Up", {"groups"}, {
{"addedIndex", each Table.AddIndexColumn(_,"Weeks in Event",1,1,Int64.Type)
, type table}}),
//Remove unneccessary columns
// Expand the grouped tables
// reset the data types
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"groups"}),
#"Expanded addedIndex" = Table.ExpandTableColumn(#"Removed Columns1", "addedIndex", {"Pers", "Date", "Event", "Weeks in Event"}, {"Pers", "Date", "Event", "Weeks in Event"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded addedIndex",{{"Pers", type text}, {"Date", type date}, {"Event", type text}, {"Weeks in Event", Int64.Type}})
in
#"Changed Type1"
Assuming your data is sorted by Person and then by Date, as you show, you can use the following M-Code.
(If your data is not so sorted, then you could merely add steps initially to sort it appropriately, and then continue with the code shown)
Please read the code comments and examine the Applied steps to understand the algorithm
Open the Advanced Editor and paste in the code below
let
//change table name in next line to your actual table name
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Pers1", type text}, {"Date", type date}, {"Event", type text}}),
//add an offset column for Pers and Event to do easy comparison with previous row
offsetPersonEvent=Table.FromColumns(
Table.ToColumns(#"Changed Type")
& {List.RemoveFirstN(#"Changed Type"[Pers1]) & {null}}
& {List.RemoveFirstN(#"Changed Type"[Event]) & {null}},
type table[Pers=text, Date=date,Event=text,offsetPers=text, offsetEvent=text]
),
//create "grouper" column by checking where both Pers and Event change
#"Added Index" = Table.AddIndexColumn(offsetPersonEvent, "Index", 0, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "groups",
each if [Pers]=[offsetPers] and [Event]=[offsetEvent] then null else [Index]),
//remove unneeded columns, fillUp the grouper, and group by "grouper"
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"offsetPers", "offsetEvent", "Index"}),
#"Filled Up" = Table.FillUp(#"Removed Columns",{"groups"}),
//Add Index column to each subtable
#"Grouped Rows" = Table.Group(#"Filled Up", {"groups"}, {
{"addedIndex", each Table.AddIndexColumn(_,"Weeks in Event",1,1,Int64.Type)
, type table}}),
//Remove unneccessary columns
// Expand the grouped tables
// reset the data types
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"groups"}),
#"Expanded addedIndex" = Table.ExpandTableColumn(#"Removed Columns1", "addedIndex", {"Pers", "Date", "Event", "Weeks in Event"}, {"Pers", "Date", "Event", "Weeks in Event"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded addedIndex",{{"Pers", type text}, {"Date", type date}, {"Event", type text}, {"Weeks in Event", Int64.Type}})
in
#"Changed Type1"
Ron's code worked with one minor tweak. For me, the following section of code was causing an error
//Add Index column to each subtable
#"Grouped Rows" = Table.Group(#"Filled Up", {"groups"}, {
{"addedIndex", each Table.AddIndexColumn(_,"Weeks in Event",1,1,Int64.Type)
, type table}}),
I removed the Int64.Type parameter from the Table.AddIndexColumn and everything functioned. I've included the updated code snip-it below:
let
Source = Excel.Workbook(File.Contents("C:\Location"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Pers1", type text}, {"Date", type date}, {"Event", type text}}),
//add an offset column for Pers and Event to do easy comparison with previous row
offsetPersonEvent=Table.FromColumns(
Table.ToColumns(#"Changed Type")
& {List.RemoveFirstN(#"Changed Type"[Pers1]) & {null}}
& {List.RemoveFirstN(#"Changed Type"[Event]) & {null}},
type table[Pers=text, Date=date,Event=text,offsetPers=text, offsetEvent=text]
),
//create "grouper" column by checking where both Pers and Event change
#"Added Index" = Table.AddIndexColumn(offsetPersonEvent, "Index", 0, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "groups",
each if [Pers]=[offsetPers] and [Event]=[offsetEvent] then null else [Index]),
//remove unneeded columns, fillUp the grouper, and group by "grouper"
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"offsetPers", "offsetEvent", "Index"}),
#"Filled Up" = Table.FillUp(#"Removed Columns",{"groups"}),
//Add Index column to each subtable
#"Grouped Rows" = Table.Group(#"Filled Up", "groups", {
{"addedIndex", each Table.AddIndexColumn(_,"Weeks in Event",1,1)
, type table}}),
//Remove unneccessary columns
// Expand the grouped tables
// reset the data types
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"groups"}),
#"Expanded addedIndex" = Table.ExpandTableColumn(#"Removed Columns1", "addedIndex", {"Pers", "Date", "Event", "Weeks in Event"}, {"Pers", "Date", "Event", "Weeks in Event"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded addedIndex",{{"Pers", type text}, {"Date", type date}, {"Event", type text}, {"Weeks in Event", Int64.Type}})
in
#"Changed Type1"

Create conditional Table.TransformColumnType in powerquery

I am trying to convert columns to numeric. If TransformColumnTypes causes an error, I want to keep it text. Something like this:
#"Changed Type" = try Table.TransformColumnTypes(CombineTables,List.Transform(sTranCol, each {_, type number})), otherwise Table.TransformColumnTypes(CombineTables,List.Transform(sTranCol, each {_, type number})),
Obviously this doesn't work. sTranCol is the list of columns to covert to numeric. It is dynamically created and isn't static. I don't care if it puts error in the cell but transposing with errors in the cells is causing query to abort.
The M Code methods I've seen to detect data type of a column consist of sampling the data and determining the type. This seems messy.
But perhaps an alternative might be type the columns as numeric, and then replace the error values with something that won't cause a problem when transposing.
Here is some sample code to replace errors with null, but you could replace with anything null or numeric:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WSlTSUTJUitWJBpI6SsZglhGQZQ5mVQBZiWCWKZCVBGaZA1kVEB0ghYYmSrGxAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,
List.Transform(Table.ColumnNames(Source), each {_,type nullable number})),
nullList = List.Transform(Table.ColumnNames(#"Changed Type"), each {_, null}),
#"Replaced Errors" = Table.ReplaceErrorValues(#"Changed Type", nullList)
in
#"Replaced Errors"
Source
Changed Type
Replaced Errors
Edit: Add M Code to set column types depending on if all numeric
let
Source = Excel.CurrentWorkbook(){[Name="Table37"]}[Content],
//check data type
//if all numbers set to number, else any
colTypes = List.Accumulate(Table.ColumnNames(Source),
{},
(state,current)=> List.Combine({state,
if List.IsEmpty(
List.RemoveMatchingItems(
List.Transform(Table.Column(Source,current), each Value.Type(_)),
{type number}))
then {{current, type number}}
else {{current, type any}}})),
#"Changed Type" = Table.TransformColumnTypes(Source,colTypes)
in
#"Changed Type"
Source
Changed Type

How to select certain column in power query

I would like to choose a certain columns in power query, but not using their names. Ex. I can do this in R, by command: select. I'm wondering how i can do it in power query. I found some information here, but not all that I need.
Any idea, if I want to refer to more than one column?
It doesn't work if I write the code as below:
#"Filtered Part Desc" = Table.SelectRows (
#"Removed Columns3",
each List.Contains(
{ "ENG", "TRANS" },
Record.Field(_, Table.ColumnNames(#"Removed Columns3") { 5, 6, 7 })
)
)
Let's say I have this table and want to do a couple of things to it.
First, I want to change the column type of the second and last columns. We can use Table.ColumnNames to do this using simple indexing (which starts at zero) as follows:
Table.TransformColumnTypes(
Source,
{
{Table.ColumnNames(Source){1}, Int64.Type},
{Table.ColumnNames(Source){3}, Int64.Type}
}
)
That works but requires specifying each index separately. If we want to unpivot these columns like this
Table.Unpivot(#"Changed Type", {"Col2", "Col4"}, "Attribute", "Value")
but using the index values instead we can use the same method as above
Table.Unpivot(
#"Changed Type",
{
Table.ColumnNames(Source){1},
Table.ColumnNames(Source){3}
}, "Attribute", "Value"
)
But is there a way to do this where we can use a single list of positional index values and use Table.ColumnNames only once? I found a relatively simple though unintuitive method on this blog. For this case, it works as follows:
Table.Unpivot(
#"Changed Type",
List.Transform({1,3}, each Table.ColumnNames(Source){_}),
"Attribute", "Value"
)
This method starts with the list of positional index values and then transforms them into column names by looking up the names of the columns corresponding to those positions.
Here's the full M code for the query I was playing with:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WSlTSUTIE4nIgtlSK1YlWSgKyjIC4AogtwCLJQJYxEFcCsTlYJAXIMgHiKiA2U4qNBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Col1 = _t, Col2 = _t, Col3 = _t, Col4 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{Table.ColumnNames(Source){1}, Int64.Type},{Table.ColumnNames(Source){3}, Int64.Type}}),
#"Unpivoted Columns" = Table.Unpivot(#"Changed Type", List.Transform({1,3}, each Table.ColumnNames(Source){_}), "Attribute", "Value")
in
#"Unpivoted Columns"

Eliminating duplicates error in Visual Studio Development Tool for Tabular and SQL services

I have a question about my M code. I am currently working in Visual Studio and 'Editing Expressions' via VSDT. The problem that I have is that I am trying to create a relationship between one dimension table and another fact table using a primary key. The primary key in the Dim table has unique values, or so it seems. I have removed nulls and blanks in the primary key column. I started off creating the PK by concatenating three columns shared between the two tables. Further, I have removed duplicates and run this command in the PQ editor. I am puzzled as to why, when I join the two tables, I get an error message saying that my Dim table does not have unique values. More frustrating is when I sort the data ascending and descending and I find no blanks, where there once was a blank. I am puzzled about how to fix this problem. I've tried 16 different ways to Sunday-- even moving some of the query steps around. To no avail...
The error thrown:
Error: Failed to save modifications to the server. Column Style_List_PK in Table dStyles contains blank values and this is not
allowed for columns on the one-side of a one-to-many relationship or
for columns that are used as a primary key of a table.
The code:
let
Source = #"SQL/sbsqld59;PJ",
dbo_Style_List = Source{[Schema="dbo",Item="Style_List"]}[Data],
#"Changed Type" = Table.TransformColumnTypes(dbo_Style_List,{{"Brand", type text}, {"Style", type text}, {"Style Description", type text}, {"Sizes", type any}, {"Style Name", type text}, {"General Category", type text}, {"Style Category", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Sizes", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Sizes.1", "Sizes.2", "Sizes.3", "Sizes.4", "Sizes.5", "Sizes.6", "Sizes.7", "Sizes.8", "Sizes.9"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Sizes.1", type text}, {"Sizes.2", type text}, {"Sizes.3", type text}, {"Sizes.4", type text}, {"Sizes.5", type text}, {"Sizes.6", type text}, {"Sizes.7", type text}, {"Sizes.8", type text}, {"Sizes.9", type text}}),
#"Replaced Errors" = Table.ReplaceErrorValues(#"Changed Type1", {{"Sizes.1", "NULL"}, {"Sizes.2", "NULL"}, {"Sizes.3", "NULL"}, {"Sizes.4", "NULL"}, {"Sizes.5", "NULL"}, {"Sizes.6", "NULL"}, {"Sizes.7", "NULL"}, {"Sizes.8", "NULL"}, {"Sizes.9", "NULL"}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Replaced Errors", {"Brand", "Style", "Style Description", "Style Name", "General Category", "Style Category"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Value", "Size"}}),
#"Replaced Value" = Table.ReplaceValue(#"Renamed Columns","","NULL",Replacer.ReplaceValue,{"Brand", "Style", "Style Description", "Style Name", "General Category", "Style Category", "Size"}),
#"Uppercased Text" = Table.TransformColumns(#"Replaced Value",{{"Style", Text.Upper, type text}, {"Brand", Text.Upper, type text}, {"Size", Text.Upper, type text}}),
#"Added Custom" = Table.AddColumn(#"Uppercased Text", "Style_List_PK", each Text.Combine({[Brand],[Style],[Size]})),
#"Changed Type2" = Table.TransformColumnTypes(#"Added Custom",{{"Style_List_PK", type text}}),
#"Trimmed Text" = Table.TransformColumns(#"Changed Type2",{{"Style_List_PK", Text.Trim, type text}}),
#"Removed Duplicates" = Table.Distinct(#"Trimmed Text", {"Style_List_PK"}),
#"Filtered Rows" = Table.SelectRows(#"Removed Duplicates", each [Style_List_PK] <> null and [Style_List_PK] <> "" and [Style_List_PK] <> " " and [Style_List_PK] <> " ")
in
#"Filtered Rows"

Resources