当前位置:主页>销售管理软件> 列表

求助:关于从文件中读写TDataSet的Fields问题. 找中国管理软件学院

记账软件版1楼: 想实现从文件中读写TDataSet的Fields,实现方法如下, 现在的问题是从文件中读出的TField对象无法在TDataSet及DBGrid中正常工作,试了好久,头有点晕了。
code:
{******************************************************************************}
{* }
{* 单元名称:读写TDataSet的Fields对象 }
{* 创建日期:2006.01.07 }
{* 单元作者:cgs }
{* 备 注: }
{* 开发平台:PWin2000pro + Delphi 7.0 }
{* 版权所有 (C) 2006 cgs_studio }
{* 更新记录: }
{* }
{******************************************************************************}


unit uCKFields;

interface

uses
Classes, sysutils, DB;

type
TCKFields = class(TObject)
private
FDataSet: TDataSet;
function GetFields: TFields;
function GetField(index: integer): TField;

public
constructor Create(ds: TDataSet);
procedure SaveToFile(FileName:string);
procedure LoadFromFile(FileName:string);
procedure SaveToStream(Stream:TStringStream);
procedure LoadFromStream(Stream:TStringStream);
procedure SaveToIni(iniFileName,Section:string);
procedure LoadFromIni(iniFileName,Section:string);

property DataSet:TDataSet read FDataSet;
property Fields:TFields read GetFields;
property Items[index:integer]:TField read GetField; Default;
end;

function ComponentToString(Component: TComponent): string;
function StringToComponent(Value: string): TComponent;

implementation

uses strutils ,inifiles;

function ComponentToString(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;

end;
finally
BinStream.Free
end;
end;

function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);

finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;

{ TCKFields }

constructor TCKFields.Create(ds: TDataSet);
begin
inherited Create;
FDataSet:=ds;
end;

function TCKFields.GetField(index: integer): TField;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields[index];
end;

function TCKFields.GetFields: TFields;
begin
result:=nil;
if FDataSet<>nil then
result:=FDataSet.Fields;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromFile }
{ 说明: 从文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}


procedure TCKFields.LoadFromFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;

ssFile:=TStringlist.Create;
try
ssFile.LoadFromFile(FileName);
if ssFile.Count=0 then exit;
stmStr:=TStringStream.Create(ssFile.Text);
try
LoadFromStream(stmStr);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromIni }
{ 说明: 从INI文本文件中读取读取Fields }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromIni(iniFileName, Section: string);
const
sKey= ''CKFields%d'';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
begin
ini:=TInifile.Create(iniFileName);
try
stmStr:= TStringStream.Create('''');
try
stmTmp:=TMemoryStream.Create;
try
stmStr.Seek(0,soFromBeginning);
i:=0;
while true do
begin
stmTmp.SetSize(0);
ini.ReadBinaryStream(Section,format(sKey,[i]),stmTmp);
if stmTmp.Size =0 then break;
stmTmp.Seek(0,soFromBeginning);
stmStr.CopyFrom(stmTmp,stmTmp.Size);
inc(i);
end;
LoadFromStream(stmStr);

finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.LoadFromStream }
{ 说明: 从流中读取Fields }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.LoadFromStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
Component:TComponent;
begin
if FDataSet=nil then exit;

ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
ssAll.Text:=Stream.DataString;
if ssAll.Count=0 then exit;
FDataSet.Fields.Clear;
for i:=0 to ssAll.Count-1 do
begin
if LowerCase(LeftStr(ssAll[i],6))=''object'' then
begin
ss.Clear;
ss.Add(ssAll[i]);

end
else if LowerCase(LeftStr(ssAll[i],3))=''end'' then
begin
ss.Add(ssAll[i]);
Component:= StringToComponent(ss.Text);
FDataSet.Fields.Add(TField(Component));

end
else if trim(ssAll[i])='''' then
begin
break;
end
else
ss.Add(ssAll[i]);
end;
finally
ssAll.Free;
ss.Free;
end;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToFile }
{ 说明: 保存到文本文件 }
{ 日期: 2006.01.07 }
{ 参数: FileName: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}


