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:
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"?>
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:
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
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:
- 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!