0

I would like a formula in excel that does what Text To Columns does. For example the following string in A1

" text with a comma, stays in one column",," keep starting blank text",1,2,3,"123"

Would be split into multiple cells like this... enter image description here

Andy Robertson
  • 171
  • 2
  • 6

1 Answers1

0

The following LET Function allows you to split the text into columns based on the splitter character (in this instance a comma). It ignores commas that are between quotes (the Delim argument - which has double quotes in it). It does this by ensuring there is an even number of quotes before the splitter character.

    =LET(
    NOTES,"Splits a string but also checks to see if the splitter is inside a delimiter. So will ignore a comma inside quotes.",
    RawString,$A1,
    Splitter,",",Note2,"This is the character to split the string by",
    Delim,"""",Note4,"This is the text delimiter it looks odd but it's just a double quote - change to "" if you don't want text delimitation",
    IgnoreBlanks,FALSE,
    CleanTextDelims,TRUE,
    TrimBlanks,FALSE,
    SplitString,Splitter&RawString&Splitter,Note3,"Add the splitter to the start and the end to help create the array of split positions",
    StringLength,LEN(SplitString),
    Seq,SEQUENCE(1,StringLength),Note5,"Get a sequence from 1 to the length of the split string",
    Note6,"The below does the bulk of the work. It works out if we are at an odd or even point in terms of count of text delimiters up to the point in the sequence we are processing.",
    Note7,"if we are at an even point and we have a delimiter then make a note of the sequence otherwise put a blank.",
    PosArray,IF(Seq=StringLength,Seq,IF(MOD(LEN(LEFT(SplitString,Seq))-LEN(SUBSTITUTE(LEFT(SplitString,Seq),Delim,"")),2)=0,IF(MID(SplitString,Seq,1)=Splitter,Seq,""),"")),
    PosArrayClean,FILTER(PosArray,PosArray<>""),Note8,"Clean blanks",
    StartArray,FILTER(PosArrayClean,PosArrayClean<>StringLength),
    EndArray,FILTER(PosArrayClean,PosArrayClean<>1),
    StringArray,MID(SplitString,StartArray+1,EndArray-StartArray-1),
    StringArrayB,IF(IgnoreBlanks,FILTER(StringArray,StringArray<>""),StringArray),
    StringArrayC,IF(CleanTextDelims,IF(LEFT(StringArrayB,1)=Delim,MID(StringArrayB,2,IF(RIGHT(StringArrayB,1)=Delim,LEN(StringArrayB)-2,LEN(StringArrayB))),StringArrayB),StringArrayB),
    IFERROR(IF(TrimBlanks,TRIM(StringArrayC),StringArrayC),"")
    )

Breaking down each step in the LET formula:

  1. Supply the raw string (from cell A1 in this case)
  2. Set the splitter character - in this case a comma
  3. Set the text delimiter - in this case double quotes (looks odd because it has to be as double double quotes - Delim,"""" )
  4. IgnoreBlanks is an option to exclude blank cells in the output
  5. CleanTextDelims will clean the TextDelimiter (Double quotes) from the start and end of the resultant string
  6. Create a SplitString variable with the split character at the front and back.
  7. Get the length of the string for ease of use
  8. Get a sequence from 1 to the length of the string.
  9. Get an array of the position of characters that are splitters with an even number of Text Delimiters to the left of that position in the string the posArray (splitter position array).
  10. Clean the blanks to get the posArrayClean
  11. Create a start and end array (start array ignores the last and end array ignores the first item in the PosArrayClean)
  12. Get the array of strings/cells to output.
  13. If the IgnoreBlanks is used then igore blank cells
  14. If the CleanTextDelims option is set then strip off the Text Delim (double quotes) from the start and end of the resultant string.
  15. If the TrimBlanks option is set then trim blank spaces off the start and end of the resulting strings.

Hopefully the notes explain clearly how this works and make it easy to modify.

If you want create a named Lambda to use you can use the following code to paste into the formula of a named range called SplitStringDelim (you can name it what you like of course). NB You can't have the line separators in this and I stripped the notes out of it.

=LAMBDA(StringRaw,SplitChar,DelimChar,IgnoreBlank,CleanTextDelim,TrimBlank, LET( RawString,StringRaw, Splitter,SplitChar, Delim,DelimChar, IgnoreBlanks,IgnoreBlank, CleanTextDelims,CleanTextDelim, TrimBlanks,TrimBlank, SplitString,Splitter&RawString&Splitter, StringLength,LEN(SplitString), Seq,SEQUENCE(1,StringLength), PosArray,IF(Seq=StringLength,Seq,IF(MOD(LEN(LEFT(SplitString,Seq))-LEN(SUBSTITUTE(LEFT(SplitString,Seq),Delim,"")),2)=0,IF(MID(SplitString,Seq,1)=Splitter,Seq,""),"")), PosArrayClean,FILTER(PosArray,PosArray<>""),Note8,"Clean blanks", StartArray,FILTER(PosArrayClean,PosArrayClean<>StringLength), EndArray,FILTER(PosArrayClean,PosArrayClean<>1), StringArray,MID(SplitString,StartArray+1,EndArray-StartArray-1), StringArrayB,IF(IgnoreBlanks,FILTER(StringArray,StringArray<>""),StringArray), StringArrayC,IF(CleanTextDelims,IF(LEFT(StringArrayB,1)=Delim,MID(StringArrayB,2,IF(RIGHT(StringArrayB,1)=Delim,LEN(StringArrayB)-2,LEN(StringArrayB))),StringArrayB),StringArrayB), IFERROR(IF(TrimBlanks,TRIM(StringArrayC),StringArrayC),"")))
Andy Robertson
  • 171
  • 2
  • 6