With a tiny bit of help from Salesforce explaining the procedure, I finally have a resolution. I'll document my procedure here.
I've created this sample flow which simply increments the start date for all contracts in the system by one day:
And we have our loop:
Procedure
Within the .flow definition file (XML), which we'll extract later, we need to create a variable. The easiest way is to actually create the variable within the flow before we start working on the XML. This will save us doing it in XML and prevent us from making mistakes:
Once you've created your loop variable(s), save the flow and activate it.
Next create a file on your computer called package.xml
and fill it with the following data:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>AAADummyFlow</members>
<name>Flow</name>
</types>
<version>48.0</version>
</Package>
Note: Replace AAADummyFlow with the API name of your flow.
Now head on over to https://workbench.developerforce.com/ and login. This isn't an official Salesforce product, but it seems to be the de facto standard for accessign the Metadata API within the community.
Once you're logged in, navigate to over to Migration > Retrieve. Select your package.xml
as the "unpackaged manifest" and then check the "Single package" box:
Click "Next" and then on the next page select "Retrieve". After a while, you'll have the option to "Download ZIP File". Select this.
Download the zip file and extract it somewhere. Your directory should now look like this:
Navigate into the "flows" folder and open your .flow file in your favourite XML-capable editor. Now we want to search for <loops>
. There will be a loops
entry for each of your loop blocks.
So I'll find the one with <name>Loop_contracts</name>
to match the loop block I created. Just under <locationY>....</locationY>
we want to reference the loop variable we created, so we'll add this line:
<assignNextValueToReference>ContractLoopItem</assignNextValueToReference>
Replace ContractLoopItem
with whatever you named your loop variable in the previous step. You should now have something a little bit like this:
We're not quite done yet. We now need to find references to Loop_contracts
and replace them with ContractLoopItem
. Note that we should only do this for references. We should not update any <connector>
references because these are links to the loop block, as opposed to the loop items. So in mine, I have an assignToReference
that needs updatingm, and an inputReference
that needs updating. We'll replace the Loop_contracts
value within these with ContractLoopItem
:
Now that we've found and replaced all the instances of the loop items, save the file and zip it all back up:
Now head back to Workbench and go to Migration > Deploy. Select the file you just edited, and then check "Rollback on Error" and "Single Package". I recommend deploying this back to your sandbox org first. If you're deploying direct to production, be sure to set test level to something other than "NoTestRun":
Click "Next" and then click "Deploy". If all has gone well you should see Status: Succeded.
Now go back to Flows on Salesforce and you can see we have a third version of our flow now:
We can also wee that the loop now references our variable:
Notes
- In my own flows I had problems with output variables from subflows. I did not have them assigned to variables, instead letting Salesforce take care of that automatically. This caused problems with things referencing them treating them as if they didn't exist. To solve this I simply explicitly assigned the values to variables.
I highly recommend checking every block that uses the loop item to ensure that everything has been assigned properly. Be sure you test your updated flow before you deploy it to production.
I read somewhere that Mac adds extra things to zip files, which could lead to a message stating that package.xml can't be found. I also found that not selecting "Single Package" led to this.
I hope this helps!