Introduction
Hi everyone, welcome to our new blog post. In this blog, we will explore how to convert a Comma-Separated String Conversion to Collection in Salesforce Flow.
In this blog post, we will explore the functionality of a Salesforce Flow called “Generic String Splitter.” The sub-flow splits a string by a separator, converts it into a collection, and returns that collection as output to the main flow that calls it. We will analyze this flow’s different elements, nodes, decisions, and variables to understand its purpose and behavior.
Overview
The purpose of the “Generic String Splitter” flow is to split a string into multiple parts based on a specified separator. This flow can be used for Comma-Separated String Conversion to Collection in Salesforce Flow It serves as a sub-flow that can be integrated into a larger flow for effective management of string-splitting operations.


Flow Variables
Let’s dive into each variable to understand their purpose in the flow –
Text Variables
- varT_StringToSplit: This variable of type String is used as an input to the flow. It represents the string that needs to be split. varT_RemainingText This variable of type String is used to store the remaining text after splitting. It is not an input or output variable.
- varT_InputSeparator: This variable of type String is used as an input to the flow. It the separator used for splitting the text. In this flow, the separator is set to a comma (,).
- varT_SplitText: Similar to varT_RemainingText, this variable of type String stores the split text temporarily during the splitting process.
- SplitResults: This variable of type String serves as the output variable for the flow. It is a collection that stores the split results.
Formula Variables
- forB_CheckTextContainsSeparator: This formula element checks whether varT_StringToSplit contains the sperator or not. CONTAINS({!varT_StringToSplit}, {!varT_InputSeparator})
- forB_ValidateStringToSplit: This formula element checks that the varT_StringToSplit is not blank, not null and has a length greater than 1. NOT(ISBLANK(TRIM({!varT_StringToSplit}))) && NOT(ISNULL(TRIM({!varT_StringToSplit}))) && LEN(TRIM({!varT_StringToSplit})) > 1
- forT_CalculateFirstText: This formula element calculates the first part of the split text. It uses the LEFT function to extract the text from varT_RemainingText before the first occurrence of the separator. The extracted text is then trimmed to remove any leading or trailing spaces. Trim(LEFT({!varT_RemainingText}, FIND({!varT_InputSeparator}, {!varT_RemainingText})-1))
- forT_ReCalculateText: This formula element calculates the remaining text after the first split. It uses the FIND function to locate the first occurrence of the separator within varT_RemainingText and extracts the text to the right of that position. The extracted text is then trimmed to remove any leading or trailing spaces. Trim(right({!varT_RemainingText}, len({!varT_RemainingText})-FIND({!varT_InputSeparator}, {!varT_RemainingText})))
Flows Steps Explanation
Step 1: Validate Input String and Separator
The flow starts with the “Validate Input String and Separator” decision to check, the input string to split and seprator has value and are not null.
Step 2: Check StringToSplit Contains Separator
The flow moves to the “Check StringToSplit Contains Separator” decision. This decision checks whether the “varT_StringToSplit” variable contains the “varT_InputSeparator” value.
Step 3: Assign the Remaining Text
The flow starts with the “Assign Remaining Text” assignment. In this assignment, two variables, “varT_RemainingText” and “varT_SplitText,” are initialized. The value of “varT_RemainingText” is set to the input variable “varT_StringToSplit”. The value of “varT_SplitText” is calculated using a formula expression defined in “forT_CalculateFirstText”. These variables will be used in subsequent steps.
Step 4: Check If the Remaining Text Contains a Separator
The flow moves to the “Check Remaining Text Contains Separator” decision. This decision checks whether the “varT_RemainingText” variable contains the specified separator value. If the condition is met, meaning the separator is found in the remaining text, the flow proceeds to the “Assign Split Text” assignment. Otherwise, it goes to the next decision, “Check Remaining Text”.
Step 5: Assign Split Text
In the “Assign Split Text” assignment, the “varT_RemainingText” and “varT_SplitText” variables are updated. The “varT_RemainingText” variable is assigned the value of “forT_ReCalculateText”, which is a formula expression extracting the text after the separator. The “varT_SplitText” variable remains unchanged. After this assignment, the flow moves to the next decision, “Check Split Text Not Empty”.
Step 6: Check If Split Text Is Not Empty
The “Check Split Text Not Empty” decision verifies if the “varT_SplitText” variable is not empty. If it contains a value, the flow proceeds to the “Add Split Text to Collection” assignment. This assignment adds the value of “varT_SplitText” to a collection variable called “SplitResults”. If the “varT_SplitText” variable is empty, the flow goes back to the “Check Remaining Text Contains Separator” decision.
Step 7: Add Split Text to the Collection
The “Add Split Text to Collection” assignment appends the value of “varT_SplitText” to the “SplitResults” collection using the “Add” operator. This ensures that the split text is stored for further processing. After this assignment, the flow returns to the “Check Remaining Text Contains Separator” decision.
Step 8: Check the Remaining Text
The “Check Remaining Text” decision checks if the “varT_RemainingText” variable is null or empty. If it is not empty, the flow proceeds to the “Add Remaining Text to Collection” assignment. This assignment adds the “varT_RemainingText” to the “SplitResults” collection. If the “varT_RemainingText” variable is empty, the flow moves to the default outcome.
Step 9: Add Remaining Text to the Collection
In the “Add Remaining Text to Collection” assignment, the “varT_RemainingText” variable is added to the “SplitResults” collection using the “Add” operator. This ensures that any remaining text is included in the final collection. The flow then continues to the next assignment, “Assign Remaining Text”.
Step 10: Assign Remaining Text
The “Assign Remaining Text” assignment assigns the value of “forT_ReCalculateText” to the “varT_RemainingText” variable. This step ensures consistency in the variable value. After this assignment, the flow has reached its end.

