I think the UDF is in many ways superior having Unicode support, and that ProgAndy is an awesome programmer. The following csv data taken from
returns 4 rows when it should return 5 rows. It also seems to return an extra column, I'm not sure if that is intentional.
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""","",5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00
Func _ParseCSV
($sFile, $sDelimiters=',;', $sQuote='"', $iFormat=0)
Local Static $aEncoding[6] = [0, 0, 32, 64, 128, 256]
If $iFormat < -1 Or $iFormat > 6 Then
Return SetError(3,0,0)
ElseIf $iFormat > -1 Then
Local $hFile = FileOpen($sFile, $aEncoding[$iFormat]), $sLine, $aTemp, $aCSV[1], $iReserved, $iCount
If @error Then Return SetError(1,@error,0)
$sFile = FileRead($hFile)
FileClose($hFile)
EndIf
If $sDelimiters = "" Or IsKeyword($sDelimiters) Then $sDelimiters = ',;'
If $sQuote = "" Or IsKeyword($sQuote) Then $sQuote = '"'
$sQuote = StringLeft($sQuote, 1)
Local $srDelimiters = StringRegExpReplace($sDelimiters, '[^-[]]', '0')
Local $srQuote = StringRegExpReplace($sQuote, '[^-[]]', '0')
Local $sPattern = StringReplace(StringReplace('(?m)(?:^|[,])h*(["](?:[^"]|["]{2})*["]|[^,rn]*)(v+)?',',', $srDelimiters, 0, 1),'"', $srQuote, 0, 1)
Local $aREgex = StringRegExp($sFile, $sPattern, 3)
If @error Then Return SetError(2,@error,0)
$sFile = '' ; save memory
Local $iBound = UBound($aREgex), $iIndex=0, $iSubBound = 1, $iSub = 0
Local $aResult[$iBound][$iSubBound], $fAdded = False
For $i = 0 To $iBound-1
Select
Case StringLen($aREgex[$i])<3 And StringInStr(@CRLF, $aREgex[$i])
$fAdded = False
$iIndex += 1
$iSub = 0
ContinueLoop
Case StringLeft(StringStripWS($aREgex[$i], 1),1)=$sQuote
$fAdded = True
$aREgex[$i] = StringStripWS($aREgex[$i], 3)
$aResult[$iIndex][$iSub] = StringReplace(StringMid($aREgex[$i], 2, StringLen($aREgex[$i])-2), $sQuote&$sQuote, $sQuote, 0, 1)
Case Else
$fAdded = True
$aResult[$iIndex][$iSub] = $aREgex[$i]
EndSelect
$aREgex[$i]=0 ; save memory
$iSub += 1
If $iSub = $iSubBound Then
$iSubBound += 1
ReDim $aResult[$iBound][$iSubBound]
EndIf
Next
If $iIndex = 0 Then $iIndex=1
ReDim $aResult[$iIndex+$fAdded][$iSubBound]
Return $aResult
EndFunc