Let's POWER Automate

From no-code to low-code

Menu
  • Expressions
  • Filters
  • General
  • Application specific solutions
    • Dataverse
    • Excel
    • Forms
    • Outlook
    • Planner
    • Power Apps
    • SharePoint
    • Teams
  • Triggers
  • Ready to use solutions
    • Approval Process Template
    • Task Delegation App
    • The Ultimate Power Automate expressions cheat sheet
    • Power Automate HTTP requests to SharePoint cheat sheet
    • Power Automate HTTP requests to Graph API cheat sheet
  • ABOUT ME
  • Get help with your flow
  • POWER PLATFORM SERVICES
Menu

Get previous value(s) of SP multiple selection columns in Power Automate

Posted on November 28, 2021March 21, 2022 by Tom

“The previously described solution works fine, but Power Automate returns an error on a multiple selection columns, how can I process them too?”


Some time ago I wrote a blog post on using Power Automate to get the previous values of updated SP columns. However, that solution works only for single selection columns. Once there’s a multiple choice, lookup or people picker column, the solution will end with an error message. The expressions expect a value, but multiple choice fields provide an array. This post is an extension of the previous one in case your SharePoint list has such columns.

Why it doesn’t work

The problem was already explained in previous posts on exporting the multiple choice or multiple people picker columns to csv. If it’s a multiple selection column, it contains an array. And as such you can’t access the values directly. You must somehow deal also with the array. Either take a specific object from the array and its value, or a specific values for each of them. And the latter is what you want to do for the multiple choice columns.

How to recognise multiple selection columns

As described in the post on processing JSON, arrays can be recognised by brackets [ and ]. If the object contains the brackets, it’s an array. And this is a knowledge you can use also in this solution. The old expressions looked for a specific words defining the field type, e.g. FieldLookupValue or SPListExpandedUser.

