DECLARE SUB MyStringsGChChSplitString (StringI AS STRING, ChSeparator1I AS STRING, ChSeparator2I AS STRING)
DECLARE SUB MyStringsGChSplitString (StringI AS STRING, ChSeparatorI AS STRING)
DECLARE FUNCTION MyStringsGJoin$ (SeparatorI AS STRING)
DECLARE SUB MyStringsGREDIMPRESERVE (NewUBoundI AS INTEGER)
DECLARE FUNCTION MyStringsGUBOUND% ()

   '----- MyStringsGChSplitString_TEST
   REDIM SHARED MyStringsG$(0)
   DIM iG


   MyStringsGChChSplitString "", ",", "|"
   FOR iG = 0 TO UBOUND(MyStringsG$)
      IF iG > 0 THEN PRINT ";";
      PRINT MyStringsG$(iG);
   NEXT
   PRINT "<== ("; UBOUND(MyStringsG$); " fields )"

   MyStringsGChChSplitString ",", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"

   MyStringsGChChSplitString ",,", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "Red,Green,Blue", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"
   PRINT


   '---------------


   MyStringsGChChSplitString "a", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a,b", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a,b,c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString ",b,c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a,,c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a,b,", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"

   '---------------
   '---------------


   MyStringsGChChSplitString "", ",", "|"
   FOR iG = 0 TO UBOUND(MyStringsG$)
      IF iG > 0 THEN PRINT ";";
      PRINT MyStringsG$(iG);
   NEXT
   PRINT "<== ("; UBOUND(MyStringsG$); " fields )"

   MyStringsGChChSplitString "|", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"

   MyStringsGChChSplitString "||", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "Red|Green|Blue", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"
   PRINT


   '---------------


   MyStringsGChChSplitString "a", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a|b", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a|b|c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "|b|c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a||c", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"


   MyStringsGChChSplitString "a|b|", ",", "|"
   PRINT MyStringsGJoin$(";"); "<== ("; MyStringsGUBOUND% + 1; " fields )"

'
'------------------------------------------------------------------------------
' This program toolbox
'------------------------------------------------------------------------------
'
'
'---------------
' MyStringsG$ (Array of String) routines
'---------------
' MyStringsGChChSplitString
'---------------
'
'===== MyStringsGChChSplitString
'
SUB MyStringsGChChSplitString (StringI AS STRING, ChSeparator1I AS STRING, ChSeparator2I AS STRING)
   DIM StringL  AS STRING

   DIM FldCountL AS INTEGER

   DIM PosSep1L  AS LONG
   DIM PosSep2L  AS LONG
   DIM PosSepL  AS LONG
   DIM iStringL  AS STRING

   REDIM MyStringsG$(0)
   FldCountL = 0

   StringL = StringI

   '----- LOOP , Search each field
   WHILE StringL <> ""

      '----- Choose between ChSeparator1 and ChSeparator2
      PosSep1L = INSTR(StringL, ChSeparator1I)
      PosSep2L = INSTR(StringL, ChSeparator2I)
      IF PosSep2L = 0 THEN
         PosSepL = PosSep1L
      ELSE
         IF PosSep1L = 0 THEN
            PosSepL = PosSep2L
         ELSE
            IF PosSep1L < PosSep2L THEN PosSepL = PosSep1L ELSE PosSepL = PosSep2L
         END IF
      END IF

      IF PosSepL > 0 THEN
         '----- Add field
         iStringL = MID$(StringL, 1, PosSepL - 1)
         FldCountL = FldCountL + 1
         MyStringsGREDIMPRESERVE (FldCountL - 1)
         MyStringsG$(FldCountL - 1) = iStringL

         '----- Prepare next search
         StringL = MID$(StringL, PosSepL + 1)
      ELSE
         '----- Add field
         FldCountL = FldCountL + 1
         MyStringsGREDIMPRESERVE (FldCountL - 1)
         MyStringsG$(FldCountL - 1) = StringL

         StringL = ""
      END IF
   WEND

   '----- One more at the end...
   IF StringI <> "" THEN
      IF (MID$(StringI, LEN(StringI), 1) = ChSeparator1I) OR (MID$(StringI, LEN(StringI), 1) = ChSeparator2I) THEN
         FldCountL = FldCountL + 1
         MyStringsGREDIMPRESERVE (FldCountL - 1)
         MyStringsG$(FldCountL - 1) = ""
      END IF
   END IF
END SUB

'
'------------------------------------------------------------------------------
' Small toolbox
'------------------------------------------------------------------------------
'
'
'---------------
' MyStringsG$ (Array of String) routines
'---------------
' MyStringsGJoin$
' MyStringsGREDIMPRESERVE
' MyStringsGUBOUND%
'---------------
'
'===== MyStringsGJoin$
'
FUNCTION MyStringsGJoin$ (SeparatorI AS STRING)
   DIM ResultL AS STRING
   DIM iL AS INTEGER

   ResultL = ""

   '----- LOOP , Concat items
   FOR iL = 0 TO UBOUND(MyStringsG$)
      IF iL > 0 THEN ResultL = ResultL + SeparatorI
      ResultL = ResultL + MyStringsG$(iL)
   NEXT

   MyStringsGJoin$ = ResultL
END FUNCTION

'
'===== MyStringsGREDIMPRESERVE
'
SUB MyStringsGREDIMPRESERVE (NewUBoundI AS INTEGER)
   REDIM SAVEArrayL$(0)
   DIM iL AS INTEGER

   IF NewUBoundI = -1 THEN
      REDIM MyStringsG$(0)
      MyStringsG$(0) = ""
      EXIT SUB
   END IF

   '----- Save current array values
   IF NewUBoundI < UBOUND(MyStringsG$) THEN
      REDIM SAVEArrayL$(NewUBoundI)
   ELSE
      REDIM SAVEArrayL$(UBOUND(MyStringsG$))
   END IF
   FOR iL = 0 TO UBOUND(SAVEArrayL$)
      SAVEArrayL$(iL) = MyStringsG$(iL)
   NEXT

   REDIM MyStringsG$(NewUBoundI)

   '----- Restore previously saved values
   FOR iL = 0 TO UBOUND(SAVEArrayL$)
      MyStringsG$(iL) = SAVEArrayL$(iL)
   NEXT
END SUB

'
'===== MyStringsGUBOUND%
'
FUNCTION MyStringsGUBOUND%
   IF UBOUND(MyStringsG$) = 0 THEN
      IF MyStringsG$(0) = "" THEN
         MyStringsGUBOUND% = -1
         EXIT FUNCTION
      END IF
   END IF

   MyStringsGUBOUND% = UBOUND(MyStringsG$)
END FUNCTION