SUB_CommonLogicForStringSplitter.flow-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>58.0</apiVersion>
<assignments>
<name>Add_remaining_Text_to_Collection</name>
<label>Add remaining Text to Collection</label>
<locationX>578</locationX>
<locationY>782</locationY>
<assignmentItems>
<assignToReference>SplitResults</assignToReference>
<operator>Add</operator>
<value>
<elementReference>varT_RemainingText</elementReference>
</value>
</assignmentItems>
<connector>
<targetReference>Assign_Remaining_Text_X2</targetReference>
</connector>
</assignments>
<assignments>
<name>Add_Split_Text_to_Collection1</name>
<label>Add Split Text to Collection</label>
<locationX>446</locationX>
<locationY>458</locationY>
<assignmentItems>
<assignToReference>SplitResults</assignToReference>
<operator>Add</operator>
<value>
<elementReference>varT_SplitText</elementReference>
</value>
</assignmentItems>
<connector>
<targetReference>Check_Remaining_Text_Contains_Separator</targetReference>
</connector>
</assignments>
<assignments>
<name>Add_Split_Text_to_Collection2</name>
<label>Add Split Text to Collection</label>
<locationX>50</locationX>
<locationY>890</locationY>
<assignmentItems>
<assignToReference>SplitResults</assignToReference>
<operator>Add</operator>
<value>
<elementReference>varT_SplitText</elementReference>
</value>
</assignmentItems>
<connector>
<isGoTo>true</isGoTo>
<targetReference>Check_Remaining_Text_Contains_Separator</targetReference>
</connector>
</assignments>
<assignments>
<name>Assign_Remaining_Text_X1</name>
<label>Assign Remaining Text</label>
<locationX>446</locationX>
<locationY>350</locationY>
<assignmentItems>
<assignToReference>varT_RemainingText</assignToReference>
<operator>Assign</operator>
<value>
<elementReference>varT_StringToSplit</elementReference>
</value>
</assignmentItems>
<assignmentItems>
<assignToReference>varT_SplitText</assignToReference>
<operator>Assign</operator>
<value>
<elementReference>forT_CalculateFirstText</elementReference>
</value>
</assignmentItems>
<connector>
<targetReference>Add_Split_Text_to_Collection1</targetReference>
</connector>
</assignments>
<assignments>
<name>Assign_Remaining_Text_X2</name>
<label>Assign Remaining Text</label>
<locationX>578</locationX>
<locationY>890</locationY>
<assignmentItems>
<assignToReference>varT_RemainingText</assignToReference>
<operator>Assign</operator>
<value>
<elementReference>forT_ReCalculateText</elementReference>
</value>
</assignmentItems>
</assignments>
<assignments>
<name>Assign_Split_Text</name>
<label>Assign Split Text</label>
<locationX>182</locationX>
<locationY>674</locationY>
<assignmentItems>
<assignToReference>varT_RemainingText</assignToReference>
<operator>Assign</operator>
<value>
<elementReference>forT_ReCalculateText</elementReference>
</value>
</assignmentItems>
<assignmentItems>
<assignToReference>varT_SplitText</assignToReference>
<operator>Assign</operator>
<value>
<elementReference>forT_CalculateFirstText</elementReference>
</value>
</assignmentItems>
<connector>
<targetReference>Check_Split_Text_Not_Empty</targetReference>
</connector>
</assignments>
<decisions>
<name>Check_Remaining_Text</name>
<label>Check Remaining Text</label>
<locationX>710</locationX>
<locationY>674</locationY>
<defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
<rules>
<name>Yes_Remaining_Text_Not_Empty</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>varT_RemainingText</leftValueReference>
<operator>IsNull</operator>
<rightValue>
<booleanValue>false</booleanValue>
</rightValue>
</conditions>
<connector>
<targetReference>Add_remaining_Text_to_Collection</targetReference>
</connector>
<label>Yes Remaining Text Not Empty</label>
</rules>
</decisions>
<decisions>
<name>Check_Remaining_Text_Contains_Separator</name>
<label>Check Remaining Text Contains Separator</label>
<locationX>446</locationX>
<locationY>566</locationY>
<defaultConnector>
<targetReference>Check_Remaining_Text</targetReference>
</defaultConnector>
<defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
<rules>
<name>Yes_Contains_Separator</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>varT_RemainingText</leftValueReference>
<operator>Contains</operator>
<rightValue>
<elementReference>varT_InputSeparator</elementReference>
</rightValue>
</conditions>
<connector>
<targetReference>Assign_Split_Text</targetReference>
</connector>
<label>Yes Contains Separator</label>
</rules>
</decisions>
<decisions>
<name>Check_Split_Text_Not_Empty</name>
<label>Check Split Text Not Empty</label>
<locationX>182</locationX>
<locationY>782</locationY>
<defaultConnector>
<isGoTo>true</isGoTo>
<targetReference>Check_Remaining_Text_Contains_Separator</targetReference>
</defaultConnector>
<defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
<rules>
<name>Yes_Split_Text_Not_Empty</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>varT_SplitText</leftValueReference>
<operator>IsNull</operator>
<rightValue>
<booleanValue>false</booleanValue>
</rightValue>
</conditions>
<connector>
<targetReference>Add_Split_Text_to_Collection2</targetReference>
</connector>
<label>Yes Split Text Not Empty</label>
</rules>
</decisions>
<decisions>
<name>Check_StringToSplit_Contains_Separator</name>
<label>Check StringToSplit Contains Separator</label>
<locationX>776</locationX>
<locationY>242</locationY>
<defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
<rules>
<name>Yes</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>forB_CheckTextContainsSeparator</leftValueReference>
<operator>EqualTo</operator>
<rightValue>
<booleanValue>true</booleanValue>
</rightValue>
</conditions>
<connector>
<targetReference>Assign_Remaining_Text_X1</targetReference>
</connector>
<label>Yes</label>
</rules>
</decisions>
<decisions>
<name>Validate_Input_String_and_Separator</name>
<label>Validate Input String and Separator</label>
<locationX>1073</locationX>
<locationY>134</locationY>
<defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
<rules>
<name>Input_String_and_Separator_Validated</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>forB_ValidateStringToSplit</leftValueReference>
<operator>EqualTo</operator>
<rightValue>
<booleanValue>true</booleanValue>
</rightValue>
</conditions>
<conditions>
<leftValueReference>varT_InputSeparator</leftValueReference>
<operator>NotEqualTo</operator>
<rightValue>
<stringValue></stringValue>
</rightValue>
</conditions>
<connector>
<targetReference>Check_StringToSplit_Contains_Separator</targetReference>
</connector>
<label>Input String and Separator Validated</label>
</rules>
</decisions>
<description>This flow is a sub flow, which contains common logic for splitting a string by separator, convert to collection and return that collection as output to main flow, from where its being called.</description>
<environments>Default</environments>
<formulas>
<name>forB_CheckTextContainsSeparator</name>
<dataType>Boolean</dataType>
<expression>CONTAINS({!varT_StringToSplit}, {!varT_InputSeparator})</expression>
</formulas>
<formulas>
<name>forB_ValidateStringToSplit</name>
<dataType>Boolean</dataType>
<expression>NOT(ISBLANK(TRIM({!varT_StringToSplit}))) && NOT(ISNULL(TRIM({!varT_StringToSplit}))) && LEN(TRIM({!varT_StringToSplit})) > 1</expression>
</formulas>
<formulas>
<name>forT_CalculateFirstText</name>
<dataType>String</dataType>
<expression>trim(LEFT({!varT_RemainingText}, FIND({!varT_InputSeparator}, {!varT_RemainingText})-1))</expression>
</formulas>
<formulas>
<name>forT_ReCalculateText</name>
<dataType>String</dataType>
<expression>Trim(right({!varT_RemainingText}, len({!varT_RemainingText})-FIND({!varT_InputSeparator}, {!varT_RemainingText})))</expression>
</formulas>
<interviewLabel>Subflow: Add Timesheet Entry Subflow: Lead Handler {!$Flow.CurrentDateTime}</interviewLabel>
<label>Subflow: Generic String Splitter</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>AutoLaunchedFlow</processType>
<start>
<locationX>947</locationX>
<locationY>0</locationY>
<connector>
<targetReference>Validate_Input_String_and_Separator</targetReference>
</connector>
</start>
<status>Active</status>
<variables>
<name>SplitResults</name>
<dataType>String</dataType>
<isCollection>true</isCollection>
<isInput>false</isInput>
<isOutput>true</isOutput>
</variables>
<variables>
<name>varT_InputSeparator</name>
<dataType>String</dataType>
<isCollection>false</isCollection>
<isInput>true</isInput>
<isOutput>false</isOutput>
</variables>
<variables>
<name>varT_RemainingText</name>
<dataType>String</dataType>
<isCollection>false</isCollection>
<isInput>false</isInput>
<isOutput>false</isOutput>
</variables>
<variables>
<name>varT_SplitText</name>
<dataType>String</dataType>
<isCollection>false</isCollection>
<isInput>false</isInput>
<isOutput>false</isOutput>
</variables>
<variables>
<name>varT_StringToSplit</name>
<dataType>String</dataType>
<isCollection>false</isCollection>
<isInput>true</isInput>
<isOutput>false</isOutput>
</variables>
</Flow>
Note – If you get an error “go to is not a valid property for flow version” while deploying from VS code, change your source version to 58.0 “sourceApiVersion”: “58.0” in sfdx-project.json file.
Conclusion
The “Generic String Splitter” flow provides a reusable solution for splitting strings based on a specified separator within a larger flow. By understanding its nodes, elements, decisions, and variables, we can incorporate this sub-flow into our Salesforce processes and efficiently handle string-splitting operations.


Leave a reply to Mark Cancel reply