Author: Jonas Bilinkevicius
When reading comma separated files with TStringList.CommaText, there is a problem,
if the value between commas contains a space it is broken up to two separate
values. Any suggestion on how to avoid this?
Answer:
Solve 1:
I had a similar problem and wrote a function that replaces all commas (,) with
carriage returns (#13). So you can do:
StringList1.Text := CommaSeparate(TheCSVString);
1 function CommaSeparate(const szString: string): string;
2 var
3 iLength: integer;
4 i: integer;
5 bDoubleQuotesActive: boolean;
6 szOutput: string;
7 begin
8 iLength := Length(szString);
9 bDoubleQuotesActive := False;
10 for i := 1 to iLength do
11 begin
12 if szString[i] = ',' then
13 begin
14 if not bDoubleQuotesActive then
15 szOutput := szOutput + Chr(13);
16 end
17 else if szString[i] = '"' then
18 begin
19 if bDoubleQuotesActive then
20 bDoubleQuotesActive := False
21 else
22 bDoubleQuotesActive := True;
23 end
24 else
25 szOutput := szOutput + szString[i];
26 end;
27 Result := szOutput;
28 end;
Solve 2:
29 { ... }
30 interface
31 {So CommaText will have the same meaning as CSV}
32 TCommaStrings = class(TStringList)
33 private
34 function GetCommaText: string;
35 procedure SetCommaText(const Value: string);
36 public
37 property CommaText: string read GetCommaText write SetCommaText;
38 end;
39
40 implementation
41
42 function TCommaStrings.GetCommaText: string;
43 var
44 S: string;
45 P: PChar;
46 I, Count: Integer;
47 begin
48 Count := GetCount;
49 if (Count = 1) and (Get(0) = '') then
50 Result := '""'
51 else
52 begin
53 Result := '';
54 for I := 0 to Count - 1 do
55 begin
56 S := Get(I);
57 P := PChar(S);
58 while not (P^ in [#0..' ', '"', ',']) do
59 P := CharNext(P);
60 if (P^ <> #0) then
61 S := AnsiQuotedStr(S, '"');
62 Result := Result + S + ',';
63 end;
64 System.Delete(Result, Length(Result), 1);
65 end;
66 end;
67
68 procedure TCommaStrings.SetCommaText(const Value: string);
69 var
70 P, P1: PChar;
71 S: string;
72 begin
73 BeginUpdate;
74 try
75 Clear;
76 P := PChar(Value);
77 while P^ in [#1..' '] do
78 P := CharNext(P);
79 while P^ <> #0 do
80 begin
81 if P^ = '"' then
82 S := AnsiExtractQuotedStr(P, '"')
83 else
84 begin
85 P1 := P;
86 while (P^ >= ' ') and (P^ <> ',') do
87 P := CharNext(P);
88 SetString(S, P1, P - P1);
89 end;
90 Add(S);
91 while P^ in [#1..' '] do
92 P := CharNext(P);
93 if P^ = ',' then
94 begin
95 repeat
96 P := CharNext(P);
97 until
98 not (P^ in [#1..' ']);
99 if P^ = #0 then
100 Add('') {Trailing commas ARE another field!}
101 end;
102 end;
103 finally
104 EndUpdate;
105 end;
106 end;
|