May 6, 2024

Diff Check with PowerFx

“How dare you move my cheese!”

I’ve been working on an app that deals with word processing functions in Dynamics and Dataverse, amongst other things. I was given requirements related to being able to tell the difference between changes in a text field. In my head, I thought of it as a “Who moved my cheese?” ask, meaning people wanted to see who changed their previous edits. It’s a reasonable ask for sure, I just like to make jokes constantly and then laugh at my own jokes to entertain myself through the day.

At first this seemed ok, but then I actually started developing and realized I had my work cut out for me. Not so funny!

Getting Edit History

If you have audit history turned on, then Audit History will be tracked in the Audits table. Seems straightforward. If you run Power Automate against that table, you will quickly realize that it has what you need with one big caveat: the actual changes are listed in nested json stored as text.

So Step 1 was to make a flow to parse that out. After much experimentation, I ended up replacing the changedAttributes nested object definition and making it an array. Once that was done, I had changes in a format that could be looped and passed back to Power Apps.

Making a Diff Check

After getting the data back from Power Automate, I put the response into a collection and wrote PowerFx to loop through the Old Value and New Value. Splitting these by each character and then using some conditionally concat trickery allowed me to use highlighting and strike through.

I posted on LinkedIn a quick GIF of the functionality: Click to see it.

Here is the PowerFx code that made this whole thing work:

// Split the old value into an array by each character
ClearCollect(colOld, Split(PlainText(ThisItem.OldValue),””));

// Split the new value into an array by each character
ClearCollect(colNew, Split(PlainText(ThisItem.NewValue),””));

// Get counts of each array
UpdateContext({varCountOld: CountRows(colOld)});
UpdateContext({varCountNew: CountRows(colNew)});

// Collect the differences
ClearCollect(colDiffs,

// Loop through a sequence from 1 to the end of the new text collection
ForAll(Sequence(varCountNew,1,1) As Ind,
{
Diff:
If(
varCountOld>varCountNew,
If(
// Here I am making sure I don’t get an index out of bounds error if old is longer than new
// then I am checking whether the values at each position are not equal
Index(FirstN(colOld, varCountNew),Ind.Value).Value <> Index(colNew, Ind.Value).Value,
// If they are not equal, highlight it
$”<mark>{Index(colNew, Ind.Value).Value}</mark>”,
// Otherwise don’t highlight it
Index(colNew, Ind.Value).Value
),
varCountOld<=varCountNew,
If(
// Make sure you don’t go over the old value array count
Ind.Value <= varCountOld,
If(
// Same logic as above, if they are not equal highlight it
Index(colOld,Ind.Value).Value <> Index(colNew, Ind.Value).Value,
$”<mark>{Index(colNew, Ind.Value).Value}</mark>”,
Index(colNew, Ind.Value).Value
),
// If the new array count is greater than the old, then that is new text and highlight it
If(
Ind.Value > varCountOld,
$”<mark>{Index(colNew, Ind.Value).Value}</mark>”,
Index(colNew, Ind.Value).Value
)
)
)

}
));

If(
// If the old text is shorter than new (or equal), then just concat the diff collection
varCountOld <= varCountNew,
UpdateContext(
{
varDiffChanges: Concat(colDiffs,Diff & “”)
}
),
// If the old text is longer than new, then concat the diff collection and append and highlight the additional text
UpdateContext(
{
varDiffChanges: Concat(colDiffs,Diff & “”) & Concat(LastN(colOld, varCountOld-varCountNew),$”<mark><s>{Value}</s></mark>”)
}
)
);

Takeaways

Honestly, doing a lot of weird Power Query projects and Power BI visual development probably helped me out a lot with this one. Splitting by each character and doing some visual hacking was something that came up with SVGs.

It was cool to figure this much out. Hopefully I can figure out more stuff with more dev work.

You may also like