In the attached, if you go to the
Data tab of the ribbon and click the
Queries and Connections icon in the
Queries and Connections section, a
Queries and Connections pane will appear, then if you choose the
Queries section of that pane you'll see 5 queries. Only the first 4 are needed.
The
DataTable query is short and simple; if you double-click it, the
Power Query Editor pops up, and in the
Applied Steps section on the right usually the last step is selected. You can click on any step to see what's happened up to that step. The three steps are
Source, which just grabs the table from the sheet, then
Trimmed Text which removes any trailing and leading spaces from all the cells in all the columns (in the same way as the vba
Trim command, it only removes those spaces and doesn't convert multiple spaces between words to single spaces as the worksheet function
TRIM does), then the third step changes the data type of the columns to an appropriate type for later processing. That's the Data table spruced up.
Now to do the same, plus a bit, to the other table which I've called
Categories. When you bring this up in the
Power Query Editor, the third step is
Split Column by Character Transition where I've chosen to split the contents of the
Department column where the text changes from being any one '=','<','>' to not being one of those three characters and I've named the columns
DeptOper and
DeptValue for obvious reasons and to make it clearer to us humans what's in those columns when we refer to them later. You can probably gather from the formula/function bar (which you can expand and scroll through just like the regular Excel formula bar) that the bit which decides how the splitting is done is:
Code:
Splitter.SplitTextByCharacterTransition({"<",">","="}, (c) => not List.Contains({"<",">","="}, c))
The next step,
Trimmed Text, trims the text in the
DeptValue column since the data in that column mostly had a space between the '<>' and the department name.
The next two steps do much the same thing to the
Count and
Month columns, while the final step changes the data type of several of the columns. So that's that.
I've put versions of these two tables on the sheet
Sheet1 of the attached - that sheet isn't needed so can safely be deleted.
Skipping to the fourth query called
Result, this is a very short one consisting of grabbing the earlier prepared DataTable query and invoking a custom function. Dead easy. Of course, the donkey work is carried out by that custom function, so let's have a look at it:
It's called
fnFindOutcomes. If you double-click on it to bring it into the
PQ Editor you'll be faced with an unhelpful
Enter Parameters dialogue. If instead you right-click it and choose
Edit you get a similar dialogue and a single step. This is because it's a function. You can see the entire code in the formula bar or you could click on
Advanced Editor in the
Home tab to see the steps there but you won't see the results of each step as a developing table. You will see the first line which is:
Code:
(myType,myDept,myStatus,myCount,myMonth)=>
which is how the parameters are passed to this function.
In order to be able to see the developing steps I've duplicated the function in a query called
DEVfnFindOutcomes, so if you bring that up in the
PQ Editor instead you'll see all the steps. In fact you'll see more steps because the first 5 are just establishing the parameters/arguments manually.
At first opening you'll see just
Outcome 29 because that's the final step of this query. If you click on any of the first 5 steps (all beginning '
my'…) you'll see the values used (some strings, some numbers) in the formula bar and you can edit them there, although it's not so obvious how to put an empty string in so it's safer to edit them in the first lines of the code manually by going into the
Advanced Editor:
Code:
let
myType="",
myDept="",
myStatus="N/A",
myCount=1,
myMonth=4.109,
This is the sort of thing I did while developing the function.
The first real step after establishing parameter values is the
Source step which just grabs the
Categories table from the
Categories query. The next
ReplacedValue step does something I really should have done in the
Categories query and brings in the value from the
DeptOper column to the
DeptValue column if the
DeptValue column is
null (there's only one row (3) this happens in).
The next 5 steps, all names ending in …'
Filter', filter the table on the 5 parameters, selecting only rows from the table using the built-in function
List.AnyTrue() [the
StatusFilter step is an exception, it was too simple] which works by returning
True if any or more of the elements in the list (in curly brackets{}) is
True.
So in that list I put some tests, and if any of the tests return true, that row is kept. In the
DeptFilter,
CountFilter and
MonthFilter steps I separated each element of the list with a carriage return to help me with the logic.
At the end of these filtering steps I may be left with a completely empty table, a table with one row (the ideal) or a table with several rows.
I remove all the other columns except for the outcomes column (called
Column1) in step
RemovedOtherColumns, convert that into a list in the
Column1 step and finally concatenate that list using
comma-space as a delimiter to create a string, being the output of the custom function.