TClientDataSet[5]: 读取数据

转载 2016年05月30日 11:41:45
本例用到:
TClientDataSet.Fields[];           { 字段集合; 它比 FieldList 有更多功能, 如可获取嵌套字段 }
TClientDataSet.FieldList[];        { 字段列表; 它比 Fields 轻便, 如果只是取值用它快一些 }
TClientDataSet.FieldByName();      { 根据字段名称获取字段对象; 获取一个字段对象时它比上两个快 }
TClientDataSet.FindField();        { 根据字段名称查找字段对象 }
TClientDataSet.FieldValues[];      { 根据字段名称获取字段值; 如果仅是获取字段值, 这个最快 }
TClientDataSet.First;              { 到第一个记录 }
TClientDataSet.Next;               { 到下一个记录 }
TClientDataSet.Last;               { 到最后一个记录 }
TClientDataSet.Prior;              { 到上一个记录 }
TClientDataSet.RecNo;              { 设置或读取当前记录的位置 }
TClientDataSet.Bof;                { 当前位置是否是第一个记录 }
TClientDataSet.Eof;                { 当前位置是否是最后一个记录 }
TClientDataSet.RecordSize;         { 一个记录的大小; 所谓一个记录就是当前行的所有字段 }
TClientDataSet.RecordCount;        { 记录总数; 也就是总行数 }
TClientDataSet.GetFieldList();     { 根据指定的几个字段名获取字段对象的列表 }
TClientDataSet.GetFieldData();     { 把指定字段的值写入一个缓冲区 }
TClientDataSet.GetCurrentRecord(); { 把当前记录(不包括 Bolb 字段)写入到一个缓冲区 }

读取字段的结构信息可以使用 TFieldDef 对象(一般来源于 FieldDefs 或 FieldDefList);

现在要读取其中的数据, 应该使用 TField 对象(一般来源于 Fields 或 FieldList).

Fields[0]、Fields[1] ... Fields[n] 获取的是当前行的第几个字段, 可用 Next、RecNo 等指定当前位置(行).

下面的例子使用了 Common Files\CodeGear Shared\Data\holdings.xml, 若更换文件需调整代码.

这是 holdings.xml 的字段信息:
ACCT_NBR  { 类型是 r8, 对应 ftFloat, 相当于 Double }
SYMBOL    { 类型是 string, 对应 ftString, 相当于 AnsiString; 指定 Size=7, 加上空结束, 大小是 8 }
SHARES    { 类型是 r8, 对应 ftFloat, 相当于 Double }
PUR_PRICE { 类型是 r8, 对应 ftFloat, 相当于 Double }
PUR_DATE  { 类型是 date, 对应 ftInteger, 相当于 Integer }

先窗体上放置 ClientDataSet1、DataSource1、DBGrid1、Memo1 和七个 Button, 然后:

{ 准备数据, 也可在设计时完成 }
procedure TForm1.FormCreate(Sender: TObject);
begin
  ChDir(GetEnvironmentVariable('CommonProgramFiles') + '\CodeGear Shared\Data\');
  ClientDataSet1.LoadFromFile('holdings.xml');
  DBGrid1.DataSource := DataSource1;
  DataSource1.DataSet := ClientDataSet1;
end;

{ 读取字段值的几种方法 }
procedure TForm1.Button1Click(Sender: TObject);
var
  v1,v2,v3,v4,v5,v6,v7,v8,v9: Variant;
  num: Double;
  fName: string;
begin
  { 获取首字段的名称 }
  fName := ClientDataSet1.Fields[0].FieldName;

  { 获取第一个字段值的几种方法: }
  v1 := ClientDataSet1.Fields[0].Value;
  v2 := ClientDataSet1.FieldByName(fName).Value;
  v3 := ClientDataSet1.FindField(fName).Value;
  v4 := ClientDataSet1.FieldValues[fName];
  v5 := ClientDataSet1[fName]; { FieldValues 是默认的数组属性 }
  v6 := ClientDataSet1.FieldList[0].Value;
  v7 := ClientDataSet1.FieldList.FieldByName(fName).Value;
  v8 := ClientDataSet1.FieldList.Find(fName).Value;
  v9 := ClientDataSet1.FieldList.Fields[0].Value;

  { 已知这个字段是 Double 类型的, 可同时转换 }
  num := ClientDataSet1.Fields[0].AsFloat;

  { 查看结果 }
  with Memo1.Lines do begin
    Clear;
    Add(v1); Add(v2); Add(v3); Add(v4); Add(v5); Add(v6); Add(v7); Add(v8);
    Add(FloatToStr(num));
  end;
end;
{ 遍历当前行字段的几种方法 }
procedure TForm1.Button2Click(Sender: TObject);
var
  Field: TField;
  i: Integer;
begin
  Memo1.Clear;
  for Field in ClientDataSet1.Fields do
  begin
    Memo1.Lines.Add(Field.Value);
  end;
  Memo1.Lines.Add('');

  for i := 0 to ClientDataSet1.FieldCount - 1 do
  begin
    Memo1.Lines.Add(ClientDataSet1.Fields[i].Value);
  end;
  Memo1.Lines.Add('');

  for i := 0 to ClientDataSet1.FieldList.Count - 1 do
  begin
    Memo1.Lines.Add(ClientDataSet1.FieldList[i].Value);
  end;
  Memo1.Lines.Add('');
end;

{ First、Next、Last、Prior、RecNo }
procedure TForm1.Button3Click(Sender: TObject);
var
  s1,s2,s3: string;
begin
  { 读取第二行第二个字段 }
  ClientDataSet1.First;
  ClientDataSet1.Next;
  s1 := ClientDataSet1.Fields[1].AsString;

  { 读取倒数第二行第二个字段 }
  ClientDataSet1.Last;
  ClientDataSet1.Prior;
  s2 := ClientDataSet1.Fields[1].AsString;

  { 读取第四行第二个字段 }
  ClientDataSet1.RecNo := 4;
  s3 := ClientDataSet1.Fields[1].AsString;

  { 查看结果 }
  with Memo1.Lines do begin
    Clear;
    Add('第二行第二个字段: ' + s1);
    Add('倒数第二行第二个字段: ' + s2);
    Add('第四行第二个字段: ' + s3);
  end;
end;

{ 遍历指定字段的所有记录 }
procedure TForm1.Button4Click(Sender: TObject);
var
  i: Integer;
begin
  if not ClientDataSet1.Bof then ClientDataSet1.First;
  Memo1.Clear;
  while not ClientDataSet1.Eof do
  begin
    Memo1.Lines.Add(ClientDataSet1.FieldList[0].Value);
    ClientDataSet1.Next;
  end;
  Memo1.Lines.Add('-------');

  for i := 1 to ClientDataSet1.RecordCount do
  begin
    ClientDataSet1.RecNo := i;
    Memo1.Lines.Add(ClientDataSet1.FieldList[1].Value);
  end;
end;

{ 通过 GetFieldList 可以读取几个指定字段的 TField 对象的列表 }
procedure TForm1.Button5Click(Sender: TObject);
var
  List: TList;
  Field: TField;
  i: Integer;
begin
  List := TList.Create;
  ClientDataSet1.GetFieldList(List, 'ACCT_NBR; SYMBOL; SHARES');

  Memo1.Clear;
  for i := 0 to List.Count - 1 do
  begin
    Field := List[i];
    Memo1.Lines.Add(Field.Value);
  end;

  List.Free;
end;

{ GetFieldData 读取字段值到指针 }
procedure TForm1.Button6Click(Sender: TObject);
var
  F1: Double;
  F2: array[0..7] of AnsiChar;
begin
  ClientDataSet1.GetFieldData(ClientDataSet1.Fields[0], @F1);
  ClientDataSet1.GetFieldData(ClientDataSet1.Fields[1], @F2);

  with Memo1.Lines do begin
    Clear;
    Add(FloatToStr(F1));
    Add(F2);
  end;
end;

//这是后面的例子用到的函数, 转换 TClientDataSet 时间格式到 TDateTime
function TDateTimeRecToDateTime(DataType: TFieldType; Data: TDateTimeRec): TDateTime;
var
  TimeStamp: TTimeStamp;
begin
  case DataType of
    ftDate:
      begin
        TimeStamp.Time := 0;
        TimeStamp.Date := Data.Date;
      end;
    ftTime:
      begin
        TimeStamp.Time := Data.Time;
        TimeStamp.Date := DateDelta;
      end;
  else
    try
      TimeStamp := MSecsToTimeStamp(Data.DateTime);
    except
      TimeStamp.Time := 0;
      TimeStamp.Date := 0;
    end;
  end;
  Result := TimeStampToDateTime(TimeStamp);
end;

{ GetCurrentRecord 是把当前行的所有字段(不包括 Blob 字段)读入到缓冲区 }
procedure TForm1.Button7Click(Sender: TObject);
type
  THoldingsStruct = packed record { 这是根据 holdings.xml 建立的数据结构 }
    ACCT_NBR: Double;
    SYMBOL: array[0..7] of AnsiChar; { 其 Size=7, 但后面还有个 #0 }
    SHARES: Double;
    PUR_PRICE: Double;
    PUR_DATE: Integer;
//    Other: array[0..4] of Byte; { 它后面还若干字节偏移, 测试时其字节数等于前面的字段数 }
  end;
var
  buf: THoldingsStruct;
  DateTimeRec: TDateTimeRec;
begin
  //ShowMessage(IntToStr(ClientDataSet1.RecordSize)); { 可通过这个值对照上面的结构 }
  if ClientDataSet1.GetCurrentRecord(@buf) then with Memo1.Lines do
  begin
    Clear;
    Add(FloatToStr(buf.ACCT_NBR));
    Add(buf.SYMBOL);
    Add(FloatToStr(buf.SHARES));
    Add(FloatToStr(buf.PUR_PRICE));

    DateTimeRec.Date := buf.PUR_DATE;
    Add(DateToStr(TDateTimeRecToDateTime(ftDate, DateTimeRec)));
  end;
end;

使用TclientDataset

由于多层应用系统经常是为了在缓慢的广域网络,或是服务大量的客户端用户,因此有效的节省网络的使用使用率便可以加快整个系统的执行效率。因此DELPHI的多层应用系统对于更新数据的设计理念便是先把更新的数据...
  • xiangyu5945
  • xiangyu5945
  • 2010年03月26日 15:12
  • 2914

可能你不知道的TClientDataset功能

keyLife富翁笔记   作者: shiningplus 标题: delphi Midas SQLServer的自增字段的处理  关键字: delphi Midas 自增字段  分类:...
  • onebigday
  • onebigday
  • 2016年02月29日 08:59
  • 1695

TClientDataSet用法详解

TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件。该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖上述几种数据库...
  • yangjian900109
  • yangjian900109
  • 2015年12月17日 15:33
  • 522

学习TClientDataset的使用

        这个控件好像很好用,以前都是用TSimpledataset,现在突然想用一下它。要用它,好像比TSimpleDataset多几个控件,我是加了以下几个控件,TSQLConnection...
  • onebigday
  • onebigday
  • 2011年03月24日 22:18
  • 7877

Delphi TClientDataSet 使用方法_详解

TClientDataSet 与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端。 TClientDataSet最...
  • xxhh07
  • xxhh07
  • 2011年10月06日 14:12
  • 2935

Delphi TClientDataSet

Delphi TClientDataSet的使用    TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的...
  • lailai186
  • lailai186
  • 2013年08月07日 13:30
  • 1556

delphi的tclientdataset的中文过滤使用注意事项

在用到Tclientdataset的中文过滤时,发现有以下几点一定要注意:第一:中文字段必须是明确的varchar类型字段,在程序中可以用if clientdataset.fieldbyname(字段...
  • baronyang
  • baronyang
  • 2009年08月22日 10:46
  • 1778

多层数据库开发十一:TClientDataSet

                                                  第十一章 TClientDataSet  与TTable、TQuery一样,TClientDataS...
  • shuaihj
  • shuaihj
  • 2004年11月05日 11:55
  • 2162

TClientDataSet

由于多层应用系统经常是为了在缓慢的广域网络,或是服务大量的客户端用户,因此有效的节省网络的使用使用率便可以加快整个系统的执行效率。因此DELPHI的多层应用系统对于更新数据的设计理念便是先把更新的数据...
  • yangjian900109
  • yangjian900109
  • 2013年08月31日 11:18
  • 713

深入TClientDataSet

与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端。TClientDataSet最大的特点是它不依赖于BDE(Borland...
  • qiume
  • qiume
  • 2009年03月06日 14:41
  • 2535
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:TClientDataSet[5]: 读取数据
举报原因:
原因补充:

(最多只允许输入30个字)