Migrating from Microsoft’s Power Automate to Make has not been without some notable differences.
The substring() function is one of them.
In PA, the parameters are: substring([string],[start],[count]) where [count] is the number of bytes to return for the substring. This makes it very easy to work with strings of varying lengths. Example: substring(string,indexOf(string,’ 00n’),18)
In Make, the parameters are: substring(text; start; end) where “end” is the end of the string itself, not the substring.
When allowing people to paste a URL or actual record ID into a form to facilitate some sort of automated processing, the latter example requires a bit more manipulation to overcome some end-user behavior. For Example, a user may paste any of the following values into the form field:
“https://company.lightning.force.com/lightning/r/Opportunity/00n5c00001xxxxxxxx/view”
company.lightning.force.com/lightning/r/Opportunity/00n5c00001xxxxxxxx/view
00n5c00001xxxxxxxx
00n5c00001xxxxxxxx/view
Opportunity/00n5c00001xxxxxxxx
Etc. (let’s face it, end users do the strangest things at times)
Since (1) we are only interested in the 18 byte record ID, (2) want to maximize success when the scenario runs, and (3) not aggressively limit what an end-user can paste into the form, we need to be a bit more prescriptive regarding the “end” value by combining the use of length(), substring(), and indexOf().
In my real-world example certain SFDC IDs start with leading zeros, which have to be accounted for a bit differently in Make as well, hence the toString(0)+toString(0), causing things to appear noisier than normal where leading zeros wouldn’t be a factor. Since this is a SFDC example, and all of our opportunity and account IDs begin with zeros, I’ve left them for reference in the event this is also the case for others.
First, we find the location (index) where the desired substring begins: substring(string; indexOf(string; toString(0) + toString(0)n);
Then we evaluate whether some variation of the URL was likely pasted: if(length(string) > 18;
and if so, determine the end of the string value for our requirements by subtracting the remaining bytes after the 18 bytes we need: length(string) - length(substring(string; indexOf(string; toString(0) + toString(0)n) + 18));
ELSE, if the string is 18 bytes (or technically less–see note at the end), the end of the string value is as such: 18))
Put it all together and you get…
substring(string; indexOf(string; toString(0) + toString(0)n); if(length(string) > 18; length(string) - length(substring(string; indexOf(string; toString(0) + toString(0)n) + 18)); 18))
You can test this by creating a new scenario with the first module being a “Compose to String” with any of the end-user examples above to evaluate, and the second “Compose to String” module with the following pasted into the text box:
{{substring(1.value; indexOf(1.value; toString(0) + toString(0)n); if(length(1.value) > 18; length(1.value) - length(substring(1.value; indexOf(1.value; toString(0) + toString(0)n) + 18)); 18))}}
Note: To mitigate complete buffoonery on behalf of the end users, the form in question requires the pasted value to include the specific record’s SFDC 3-byte prefix and be at least 18 bytes long.