Replace Row Values Conditionally in Power Query, M
Replace Row Values Conditionally in Power Query, M
DID YOU
KNOW?
Introduction
In Today's Menu we will explore a more uncommon task: conditionally
replacing multiple row values conditionally. A follow-up question to a
challenge posted by Tanya McIlravy, to provide the ability to modify
entries based on specified business rules. Here's our sample dataset:
let
Source = Table.FromRows(
{
{"46828", "MDK24", "", ""},
{"46403", "", "", ""},
{"24359", "DND24", "", ""},
{"18791", "MDK24", "", ""},
{"13093", "MDK24", "", ""},
{"10073", "", "", ""},
{"45397", "LTA24", "", ""},
{"24982", "LTA24", "", ""},
{"10987", "DND24", "", ""},
{"32311", "", "", ""}
}, type table
[RECORD_ID=text, ACTION=text, VALUE1=text, VALUE2=text]
)
in
Source
Multiple Value Replacements on a Row
There is a lot of good content out there on replacing multiple values.
Simply put, that involves replacing A with B in one or more columns.
Extremely useful to combat inconsistencies, errors, and missing values.
If the string in the ACTION column StartsWith this text, row values in the:
ACTION, VALUE1 and VALUE2 fields have to be replaced.
Preparation: Buffering Lists for Lookups
Based on the replValues table we can create lists for both StartsWith
and Replacement columns, buffer them into memory using List.Buffer.
Buffering is a performance optimization to prevent Power Query from
re-evaluating these lists each time they're accessed.
An iterations list is created which contains all index positions, this gives
us a way to loop through each of the specified replacement rules.
Replacer = Table.FromRecords(
List.Accumulate(
iterations,
Table.ToRecords(Source),
(s, a)=> List.Transform( s, each
if Text.StartsWith( _[ACTION], lookFor{a} )
then _ & replWith{a}
else _
)
)
)
Conclusion
This method enables you to dynamically search for, and replace parts of
the dataset based on specified business rules and requirements.
In our example the condition depended on the starting text of a specific
field. We leveraged lists, and the record merge to overwrite likenamed
fields from the left operand with the right, updating them all.