procedure TCKFields.SaveToFile(FileName: string);
var
ssFile:TStrings;
stmStr:TStringStream;
begin
if FDataSet=nil then exit;
ssFile:=TStringlist.Create;
try
stmStr:= TStringStream.Create('''');
try
SaveToStream(stmStr);
ssFile.Text:=stmStr.DataString;
ssFile.SaveToFile(FileName);
finally
stmStr.Free;
end;
finally
ssFile.Free;
end;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToIni }
{ 说明: 保存到INI文件 }
{ 日期: 2006.01.07 }
{ 参数: iniFileName, Section: string }
{ 返回值: 无 }
{------------------------------------------------------------------------------}
procedure TCKFields.SaveToIni(iniFileName, Section: string);
const
BuffSize=40;
sKey= ''CKFields%d'';
var
i:integer;
ini:TInifile;
stmStr:TStringStream;
stmTmp:TMemoryStream;
Buffer:Array[0..BuffSize-1] of char;
begin
ini:=TInifile.Create(iniFileName);
try
ini.EraseSection(Section);
stmStr:= TStringStream.Create('''');
try
stmTmp:=TMemoryStream.Create;
try
SaveToStream(stmStr);
stmStr.Seek(0,soFromBeginning);
for i:=0 to stmstr.Size div BuffSize -1 do
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,length(Buffer));
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,length(Buffer));
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,[i]),stmTmp);
end;
if stmStr.Size mod BuffSize >0 then
begin
FillChar(Buffer,length(Buffer),#0);
stmStr.Read(Buffer,stmStr.Size mod BuffSize);
stmTmp.SetSize(0);
stmTmp.WriteBuffer(Buffer,stmStr.Size mod BuffSize);
stmTmp.Seek(0,soFromBeginning);
ini.WriteBinaryStream(Section,format(sKey,[i]),stmTmp);
end;

finally
stmTmp.Free;
end;
finally
stmStr.Free;
end;
finally
ini.Free;
end;
end;

{------------------------------------------------------------------------------}
{ 过程名: TCKFields.SaveToStream }
{ 说明: 保存到流 }
{ 日期: 2006.01.07 }
{ 参数: Stream: TStringStream }
{ 返回值: 无 }
{------------------------------------------------------------------------------}

procedure TCKFields.SaveToStream(Stream: TStringStream);
var
ssAll,ss:TStrings;
i:integer;
begin
if FDataSet=nil then exit;

ss:=TStringlist.Create;
ssAll:=TStringlist.Create;
try
for i:=0 to FDataSet.Fields.Count-1 do
begin
ss.Text:= ComponentToString(FDataSet.Fields[i]);
ssAll.AddStrings(ss);
end;

if ssAll.Count>0 then
begin
Stream.Size:=0;
Stream.writeString(ssAll.Text);
end;
finally
ssAll.Free;
ss.Free;
end;
end;

initialization

RegisterClasses([TIntegerField,TBooleanField,TDateTimeField,TFloatField,
TCurrencyField,TWideStringField,TBlobField,TDataSetField,TDateField,TMemoField,
TWordField,TStringField,TAutoIncField,TSmallintField,TTimeField,TBCDField]);
end.

2楼: 技術交流QQ:136293586
控件裡本身就有這個功能了。 如中国管理软件学院

3楼: 數據流到文件


procedure TForm1.Button1Click(Sender: TObject);
var
Stream:TMemoryStream;
Conn:String;
begin
if SaveDialog1.Execute then
begin
Conn:= SaveDialog1.FileName;
Stream:=TMemoryStream.Create;
Stream.Position:=0;
try
TBlobField(ADOTable1.FieldByName(''acc'')).SaveToStream(Stream);
Stream.SaveToFile(Conn);
finally
Stream.Free;
end;
end;
end;

文件到數據流
procedure TForm1.Button2Click(Sender: TObject);
var
Stream:TMemoryStream;
begin
if OpenDialog1.Execute then
begin
adotable1.Append;
ADOTable1.FieldByName(''name'').AsString:=OpenDialog1.FileName;
Stream:=TMemoryStream.Create;
Stream.Position:=0;
try
Stream.LoadFromFile(OpenDialog1.FileName);
TBlobField(ADOTable1.FieldByName(''acc'')).LoadFromStream(Stream);
ADOTable1.post;
finally
Stream.Free;
end;
end;
end;

4楼: bbscom ,你理解错了,我不是保存Dataset的数据,是保存它的结构(保存每个TField对象)


然后从文件中读取这些TField对象,并动态创建。

5楼: 我觉得应该可以 ini
[fieldcount]
fieldcount=10;
[field1]
name=qq
datastyle=ww
[field2]




然后根据fieldcound读出所有数据

然后创建
procedure TForm1.ImageButton1Click(Sender: TObject);
var
ClientDataSet1qq: TStringField;
begin
ClientDataSet1qq:=TStringField.Create(ClientDataSet1);
end;

6楼: Component:= StringToComponent(ss.Text);
FDataSet.Fields.Add(TField(Component));

field也是对象,你好像没有创建,直接就加进去了

记账软件版7楼: sbzldlb, TField在StringToComponent中用TStream.ReadComponent方法创建了。

刚刚看了帮助发现TStream.ReadComponent(NIL)创建的是newly component,试了下发现创建的TField.Owner为nil ,且Index为-1,不知道怎样初始化它们?

8楼: 睡一觉精神好多了,问题自然也解决了,哈哈!
谢谢大家~