Public Function Merri_QuoteSplit1(ByRef Expression As String, Optional ByRef Delimiter As String = " ", Optional ByVal Compare As VbCompareMethod = vbBinaryCompare) As String()
Const QUOTE As String = """"
Static lngEnd() As Long, lngEndUB As Long
Dim strOut() As String
Dim lngPosQ As Long, lngPosQE As Long, lngPos As Long, lngCount As Long
Dim blnInQuote As Boolean, lngLen As Long
' remember delimiter length
lngLen = Len(Delimiter)
' error detection
If (lngLen = 0) Or (LenB(Expression) < LenB(Delimiter)) Then
ReDim strOut(0)
strOut(0) = Expression
Merri_QuoteSplit1 = strOut
Exit Function
End If
' see if any quotes
lngPosQ = InStr(Expression, QUOTE)
' no quotes? use Split!
If lngPosQ < 1 Then
Merri_QuoteSplit1 = Split(Expression, Delimiter, , Compare)
Exit Function
Else
' ending quote
lngPosQE = InStr(lngPosQ + 1, Expression, QUOTE)
End If
' see if any delimeters
lngPos = InStr(1, Expression, Delimiter, Compare)
If lngPosQE > 0 And lngPos > lngPosQ Then
lngPos = InStr(lngPosQE + 1, Expression, Delimiter, Compare)
End If
' no delimeter or all quoted? get out!
If lngPos < 1 Or (lngPosQE <= 0 And lngPosQ < lngPos) Then
ReDim strOut(0)
strOut(0) = Expression
Merri_QuoteSplit1 = strOut
Exit Function
End If
' reserve space if first time run
If lngEndUB = 0 Then lngEndUB = 40: ReDim lngEnd(lngEndUB)
' then start off collecting indexes
Do Until lngPos < 1
' need more space?
If lngEndUB < lngCount Then
lngEndUB = lngEndUB * 2
ReDim Preserve lngEnd(lngEndUB)
End If
' check if found within a quote
blnInQuote = (lngPosQ < lngPos)
If blnInQuote And (lngPos < lngPosQE) Then
' find next quote
lngPosQ = InStr(lngPosQE + 1, Expression, QUOTE)
' found a next quote?
If lngPosQ > 0 Then
lngPosQE = InStr(lngPosQ + 1, Expression, QUOTE)
If lngPosQE <= 0 Then
' all remaining are belong to us
Exit Do
Else
lngPos = InStr(lngPosQE + 1, Expression, Delimiter, Compare)
End If
Else
' nope, there are no more quotes to worry about
lngPos = InStr(lngPosQE + 1, Expression, Delimiter, Compare)
lngPosQE = lngPosQ
Exit Do
End If
Else
' remember
lngEnd(lngCount) = lngPos + lngLen - 1
' jump to next
lngCount = lngCount + 1
' find next quote
lngPosQ = InStr(lngPos + lngLen, Expression, QUOTE)
' look for next ending quote
If lngPosQ > 0 Then
lngPosQE = InStr(lngPosQ + 1, Expression, QUOTE)
If lngPosQE > 0 Then
' find next delimiter
lngPos = InStr(lngPosQE + 1, Expression, Delimiter, Compare)
Else
' all remaining are belong to us
Exit Do
End If
Else
' find next delimiter
lngPos = InStr(lngPos + lngLen, Expression, Delimiter, Compare)
' huh, no quote found? we go out!
Exit Do
End If
End If
Loop
' see if we do unquoted work
If (lngPosQ < 1) And (lngPos > 0) Then
' no quotes remaining, so we can work like this
Do Until lngPos < 1
' need more space?
If lngEndUB < lngCount Then
lngEndUB = lngEndUB * 2
ReDim Preserve lngEnd(lngEndUB)
End If
' remember
lngEnd(lngCount) = lngPos + lngLen - 1
' jump to next
lngCount = lngCount + 1
' find next
lngPos = InStr(lngPos + lngLen, Expression, Delimiter, Compare)
Loop
End If
' need more space?
If lngEndUB < lngCount Then
lngEndUB = lngEndUB * 2
ReDim Preserve lngEnd(lngEndUB)
End If
' add end of string
lngEnd(lngCount) = Len(Expression) + lngLen
' reserve space for strings
ReDim Preserve strOut(lngCount)
' get first item
strOut(0) = Left$(Expression, lngEnd(0) - lngLen)
' get remaining items
For lngPos = 1 To lngCount
' clip the one we need
strOut(lngPos) = Mid$(Expression, lngEnd(lngPos - 1) + 1, lngEnd(lngPos) - lngEnd(lngPos - 1) - lngLen)
Next lngPos
' oh my god, we are done!
Merri_QuoteSplit1 = strOut
End Function