Registriert seit: 1. Apr 2017
3 Beiträge
|
AW: Generics Type feststellen?
1. Apr 2017, 19:26
Danke für die Hilfe! Falls das mal jemand benötigt hier meine Version (mit ein bischen Generics)
Code:
Type
TCustomCSVFile<T> = Class
private
fRowCount: Integer;
fColCount: Integer;
fData: Array Of Array Of T;
function GetData(ACol, ARow: Integer): T;
procedure SetData(ACol, ARow: Integer; const Value: T);
protected
procedure TrimData(AData: TStringList);
function CalcColCount(AData: TStringList): Integer;
procedure SetDataRow(ARow, MaxCol: Integer; const Data: TStringDynArray); virtual; abstract;
function GetDataRow(ARow: Integer): String; virtual; abstract;
public
procedure Clear; virtual; abstract;
procedure LoadFromFile(FileName: String);
procedure SaveToFie(FileName: String);
procedure DimData(ColCount, RowCount: Integer);
property RowCount: Integer read fRowCount;
property ColCount: Integer read fColCount;
property Data[ACol, ARow: Integer]: T read GetData write SetData;
End;
TDoubleCSVFile = Class(TCustomCSVFile<Double>)
protected
procedure SetDataRow(ARow, MaxCol: Integer; const Data: TStringDynArray); override;
function GetDataRow(ARow: Integer): String; override;
End;
TIntegerCSVFile = Class(TCustomCSVFile<Integer>)
protected
procedure SetDataRow(ARow, MaxCol: Integer; const Data: TStringDynArray); override;
function GetDataRow(ARow: Integer): String; override;
End;
Die Implementierung sieht dann (ungetestet) wie folgt aus:
Code:
{ TCustomCSVFile }
procedure TCustomCSVFile<T>.DimData(ColCount, RowCount: Integer);
begin
SetLength(fData, ColCount, RowCount);
end;
procedure TCustomCSVFile<T>.LoadFromFile(FileName: String);
var
LTmp: TStringList;
i, LEnd: Integer;
sa: TStringDynArray;
j: Integer;
begin
LTmp := TStringList.Create;
try
LTmp.LoadFromFile(FileName);
TrimData(LTmp);
fColCount := CalcColCount(LTmp);
fRowCount := LTmp.Count;
if (fColCount > 0) And (fRowCount > 0) then
begin
DimData(fColCount, fRowCount);
for i := 0 to fRowCount-1 do
begin
sa := SplitString(LTmp[i], ',');
LEnd := Min(fColCount, Length(sa));
SetDataRow(i, LEnd, sa);
end;
end
else
Clear;
finally
LTmp.Free;
end;
end;
procedure TCustomCSVFile<T>.SaveToFie(FileName: String);
var
LTmp: TStringList;
i, j: Integer;
begin
LTmp := TStringList.Create;
try
for i := 0 to Length(fData)-1 do
begin
LTmp.Add(GetDataRow(i));
end;
LTmp.SaveToFile(FileName);
finally
LTmp.Free;
end;
end;
function TCustomCSVFile<T>.GetData(ACol, ARow: Integer): T;
begin
Result := fData[ACol, ARow];
end;
procedure TCustomCSVFile<T>.SetData(ACol, ARow: Integer; const Value: T);
begin
fData[ACol, ARow] := Value;
end;
function TCustomCSVFile<T>.CalcColCount(AData: TStringList): Integer;
var
sa: TStringDynArray;
begin
// use the first row (after TrimData)
sa := SplitString(AData[0], ',');
Result := Length(sa);
end;
procedure TCustomCSVFile<T>.TrimData(AData: TStringList);
var
i: Integer;
Ln: string;
begin
for i := AData.Count-1 downto 0 do
begin
Ln := Trim(AData[i]);
if (Length(Ln) > 0) And (((Ln[1] >= '0') And (Ln[1]<='9')) Or (Ln[1]='+') Or (Ln[1]='-')) then
begin
AData[i] := Ln;
end
else
AData.Delete(i);
end;
end;
{ TDoubleCSVFile }
function TDoubleCSVFile.GetDataRow(ARow: Integer): String;
var
i: Integer;
sa: TStringDynArray;
LFmtSet: TFormatSettings;
begin
LFmtSet := TFormatSettings.Create();
LFmtSet.DecimalSeparator := '.';
SetLength(sa, High(fData[ARow]));
for i := 0 to High(fData[ARow]) do
begin
sa[i] := FloatToStr(fData[ARow, i], LFmtSet);
end;
Result.Join(',', sa);
end;
procedure TDoubleCSVFile.SetDataRow(ARow, MaxCol: Integer; const Data: TStringDynArray);
var
i: Integer;
LFmtSet: TFormatSettings;
begin
LFmtSet := TFormatSettings.Create();
LFmtSet.DecimalSeparator := '.';
for i := 0 to MaxCol-1 do
begin
fData[ARow, i] := StrToFloatDef(Data[i], 0.0, LFmtSet )
end;
end;
{ TIntegerCSVFile }
function TIntegerCSVFile.GetDataRow(ARow: Integer): String;
var
i: Integer;
sa: TStringDynArray;
begin
for i := 0 to High(fData[ARow]) do
begin
sa[i] := IntToStr(fData[ARow, i]);
end;
Result.Join(',', sa);
end;
procedure TIntegerCSVFile.SetDataRow(ARow, MaxCol: Integer; const Data: TStringDynArray);
var
i: Integer;
begin
for i := 0 to MaxCol-1 do
begin
fData[ARow, i] := StrToIntDef(Data[i], 0);
end;
end;
|
|
Zitat
|