The more I use Power Query and the M language that underpins it, the more I see how useful it is – quite apart from its abilities to import data from other data sources – as a third option (after regular Excel formulas and Power Pivot/DAX) to solve problems in Excel itself. For example, last week I read this blog post by David Hager about finding the number of unique values in a delimited string:
It’s an interesting question and the Excel formulas in this post are way beyond what I’m capable of writing. The point is, though, that Power Query can do this very easily indeed just through the UI. Starting with the following table in a worksheet:
You just need to import it into a Power Query query:
Use the Split Column/By Delimiter/By Comma option on the Input column:
This creates as many columns as you’ve got values in the delimited list with the largest number of values:
You can then use the Unpivot option on these new columns:
Then remove the Attribute column:
Next, select Remove Duplicates on the entire table:
Finally, do a Group By on the RowID column and Count the number of rows:
And bingo, you have the number of distinct values in each delimited list:
Here’s the complete code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
SplitColumnDelimiter = Table.SplitColumn(Source,"Input",Splitter.SplitTextByDelimiter(","),13),
Unpivot = Table.Unpivot(SplitColumnDelimiter,{"Input.1", "Input.2", "Input.3", "Input.4",
"Input.5", "Input.6", "Input.7", "Input.8", "Input.9", "Input.10", "Input.11", "Input.12"
, "Input.13"},"Attribute","Value"),
RemovedColumns = Table.RemoveColumns(Unpivot,{"Attribute"}),
DuplicatesRemoved = Table.Distinct(RemovedColumns),
GroupedRows = Table.Group(DuplicatesRemoved, {"RowID"}, {{"Count of Distinct Values"
, each Table.RowCount(_), type number}})
in
GroupedRows
Emboldened by this, I turned to another Excel challenge – this time from Chandoo’s blog:
http://chandoo.org/wp/2013/07/16/formula-challenge-001-1/
This time the objective is to split a string containing blocks of text and numbers so that you get everything after the first block of numbers. The whole point of the challenge that Chandoo lays down is to do this in a single Excel formula with no VBA; I was just curious to see how easy it would be to solve the problem in Power Query however many steps it took. Unfortunately this is not a something that you can do just in the UI and you need to write some M, but the code isn’t too bad:
Starting with the following table:
You then need to create a new column containing a list of the positions of every occurrence of a numeric character in each string:
Then create another new column containing a list of continuous numbers starting from the first number in the previous list and incrementing by 1:
Then create another new column containing the minimum value from a list all of the values that are in the previous list and not in the first list you created :
This gives the position of the first character in the second block of text, which can then be used to find a substring of the original text:
Here’s the complete code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
InsertedCustom = Table.AddColumn(Source, "NumericPositions",
each Text.PositionOfAny([Input], {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, Occurrence.All)),
InsertedCustom1 = Table.AddColumn(InsertedCustom, "NumberOfPositions",
each List.Numbers(List.Min([NumericPositions]), List.Count([NumericPositions]))),
InsertedCustom2 = Table.AddColumn(InsertedCustom1, "StartChar",
each List.Min(List.Difference([NumberOfPositions], [NumericPositions]))),
InsertedCustom3 = Table.AddColumn(InsertedCustom2, "Output", each Text.Range([Input], [StartChar]))
in
InsertedCustom3
My first reaction when I saw M was that I liked it, but I didn’t think Excel users were prepared to learn yet another language. I still think this (it would have been much better if Power Query, like Power Pivot/DAX, used a language that was consistent with Excel formula language) but as you can see from these examples, sometimes having a choice of tools means it’s more likely that you can find an easy solution to a problem.