Quote
William Chan wrote in message <371D4609.1AC0A...@hkstar.com>...
>I have a tab-delimited text file with the format like the following :
On Web pages with Delphi components you can find free TDataSet descendant
components with source code that define capability on text files just what
you need.
I have one of those and I am sending it on the end of this post ... Try this
out, you can connect it with the data grid through data source, it worked
for me in Delphi2. If there are some bugs do not blame me.
tomi.
unit TxtTable;
interface
uses
Classes, Db, Consts;
type
TRecInfo = packed record
BookMark: Longint;
UpdateStatus: TUpdateStatus;
BookmarkFlag: TBookmarkFlag;
end;
TArrInt = array [0..10000] of integer;
PInteger = ^TArrInt;
PRecInfo = ^TRecInfo;
PLongInt = ^LongInt;
// TStrGrid - used for keep data in memory,
// also implements methods for retrieving and storing
// data in text files
TStrGrid = class(TStringList)
private
FRow, FCol : longint;
FDChar : char;
function GetCells(ACol, ARow: Integer): string;
procedure SetCells(ACol, ARow: Integer; const Value: string);
function GetRObject(ARow: Integer): TObject;
procedure PutRObject(ARow: Integer; const AObject: TObject);
function GetCObject(ACol: Integer): TObject;
procedure PutCObject(ACol: Integer; const AObject: TObject);
procedure ReadRow( Reader: TReader);
procedure ReadCol( Reader: TReader);
procedure WriteRow(Writer: TWriter);
procedure WriteCol(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
public
constructor Create;
property Cells[ACol, ARow: Integer]: string read GetCells write
SetCells; default;
property RowObjects[ARow: Integer]: TObject read GetRObject write
PutRObject;
property ColObjects[ACol: Integer]: TObject read GetCObject write
PutCObject;
property RowCount : LongInt read FRow;
property ColCount : LongInt read FCol;
property DivChar : char read FDChar write FDChar;
procedure LoadFromFile( const FileName : string ); override;
procedure SaveToFile( const FileName : string ); override;
function IndexOfObject( const AObject : TObject ) : longint;
procedure InsertRow( Index : integer; Str : String; Obj : TObject );
procedure DeleteRow( Index : integer );
end;
// TTextTable - descedant of TDataSet, implements
// simple text file based dataset
TTextTable = class(TDataSet)
private
FFldOffs : PInteger;
FData : TStrGrid;
FFldNames : TStrings;
FRecSize : Integer;
FRecBufSize : Integer;
FRecInfoOfs : Integer;
FCurRec : Integer;
FFileName : string;
FLastBookmark : LongInt;
FSaveChanges : Boolean;
FKeepDataInMem : Boolean;
procedure ReadFld( Reader: TReader );
procedure WriteFld( Writer: TWriter );
procedure SetDChar( FDivCh : char );
function GetDChar : char;
protected
procedure DefineProperties(Filer: TFiler); override;
function AllocRecordBuffer: PChar; override;
procedure FreeRecordBuffer(var Buffer: PChar); override;
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
function GetFieldData(Field: TField; Buffer: Pointer): Boolean;
override;
function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean):
TGetResult; override;
function GetRecordSize: Word; override;
procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;
procedure InternalClose; override;
procedure InternalDelete; override;
procedure InternalFirst; override;
procedure InternalGotoBookmark(Bookmark: Pointer); override;
procedure InternalHandleException; override;
procedure InternalInitFieldDefs; override;
procedure InternalInitRecord(Buffer: PChar); override;
procedure InternalLast; override;
procedure InternalOpen; override;
procedure InternalPost; override;
procedure InternalSetToRecord(Buffer: PChar); override;
function IsCursorOpen: Boolean; override;
procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
override;
procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
procedure SetFieldData(Field: TField; Buffer: Pointer); override;
function GetRecordCount: Integer; override;
function GetRecNo: Integer; override;
procedure SetRecNo(Value: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function FindKey(const KeyValues: array of const): Boolean;
published
property DivChar : char read GetDChar write SetDChar;
property KeepData : Boolean read FKeepDataInMem write FKeepDataInMem;
property FileName: string read FFileName write FFileName;
property Active;
property BeforeOpen;
property AfterOpen;
property BeforeClose;
property AfterClose;
property BeforeInsert;
property AfterInsert;
property BeforeEdit;
property AfterEdit;
property BeforePost;
property AfterPost;
property BeforeCancel;
property AfterCancel;
property BeforeDelete;
property AfterDelete;
property BeforeScroll;
property AfterScroll;
property OnCalcFields;
property OnDeleteError;
property OnEditError;
property OnNewRecord;
property OnPostError;
end;
procedure Register;
implementation
uses SysUtils, Forms;
const
MaxRecLength = 4096;
DefDivChar : char = #9;
// Component registering
procedure Register;
begin
RegisterComponents('SAV', [TTextTable]);
end;
// StrGrid Methods
procedure TStrGrid.ReadRow( Reader: TReader);
begin FRow := Reader.ReadInteger; end;
procedure TStrGrid.ReadCol( Reader: TReader);
begin FCol := Reader.ReadInteger; end;
procedure TStrGrid.WriteRow( Writer: TWriter);
begin Writer.WriteInteger( FRow ); end;
procedure TStrGrid.WriteCol( Writer: TWriter);
begin Writer.WriteInteger( FCol ); end;
procedure TStrGrid.DefineProperties(Filer: TFiler);
begin
Filer.DefineProperty( 'RowCount', ReadRow, WriteRow, Count>0 );
Filer.DefineProperty( 'ColCount', ReadCol, WriteCol, Count>0 );
inherited DefineProperties(Filer);
end;
constructor TStrGrid.Create;
begin
inherited Create;
FRow := 0; FCol := 0; FDChar := DefDivChar;
end;
function TStrGrid.GetCells(ACol, ARow: Integer): string;
begin Result := Strings[ARow*FCol+ACol]; end;
procedure TStrGrid.SetCells(ACol, ARow: Integer; const Value: string);
begin Strings[ARow*FCol+ACol] := Value end;
function TStrGrid.GetRObject(ARow: Integer): TObject;
begin Result := Objects[ARow*FCol]; end;
procedure TStrGrid.PutRObject(ARow: Integer; const AObject: TObject);
begin Objects[ARow*FCol] := AObject; end;
function TStrGrid.GetCObject(ACol: Integer): TObject;
begin Result := Objects[ACol]; end;
procedure TStrGrid.PutCObject(ACol: Integer; const AObject: TObject);
begin Objects[ACol] := AObject; end;
procedure TStrGrid.InsertRow( Index : Integer; Str : String; Obj :
TObject );
var
i : integer;
begin
InsertObject( Index*FCol, Str, Obj );
for i := 2 to FCol do Insert( Index*FCol+i-1, '' );
inc(FRow);
end;
procedure TStrGrid.DeleteRow( Index : Integer );
var
i : integer;
begin
Delete( Index*FCol );
for i := 2 to FCol do Delete( Index*FCol );
dec(FRow);
end;
function TStrGrid.IndexOfObject( const AObject : TObject) : Integer;
begin
Result := inherited IndexOfObject(AObject);
if Result >= 0 then Result := Result div FCol;
end;
procedure TStrGrid.LoadFromFile( const FileName : string);
function FetchParm( var StrP : PChar ) : string;
var
p1 : PChar;
begin
p1 := StrScan( StrP, FDChar ); if p1 <> nil then p1[0] := #0;
Result := StrPas( StrP );
if p1 <> nil then StrP := p1 + 1 else StrP := nil;
end;
type
StrBuf = array [0..MaxRecLength] of char;
StrBufP = ^StrBuf;
var
j : integer;
GridF : TextFile;
ReadBuf, p1 : StrBufP;
begin
AssignFile( GridF, FileName ); Reset( GridF );
Clear;
ReadBuf := new(StrBufP); ReadLn( GridF, ReadBuf^ ); p1 := ReadBuf;
while p1<>nil do Add(FetchParm( PCHar(p1) ));
FCol := Count; FRow := 1;
while not eof( GridF ) do
begin
ReadLn( GridF, ReadBuf^ );
p1 := ReadBuf; if p1^[0]=#0 then Break;
for j := 1 to FCol do Add(FetchParm( PCHar(p1) ));
inc( FRow );
end;
Dispose(ReadBuf );
CloseFile( GridF );
end;
procedure TStrGrid.SaveToFile( const FileName : string);
var
i, j : integer;
GridF : TextFile;
begin
AssignFile( GridF, FileName ); Rewrite( GridF );
for i := 1 to FRow do
begin
Write( GridF, Strings[(i-1)*FCol] );
for j := 2 to FCol do Write( GridF, FDChar+Strings[(i-1)*FCol+j-1] );
WriteLn( GridF );
end;
CloseFile( GridF );
end;
// TextTable Methods
procedure TTextTable.ReadFld(Reader: TReader);
begin
Reader.ReadListBegin;
FFldNames.BeginUpdate;
try
FFldNames.Clear;
while not Reader.EndOfList do FFldNames.Add(Reader.ReadString);
finally
FFldNames.EndUpdate;
end;
Reader.ReadListEnd;
end;
procedure TTextTable.WriteFld( Writer: TWriter );
var
i : integer;
begin
Writer.WriteListBegin;
for i := 1 to FFldNames.Count do Writer.WriteString( FFldNames[i-1] );
Writer.WriteListEnd;
end;
procedure TTextTable.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty( 'FldNames', ReadFld, WriteFld, FFldNames.Count>0 );
FData.DefineProperties(Filer);
end;
constructor TTextTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FKeepDataInMem := true;
FData := TStrGrid.Create;
FFldNames := TStringList.Create;
end;
destructor TTextTable.Destroy;
begin
inherited Destroy;
FData.Free; FFldNames.Free;
end;
procedure TTextTable.SetDChar( FDivCh : char );
begin
if FData <> nil then FData.DivChar :=
...
read more »