Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zeilen in Memo in 3 Teile zerlegen


tenacer - Sa 17.10.09 13:46
Titel: Zeilen in Memo in 3 Teile zerlegen
Hallo,

Ein Datensatz (.txt) habe ich in ein Memo geladen. In jeder Zeile stehen Daten nach dem Muster:
Name, Wert1,Wert2

Wie kann ich nun die Daten zerlegen und jeweils Name Wert1 oder Wert2 in Arrays speichern?

Bin über jede Hilfe dankbar


Andreas L. - Sa 17.10.09 13:55

Entweder du zerlegst den String mit Pos, PosEx, Copy und Delete oder du verwendest einen CSV-Parser wie z. B. MyLittleBase oder meinen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
unit BCParsers;

interface

uses
  SysUtils, Classes, ContNrs, BCUtils, DateUtils, StrUtils;

type
  { forward declarations }
  TBcCSVParser = class;
  TBcSimpleDataSets = class;
  TBcSimpleDataSet = class;

  TBcCSVParser = class(TComponent)
  private
    FDataSets: TBcSimpleDataSets;
    FFieldSeparator: String;
  protected
    procedure SetDataSets(Value: TBcSimpleDataSets);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure ParseStrings(Strings: TStrings);
    procedure LoadFromStream(Stream: TStream);
    procedure LoadFromFile(const FileName: String);
    procedure BuildStrings(Strings: TStrings);
    procedure SaveToStream(Stream: TStream);
    procedure SaveToFile(const FileName: String);
    property DataSets: TBcSimpleDataSets read FDataSets write SetDataSets;
  published
    property FieldSeparator: String read FFieldSeparator write FFieldSeparator;
  end;

TBcSimpleDataSets = class(TObjectList)
  protected
    procedure SetItem(Index: Integer; Value: TBcSimpleDataSet);
    function GetItem(Index: Integer):TBcSimpleDataSet;
  public
    function Add:Integer;
    property Items[Index: Integer]: TBcSimpleDataSet read GetItem write SetItem; default;
  end;

  TBcSimpleDataSet = class(TPersistent)
  private
    FFields: TStrings;
  protected
    procedure SetFields(Value: TStrings);
  public
    constructor Create;
    destructor Destroy; override;
    property Fields: TStrings read FFields write SetFields;
  end;

implementation

{ TBcParser }
constructor TBcCSVParser.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDataSets := TBcSimpleDataSets.Create;
  FFieldSeparator := ';';
end;

destructor TBcCSVParser.Destroy;
begin
  FDataSets.Free;
  inherited Destroy;
end;

procedure TBcCSVParser.SetDataSets(Value: TBcSimpleDataSets);
begin
  FDataSets := Value;
end;

procedure TBcCSVParser.ParseStrings(Strings: TStrings);
var
  iLine: Integer;
  CurrentLine: String;
begin
  DataSets.Clear;

  for iLine := 0 to Strings.Count -1 do
  begin
    CurrentLine := Trim(Strings[iLine]);
    if (pos('#', CurrentLine) = 0and (CurrentLine <> ''then
      DataSets[DataSets.Add].Fields.Text := StringReplace(CurrentLine,
                                                          FFieldSeparator,
                                                          sLineBreak,
                                                          [rfReplaceAll]);
  end;
end;

procedure TBcCSVParser.LoadFromStream(Stream: TStream);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    Data.LoadFromStream(Stream);
    ParseStrings(Data);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.LoadFromFile(const FileName: string);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    Data.LoadFromFile(FileName);
    ParseStrings(Data);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.BuildStrings(Strings: TStrings);
var
  iDataSet: Integer;
begin
  Strings.Clear;

  for iDataSet := 0 to DataSets.Count -1 do
    Strings.Add(StringReplace(DataSets[iDataSet].Fields.Text, sLineBreak,
                           FFieldSeparator, [rfReplaceAll]));
end;

procedure TBcCSVParser.SaveToStream(Stream: TStream);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    BuildStrings(Data);
    Data.SaveToStream(Stream);
  finally
    Data.Free;
  end;
end;

procedure TBcCSVParser.SaveToFile(const FileName: string);
var
  Data: TStrings;
begin
  Data := TStringList.Create;
  try
    BuildStrings(Data);
    Data.SaveToFile(FileName);
  finally
    Data.Free;
  end;
end;

{ TBcSimpleDataSets }
procedure TBcSimpleDataSets.SetItem(Index: Integer; Value: TBcSimpleDataSet);
begin
  inherited Items[Index] := Value;
end;

function TBcSimpleDataSets.GetItem(Index: Integer):TBcSimpleDataSet;
begin
  Result := inherited Items[Index] as TBcSimpleDataSet;
end;

function TBcSimpleDataSets.Add:Integer;
var
  NewDataSet: TBcSimpleDataSet;
begin
  NewDataSet := TBcSimpleDataSet.Create;
  Result := inherited Add(NewDataSet);
end;

{ TBcSimpleDataSet }
constructor TBcSimpleDataSet.Create;
begin
  inherited Create;
  FFields := TStringList.Create;
end;

destructor TBcSimpleDataSet.Destroy;
begin
  FFields.Free;
  inherited Destroy;
end;

procedure TBcSimpleDataSet.SetFields(Value: TStrings);
begin
  FFields.Assign(Value);
end;


Anwendungsbeispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  csv: TBcCSVParser;
  i: Integer;
begin
  csv := TBcCSVParser.Create(nil);
  try
    csv.ParseStrings(Memo1.Lines);
    for i := 0 to csv.DataSets.Count -1 do
      ShowMessage(CSV.DataSets[i].Fields.Text);
    //Zugriff auf einzelne Elemente: CSV.DataSets[i].Fields[0]; //0 = erstes Element, 1 = zweites, etc. Fields.Count = Anzahl an Feldern
  finally
    csv.Free;
  end;
end;


tenacer - Sa 17.10.09 15:42

Danke für die Nachricht, aber CSV-Parser sagen mir gar nichts.
Mit Pos habe ich es versucht aber ich versteh überhaupt nicht, wie ich alle Zeilen aus dem Memo aufteilen kann und dann die Daten in die jeweiligen Arrays kopieren kann. :-(


jaenicke - So 18.10.09 01:54

user profile icontenacer hat folgendes geschrieben Zum zitierten Posting springen:
Danke für die Nachricht, aber CSV-Parser sagen mir gar nichts.
Der komplette Quelltext dazu steht doch da... :roll:

user profile icontenacer hat folgendes geschrieben Zum zitierten Posting springen:
Mit Pos habe ich es versucht aber ich versteh überhaupt nicht, wie ich alle Zeilen aus dem Memo aufteilen kann und dann die Daten in die jeweiligen Arrays kopieren kann. :-(
Wie hast du es denn versucht?


Delete - So 18.10.09 02:44

Nun ja, man kann auch mit Mücken auf Elefanten schießen. Ein einfaches Explode [http://www.delphipraxis.net/topic3816_ein+dynamisches+array+aus+einem+string+erzeugen.html] sollte schon reichen.