Converting Comma-Separated or any separator String to a String Collection In Salesforce Flow Utilizing the Generic String Splitter Flow for Enhanced Data Handling

Converting Comma-Separated or any separator String to a String Collection In Salesforce Flow: Utilizing the Generic String Splitter Flow for Enhanced Data Handling

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.

Subflow: Generic String Splitter

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}))) &amp;&amp; NOT(ISNULL(TRIM({!varT_StringToSplit}))) &amp;&amp; LEN(TRIM({!varT_StringToSplit})) &gt; 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.  

5 responses to “Converting Comma-Separated or any separator String to a String Collection In Salesforce Flow: Utilizing the Generic String Splitter Flow for Enhanced Data Handling”

  1. to return the Nth element of the Collection, set up a subflow with Inputs for the Collection and a Number and an Output variable.
    Set a Counter at 1 then loop through the Collection.
    Use a Decision Element to check if the Counter equals the Number,
    if true, assign the “current item from loop” to the Output variable and End
    Outside of the decision element, use a formula to increment the Counter (Counter + 1)
    This flow will iterate through each element until the Counter reaches the specified Number then return the nth element of the Collection.

    Like

  2. First of all, thanks for showing us the code. It is nicely made. I would make one suggestion, though,
    If you parse a string that does not contain the delimiter, you would get a collection that looks like [,’something’] simply because you assign the split before you check to see, if the string itself contains the delimiter.
    So if you move the Assignment “Add Split Text to Collection” to after the “Check Remaining Text”, then you account for the possibility, that the input string might not have a comma-delimiter and return a collection of just one anyway.
    Otherwise, a check on contains delimiter must be made before calling the subflow.

    Like

    1. Thanks for your suggestion thomas, I have updated the flow including some more validation check.

      Like

  3. Very nicely done! Is it ok to use this flow in my project work. Is there any copyright requirements. Please advise.

    Like

    1. Hi, you can use this flow for your requirement. there is no copyright.

      Like

Leave a reply to Bala Cancel reply