The same approach can be used also to check if given field type contains an array. If it contains ‘FieldLookupValue’ and ‘[‘ at the same time, it’s a multiple lookup field. If it contains ‘SPListExpandedUser’ and ‘[‘ it’s a multiple people picker. And once you know it’s a multiple selection field, you can process it accordingly. For the old values:

if(contains(string(outputs('Compose')),'FieldLookupValue'),
  if(contains(string(outputs('Compose')),'['),
    <multiple selection lookup>,
    outputs('Compose')?['LookupValue'] = <single selection lookup>
  ),
  if(contains(string(outputs('Compose')),'FieldUserValue'),
    if(contains(string(outputs('Compose')),'['),
        <multiple selection people picker>,
        outputs('Compose')?['LookupValue'] = <single selection people picker>
    ),
    if(contains(string(outputs('Compose')),'String'),
        <multiple selection choice>,
        outputs('Compose') = <all other column types>
    )
  )
)

And for the new values:

if(contains(string(outputs('Compose_2')),'SPListExpandedReference'),
  if(contains(string(outputs('Compose_2')),'['),
    <multiple selection lookup or choice field>,
    outputs('Compose_2')?['Value'] = <single selection lookup>
  ),
  if(contains(string(outputs('Compose_2')),'SPListExpandedUser'),
    if(contains(string(outputs('Compose_2')),'['),
        <multiple selection people picker>,
        outputs('Compose_2')?['DisplayName'] = <single selection people picker>
    ),
    outputs('Compose_2') = <all other column types>
  )
)

What is missing are the expressions for the multiple selection columns.

Multiple selection choice columns

Multiple choice column is the first one, and the easiest one.

To get the original values just convert the [‘results’] array to a string.

join(outputs('Compose')?['Results'],', ')

The updated values can be then extracted with the xpath(…) expression. It’s the same expression that will be used also for the multiple lookup column values.

join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/Value/text()'), ', ')

Adding them to the expressions:

if(contains(string(outputs('Compose')),'FieldLookupValue'),
  if(contains(string(outputs('Compose')),'['),
    <multiple selection lookup>,
    outputs('Compose')?['LookupValue']
  ),
  if(contains(string(outputs('Compose')),'FieldUserValue'),
    if(contains(string(outputs('Compose')),'['),
        <multiple selection people picker>,
        outputs('Compose')?['LookupValue']
    ),
    if(contains(string(outputs('Compose')),'String'),
        join(outputs('Compose')?['Results'],', '),
        outputs('Compose')
    )
  )
)
if(contains(string(outputs('Compose_2')),'SPListExpandedReference'),
  if(contains(string(outputs('Compose_2')),'['),
    join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/Value/text()'), ', '),
    outputs('Compose_2')?['Value']
  ),
  if(contains(string(outputs('Compose_2')),'SPListExpandedUser'),
    if(contains(string(outputs('Compose_2')),'['),
        <multiple selection people picker>,
        outputs('Compose_2')?['DisplayName']
    ),
    outputs('Compose_2')
  )
)

Multiple selection people picker columns

The multiple people picker columns are provided as objects in both situations, therefore, you must use the xpath(…) expression for both.

if(contains(string(outputs('Compose')),'FieldLookupValue'),
  if(contains(string(outputs('Compose')),'['),
    <multiple selection lookup>,
    outputs('Compose')?['LookupValue']
  ),
  if(contains(string(outputs('Compose')),'FieldUserValue'),
    if(contains(string(outputs('Compose')),'['),
        join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose') , '}}'))), '/body/value/results/LookupValue/text()'), ', '),
        outputs('Compose')?['LookupValue']
    ),
    if(contains(string(outputs('Compose')),'String'),
        join(outputs('Compose')?['Results'],', '),
        outputs('Compose')
    )
  )
)
if(contains(string(outputs('Compose_2')),'SPListExpandedReference'),
  if(contains(string(outputs('Compose_2')),'['),
    join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/Value/text()'), ', '),
    outputs('Compose_2')?['Value']
  ),
  if(contains(string(outputs('Compose_2')),'SPListExpandedUser'),
    if(contains(string(outputs('Compose_2')),'['),
        join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/DisplayName/text()'), ', '),
        outputs('Compose_2')?['DisplayName']
    ),
    outputs('Compose_2')
  )
)

Multiple selection lookup columns

As already mentioned above, multiple selection lookup columns are the same as multiple choice columns for the current values. That means, the second expression is already complete, all that’s left is to extract the old values in the first one.

if(contains(string(outputs('Compose')),'FieldLookupValue'),
  if(contains(string(outputs('Compose')),'['),
    join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose') , '}}'))), '/body/value/results/LookupValue/text()'), ', '),
    outputs('Compose')?['LookupValue']
  ),
  if(contains(string(outputs('Compose')),'FieldUserValue'),
    if(contains(string(outputs('Compose')),'['),
        join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose') , '}}'))), '/body/value/results/LookupValue/text()'), ', '),
        outputs('Compose')?['LookupValue']
    ),
    if(contains(string(outputs('Compose')),'String'),
        join(outputs('Compose')?['Results'],', '),
        outputs('Compose')
    )
  )
)
if(contains(string(outputs('Compose_2')),'SPListExpandedReference'),
  if(contains(string(outputs('Compose_2')),'['),
    join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/Value/text()'), ', '),
    outputs('Compose_2')?['Value']
  ),
  if(contains(string(outputs('Compose_2')),'SPListExpandedUser'),
    if(contains(string(outputs('Compose_2')),'['),
        join(xpath(xml(json(concat('{"body":{"value":', outputs('Compose_2') , '}}'))), '/body/value/DisplayName/text()'), ', '),
        outputs('Compose_2')?['DisplayName']
    ),
    outputs('Compose_2')
  )
)

Summary

As you can see, extracting the previous and current values from multiple selection SP columns with Power Automate is not easy. It makes the solution that was quite complex before even more complicated. But if your list contains these multiple selection columns, you don’t have much of a choice. It’s either removing them, or adjusting the flow. And I suppose the second option is the preferred one.


