本例用到:


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[].FieldName;   { 获取第一个字段值的几种方法: }
  v1 := ClientDataSet1.Fields[].Value;
  v2 := ClientDataSet1.FieldByName(fName).Value;
  v3 := ClientDataSet1.FindField(fName).Value;
  v4 := ClientDataSet1.FieldValues[fName];
  v5 := ClientDataSet1[fName]; { FieldValues 是默认的数组属性 }
  v6 := ClientDataSet1.FieldList[].Value;
  v7 := ClientDataSet1.FieldList.FieldByName(fName).Value;
  v8 := ClientDataSet1.FieldList.Find(fName).Value;
  v9 := ClientDataSet1.FieldList.Fields[].Value;   { 已知这个字段是 Double 类型的, 可同时转换 }
  num := ClientDataSet1.Fields[].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 := to ClientDataSet1.FieldCount - do
  begin
    Memo1.Lines.Add(ClientDataSet1.Fields[i].Value);
  end;
  Memo1.Lines.Add('');   for i := to ClientDataSet1.FieldList.Count - 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[].AsString;   { 读取倒数第二行第二个字段 }
  ClientDataSet1.Last;
  ClientDataSet1.Prior;
  s2 := ClientDataSet1.Fields[].AsString;   { 读取第四行第二个字段 }
  ClientDataSet1.RecNo := ;
  s3 := ClientDataSet1.Fields[].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[].Value);
    ClientDataSet1.Next;
  end;
  Memo1.Lines.Add('-------');   for i := to ClientDataSet1.RecordCount do
  begin
    ClientDataSet1.RecNo := i;
    Memo1.Lines.Add(ClientDataSet1.FieldList[].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 := to List.Count - 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[..] of AnsiChar;
begin
  ClientDataSet1.GetFieldData(ClientDataSet1.Fields[], @F1);
  ClientDataSet1.GetFieldData(ClientDataSet1.Fields[], @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 := ;
        TimeStamp.Date := Data.Date;
      end;
    ftTime:
      begin
        TimeStamp.Time := Data.Time;
        TimeStamp.Date := DateDelta;
      end;
  else
    try
      TimeStamp := MSecsToTimeStamp(Data.DateTime);
    except
      TimeStamp.Time := ;
      TimeStamp.Date := ;
    end;
  end;
  Result := TimeStampToDateTime(TimeStamp);
end; { GetCurrentRecord 是把当前行的所有字段(不包括 Blob 字段)读入到缓冲区 }
procedure TForm1.Button7Click(Sender: TObject);
type
  THoldingsStruct = packed record { 这是根据 holdings.xml 建立的数据结构 }
    ACCT_NBR: Double;
    SYMBOL: array[..] 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[5]: 读取数据的更多相关文章

  1. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  2. [MVC4]ASP.NET MVC4+EF5(Lambda/Linq)读取数据

    继续上一节初始ASP.NET MVC4,继续深入学习,感受了一下微软的MVC4+EF5(EntityFramework5)框架的强大,能够高效的开发出网站应用开发系统,下面就看一下如何用MVC4+EF ...

  3. ubuntu server 12.04U盘安装,提示无法挂载安装光盘或光盘读取数据出错

    今天用Ultraiso将Ubuntu server 12.04 刻入U盘中安装系统,中间提示错误:1.检测不到cdrom(即U盘没有挂载上):2.从光盘中读取数据出错.问题如下图所示: 上网搜了下解决 ...

  4. MySQL数据库中tinyint类型字段读取数据为true和false

    今天遇到这么一个问题,公司最近在做一个活动,然后数据库需要建表,其中有个字段是关于奖励发放的状态的字段,结果读取出来的值为true 一.解决读取数据为true/false的问题 场景: 字段:stat ...

  5. My Game --文件读取数据

    My Game --线段数据 中说到背景的绘制由贝赛尔曲线生成线段,用 DrawNode 画多边形,同时一张背景有两座山,一座山有两条以上贝赛尔曲线保存,用了嵌套的数据类:Bezier,LineLay ...

  6. Java—从文件中读取数据

    1.FileInputStream() // 构建字节输入流对象,参数为文件名 FileInputStream fin = new FileInputStream("message" ...

  7. 10天学会phpWeChat——第三天:从数据库读取数据到视图

    在第二天,我们创建了我们的第一个phpWeChat功能模块,但是比较简单.实际生产环境中,我们不可能有如此简单的需求.更多的情况是数据存储在MySql数据库中,我们开发功能模块的作用就是将这些数据从M ...

  8. 用EXCEL内嵌的Visual Basic for Application 编程,通过 UGSimple USB-GPIB 控制器来驱动仪器34401A,并从34401A读取数据

    现在市场上有很多中USB-GPIB 控制器,或叫 USB 转GPIB链接线. 每种GPIB控制器都有它的 函数库(dll库).各种GPIB 控制器的价钱插别很大.这里以一种价钱较便宜的USB-GPIB ...

  9. winform 异步读取数据 小实例

    这几天对突然对委托事件,异步编程产生了兴趣,大量阅读前辈们的代码后自己总结了一下. 主要是实现 DataTable的导入导出,当然可以模拟从数据库读取大量数据,这可能需要一定的时间,然后 再把数据导入 ...

随机推荐

  1. 【win7下安装node.js错误:roling back action】与【"grunt" 不是内部或外部命令】 解决方法

    [win7下安装node.js错误:roling back action] 解决方法: Node.js 服务器端的JavaScript Node.js 是一个基于Chrome JavaScript 运 ...

  2. linux Ubuntu Kali 安装flash

    http://jingyan.baidu.com/article/fa4125accdeeec28ad709252.html

  3. Object重写equals()、hashcode()方法的原因

    一.问题 在我们新建java对象的时候,如果后期用到对象比较,就必须重写equals(0.hashcode()方法 为什么必须重写这两个方法? 只是比较相等的话,重写equals()方法不就可以吗?为 ...

  4. stl源码分析之priority queue

    前面两篇介绍了gcc4.8的vector和list的源码实现,这是stl最常用了两种序列式容器.除了容器之外,stl还提供了一种借助容器实现特殊操作的组件,谓之适配器,比如stack,queue,pr ...

  5. Selenium2+python自动化-xpath定位语法

    前言    在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语 ...

  6. 【Jmeter测试】如何使用BeanShell断言判断请求返回的Json相应结果

      脚本结构​上图中,queryMaterialApiDTOListByPkIds是返回Json格式响应结果的请求,然后添加BeanShell断言详细判断Json结果中的值是否正确. Json格式的相 ...

  7. 4星|《财经》2018年第13期:年轻人大多从大三和大四起开始就从QQ向微信转移

    <财经>2018年第13期 总第530期 旬刊 本期主要话题是快递业,其他我感兴趣的重要话题还有:香港9价HPV疫苗断供风波:华盛顿邮报被贝佐斯收购后这几年的变化:北京二中朝阳学校的划片风 ...

  8. Atom 插件 Sync Settings 备份与恢复

    当使用 Atom IDEA.随着使用的越来越多,安装的插件也越来越多,一旦电脑重装后需要复原开发环境,这将是一件比较头疼的事.「Sync Settings」插件可以帮助我们解决这个问题. 操作流程 安 ...

  9. JAVA学习笔记--匿名内部类

    匿名内部类,即没有名字的内部类. 我们在编写JAVA程序时,往往要创建很多类,类是可以被重复使用的.但有时,我们创建了一个类,却只需要使用该类一次,那么单独为其编写一个类就显得有些麻烦,这时可以使用匿 ...

  10. day02——作业讲解

    # 设定⼀个理想数字⽐如:66,让⽤户输⼊数字,如果⽐66⼤,则显示猜测# 的结果⼤了:如果⽐66⼩,则显示猜测的结果⼩了;只有等于66,显示猜测结果# 正确,然后退出循环 #升级版# 可以帮我们生成 ...