#100724 - 2003-05-05 10:37 PM
KixGolf Suggestion
|
New Mexico Mark
Hey THIS is FUN
  
Registered: 2002-01-03
Posts: 223
Loc: Columbia, SC
|
There are many flavors of CSV. Most are just subsets of the de facto standard. I would love to see one or two UDF's that could handle reading/writing a file in CSV format (or subset, so long as none of the rules were violated). I'm assuming that:
1. To write, the UDF would accept a filespec or open file object and 2D array of values to write in CSV format.
2. To read, the UDF would accept a filespec or open file object and return a 2D array of values.
Here is the best summary I've personally seen on CSV.
http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
I've started something like this more than once, but the logic is a little dizzying. However, I'm sure many of the intrepid coders on this board could knock something like this out in a day or so.
NMM
|
|
Top
|
|
|
|
#100727 - 2003-05-06 04:23 AM
Re: KixGolf Suggestion
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
this might be a deal breaker for kix...
quote:
Each record is one line ...but A record separator may consist of a line feed (ASCII/LF=0x0A), or a carriage return and line feed pair (ASCII/CRLF=0x0D 0x0A). ...but: fields may contain embedded line-breaks (see below) so a record may span more than one line.
kix's native own file reading commands may come up short in being able to read a entry that covers multiple lines...
only way around this that i can think of right now, is if you enter into the CSV reading UDF knowing the total number of data fields before hand, or if your CSV file always has a header line.
|
|
Top
|
|
|
|
#100728 - 2003-05-06 04:37 AM
Re: KixGolf Suggestion
|
Howard Bullock
KiX Supporter
   
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Then the challenge is more interesting...isn't it? [ 06. May 2003, 04:37: Message edited by: Howard Bullock ]
|
|
Top
|
|
|
|
#100730 - 2003-05-07 12:21 AM
Re: KixGolf Suggestion
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
quote: Later in the article a demo of this multiline is displayed. In the first and last line, notice the single "...
The problem is that KiXtart (with ReadLine() at least) will interpret both 0x0A and 0x0D 0x0A as line terminators.
This means that when you come to reconstruct the data, you don't known which characters to join the field parts back together with.
You would need to use the FSO calls or similar, to get the binary data.
While in practice you may not care what the embedded line termination characters were, you cannot contstruct a valid general CSV parser without handling them.
You could kludge it by counting the number of characters read and comparing to the file length. Where the record line terminators and embedded line terminators are the same characters you can calculate the number of characters missing and determine which line termination characters were used.
Where the embedded line termination is different from the record line termination you may still be able to calculate which to use based on the number of lines read, however there will be occasions when it is impossible to determine (number of record line terminators = number of embedded line terminators).
|
|
Top
|
|
|
|
#100732 - 2003-05-06 02:17 PM
Re: KixGolf Suggestion
|
Howard Bullock
KiX Supporter
   
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Richard, shame on you for giving away the solution. ![[Wink]](images/icons/wink.gif) [ 06. May 2003, 14:18: Message edited by: Howard Bullock ]
|
|
Top
|
|
|
|
#100739 - 2003-05-07 11:28 PM
Re: KixGolf Suggestion
|
kholm
Korg Regular
   
Registered: 2000-06-19
Posts: 714
Loc: Randers, Denmark
|
Mark,
Here is a clean KiX code example for reading the CSV-file into a 2D Array.
The errorchecking is not fully made, but the code is functioning. (KiX 4.20/4.21 RC2)
Sorry, I can't keep the Golf score under 100 lines
code:
Break On $RC = SetOption(Explicit,On) Dim $File,$CsvArr $File = @CurDir + '\csvtest.txt' $CsvArr = CsvArray($File) If @Error = 0 CsvShow($CsvArr) ; Display array on screen EndIf Return ; ********** Convert a CSV - file to 2D array ********** Function CsvArray($File) Dim $Rec,$Row,$NumFields,$Handle,$i $Handle = FreeFileHandle() If $Handle $RC = Open($Handle,$File) Else Exit 9 ; No free filehandles EndIf ; Read first record, and determine number of fields $Rec = ReadRec($Handle) If @Error Exit 1 ; File not found or empty EndIf $NumFields = UBound($Rec) ReDim $CsvArray[$NumFields,0] $Row = 0 For $i = 0 To $NumFields $CsvArray[$i,0] = $Rec[$i] Next ; Read the rest of records in the file Do $Rec = ReadRec(1) ; Read next record If Not @Error If UBound($Rec) <> $NumFields Exit 2 ; Error in CSV-file, wrong number of fields in a record EndIf $Row = $Row + 1 ReDim Preserve $CsvArray[$NumFields,$Row] For $i = 0 To $NumFields $CsvArray[$i,$Row] = $Rec[$i] Next EndIf Until @Error $RC = Close($Handle) EndFunction ; Supportfunction for CsvArray() - Read a record from the CSV-file Function ReadRec($Handle) Dim $Line,$Tmp,$Start,$End,$i $Line = ReadLine($Handle) If @Error = 0 $Line = Join(Split($Line,'""'),Chr(1)) If InStr($Line,'"') While (UBound(Split($Line,'"')) & 1) And (@Error = 0) $Tmp = ReadLine($Handle) If @Error = 0 $Line = $Line + @CRLF + Join(Split($Tmp,'""'),Chr(1)) EndIf Loop EndIf $Start = Left($Line,1) = '"' $End = Right($Line,1) = '"' $Tmp = Split($Line,'"') $Line = '' For $i = $Start To Ubound($Tmp) - $End If $i & 1 $Tmp[$i] = '"' + Join(Split($Tmp[$i],','),Chr(2)) + '"' EndIf $Line = $Line + $Tmp[$i] Next $Tmp = Split($Line,',') For $i = 0 To Ubound($Tmp) $Tmp[$i] = Trim(Join(Split($Tmp[$i],Chr(1)),'""')) $Tmp[$i] = Join(Split($Tmp[$i],Chr(2)),',') Next $ReadRec = $Tmp Else Exit 1 EndIf EndFunction ; Testfunction for CsvArray() - Display the array Function CsvShow($CsvRec) Dim $i,$j For $i = 0 To UBound($CsvRec,2) For $j = 0 To UBound($CsvRec,1) 'Index: ' + $i + ',' $j ? $CsvRec[$j,$i] ? Next ? Next EndFunction
Testfile: csvtest.txt quote: John,Doe,120 jefferson st.,Riverside, NJ, 08075 "John ""Da Man""",Repici,"120, 121 Jefferson St.",Riverside, NJ,08075 Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234 ,Blankman,,SomeTown, SD, 00298 "Joan ""the bone"", Anne",Jet,"9th, at Terrace plc",Desert City,CO,00123
-Erik
{Edit} Corrected missing DIM's [ 08. May 2003, 01:34: Message edited by: kholm ]
|
|
Top
|
|
|
|
Moderator: Arend_, Allen, Jochen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 2220 anonymous users online.
|
|
|