πŸš€ Master Power Automate

Join 2,000+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

9 thoughts on “Get previous value(s) of SP multiple selection columns in Power Automate”

  1. Melissa B. says:
    December 4, 2021 at 1:06 am

    You beautiful, beautiful human. Thank you for posting this, and your previous post. Saved me tons of testing time!

    Reply
  2. Edwin says:
    March 8, 2022 at 6:25 pm

    This has been a HUGE step forward for me. Thank you so much! I have everything working except a certain scenario with the people picker. The final blocks of code for the expressions are the only 2 that will be accepted by Sharepoint. The other blocks are rejected by Sharepoint as bad expressions. When I use the final 2 blocks of code and update single input, multiple choice inputs, or change one set of people for a new set people, it works. However, if there were previously no people and I then add people, it gives the following error:

    Unable to process template language expressions in action ‘Append_to_array_variable’ inputs at line ‘0’ and column ‘0’: ‘The template language expression ‘if(contains(string(outputs(‘Compose_2′)),’SPListExpandedReference’),
    if(contains(string(outputs(‘Compose_2’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose_2’) , ‘}}’))), ‘/body/value/Value/text()’), ‘, ‘),
    outputs(‘Compose_2’)?[‘Value’]
    ),
    if(contains(string(outputs(‘Compose_2′)),’SPListExpandedUser’),
    if(contains(string(outputs(‘Compose’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose_2’) , ‘}}’))), ‘/body/value/DisplayName/text()’), ‘, ‘),
    outputs(‘Compose_2’)?[‘DisplayName’]
    ),
    outputs(‘Compose_2′)
    )
    )’ cannot be evaluated because property ‘DisplayName’ cannot be selected. Array elements can only be selected using an integer index. Please see https://aka.ms/logicexpressions for usage details.’.

    The trigger to the error seems to be going from a blank/null value to the new value. Any advice would be great. As a side note, if there is a way to update this so that blank values say something like “Blank” or “Empty”, that would be great. The email that goes out now says the values “updated from to ” which does not read very well. I have tried to figure this out but not gotten it yet. Much appreciated!

    Reply
    1. Edwin says:
      March 9, 2022 at 11:29 pm

      Low tech fix is I have made the People Picker a required field on the form. So it should never be blank.

      Reply
    2. Tom says:
      March 21, 2022 at 6:04 pm

      Hello Edwin,
      I think I’ve got the expression wrong. It references the ‘Compose 2’ everywhere expect the one place that leads to the error, that one references ‘Compose’. I think it should be ‘Compose_2’ everywhere. If you replace the sole ‘Compose’ with ‘Compose_2’ it should work. I’ll have to update it in the blog post.

      Reply
  3. Charms Dee says:
    July 26, 2023 at 10:00 pm

    I’ve followed the two related articles with no trouble but I’m trying to put the following if statement as stated above into the Expression field and it keeps telling me the expression is invalid:

    if(contains(string(outputs(‘Compose’)),’FieldLookupValue’),
    if(contains(string(outputs(‘Compose’)),'[‘),
    ,
    outputs(‘Compose’)?[‘LookupValue’]
    ),
    if(contains(string(outputs(‘Compose’)),’FieldUserValue’),
    if(contains(string(outputs(‘Compose’)),'[‘),
    ,
    outputs(‘Compose’)?[‘LookupValue’]
    ),
    if(contains(string(outputs(‘Compose’)),’String’),
    join(outputs(‘Compose’)?[‘Results’],’, ‘),
    outputs(‘Compose’)
    )
    )

    What am I missing?

    Reply
    1. Tom says:
      August 13, 2023 at 9:33 pm

      Hello Charms,
      from the quick look you’ve got a few times 2 commas one after another where a ifYes branch of the condition should be. Also a closing bracket is missing at the end.
      I’d recommend downloading some code editor, e.g. Visual Studio Code and place the expression inside, it’ll show you the brackets and you can use it also to add some spaces to see the whole expression better structured.

      Reply
  4. DannyDicaprio says:
    May 1, 2024 at 11:57 am

    Hi, thanks for this wonderful Knowledge!
    it’s really amazing.

    I have an issue with the formula, I have a person type column in my SharePoint list.
    I have applied the last formula which u have shared in this article, for the rest of the formulas it is showing some error.

    I am able to get the current version details for the person type column, but for the previous version details it is showing as blank.

    Below is the formula which I have used for the two compose?

    if(contains(string(outputs(‘Compose’)),’FieldLookupValue’),
    if(contains(string(outputs(‘Compose’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose’) , ‘}}’))), ‘/body/value/results/LookupValue/text()’), ‘, ‘),
    outputs(‘Compose’)?[‘LookupValue’]
    ),
    if(contains(string(outputs(‘Compose’)),’FieldUserValue’),
    if(contains(string(outputs(‘Compose’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose’) , ‘}}’))), ‘/body/value/results/LookupValue/text()’), ‘, ‘),
    outputs(‘Compose’)?[‘LookupValue’]
    ),
    if(contains(string(outputs(‘Compose’)),’String’),
    join(outputs(‘Compose’)?[‘Results’],’, ‘),
    outputs(‘Compose’)
    )
    )
    )

    if(contains(string(outputs(‘Compose_2′)),’SPListExpandedReference’),
    if(contains(string(outputs(‘Compose_2’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose_2’) , ‘}}’))), ‘/body/value/Value/text()’), ‘, ‘),
    outputs(‘Compose_2’)?[‘Value’]
    ),
    if(contains(string(outputs(‘Compose_2′)),’SPListExpandedUser’),
    if(contains(string(outputs(‘Compose_2’)),'[‘),
    join(xpath(xml(json(concat(‘{“body”:{“value”:’, outputs(‘Compose_2’) , ‘}}’))), ‘/body/value/DisplayName/text()’), ‘, ‘),
    outputs(‘Compose_2’)?[‘DisplayName’]
    ),
    outputs(‘Compose_2’)
    )
    )

    Could u please help me to figure out, what would be the cause for not getting those details from the SharePoint list for the previous version person type column details?

    Reply
  5. SANDEEP SINGH says:
    September 30, 2024 at 10:50 pm

    Hi Tom
    My flow works perfectly from start to till SEND HTTP REQUEST PART but in htp request output i can not see the current values in body’s metadata code
    output of Get Changes for item or file (properties only ) is also correct as it shows current version and old version but in HTTP output i can not see the current updated values

    Reply
  6. Cody says:
    October 16, 2024 at 11:13 pm

    I have a add on question. I have successfully got the changes. I added to post to workflows chat in teams. it seems something is triggering “modified” every second. How do i filter out modify?

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

πŸš€ Master Power Automate

Join 2,000+ professionals getting actionable Power Automate tutorials, solutions, cheat sheets & tips every week.

No spam. Unsubscribe anytime.

Working on an Approval process?

Use the Approval Process Template and the Task Delegation App to skip the hard part and deploy a fully functional approval solution on a SharePoint list in minutes! And then the next one, and the next one...

Approval Template Preview ✨ Learn more ✨

Turn ideas into flows with ease!

Grab the complete Power Automate Cheat Sheet Bundleβ€”everything you need to master expressions, SharePoint HTTP calls, and Graph API in Power Automate.

Cheat Sheet Bundle Preview ✨ Get the Cheat Sheets

Didn't find what you were looking for?
Need to adjust a solution to fit your needs?
Or would you just like to get an assistance from somebody with thousands of hours of experience with Power Automate?

Power Automate blogs worth visiting

Damien Bird
Dennis (Expiscornovus)
Paul Murana

©2025 Let's POWER Automate | Theme by SuperbThemes