文档章节

TClientDataSet[9]: 计算字段和 State

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 827
阅读 5
收藏 0

TClientDataSet 中计算字段有两种: Calculated(计算字段)、InternalCalc(内部计算字段).

两者区别是: Calculated 在每次需要时都要重新计算; InternalCalc 只需要计算一次.
Calculated 需要计算的时间, InternalCalc 需要存取的时间; 当然后者快.

计算字段不会被保存到文件.

下面的例子先定义了两个整数字段: sum1、sum2;
又定义了两个计算字段: SUM(求和)、MUL(求积), 分别指定了 Calculated、InternalCalc.

计算是在 TClientDataSet 的 OnCalcFields 事件中完成的, 每当需要计算结果时事件会被自动激活.
除了 OnCalcFields 事件中的代码外, 其他都可以在设计时完成; 这里是动态完成的.

//准备: 窗体放置 ClientDataSet1、DataSource1、DBGrid1(关联一下)、Button1
//程序运行后, 可用 Tab 和 ↑ ↓ → ← 键配合着输入测试数据.

{ 建立数据集, 包括计算字段 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TIntegerField.Create(Self) do
  begin
    FieldName := 'num1';       { FieldKind 的默认值是 fkData }
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'num2';
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'SUM';
    FieldKind := fkCalculated;  { 指定为计算字段 }
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'MUL';
    FieldKind := fkInternalCalc; { 指定为内部计算字段 }
    DataSet := ClientDataSet1;
  end;

  ClientDataSet1.CreateDataSet;
  Button1.Enabled := False;
end;

{ OnCalcFields 事件 }
procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
begin
  { 获取计算字段的值 }
  DataSet['SUM'] := DataSet['num1'] + DataSet['num2'];

  { 获取内部计算字段的值; 一般要先判断一下以避免重复运算 }
  if DataSet.State = dsInternalCalc then
    DataSet['MUL'] := DataSet['num1'] * DataSet['num2'];
end;

 
 
 
 
 

 

 

  

在上面程序的基础上再添加一个 Timer1, 为详细测试 Calculated 和 InternalCalc 的区别, 代码修改如下:
var
  Calc, InternalCalc: Integer;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  with TIntegerField.Create(Self) do
  begin
    FieldName := 'num1';
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'num2';
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'SUM';
    FieldKind := fkCalculated;
    DataSet := ClientDataSet1;
  end;

  with TIntegerField.Create(Self) do
  begin
    FieldName := 'MUL';
    FieldKind := fkInternalCalc; { 指定为内部计算字段 }
    DataSet := ClientDataSet1;
  end;
  ClientDataSet1.CreateDataSet;

  { 添加测试数据 }
  ClientDataSet1.DisableControls;
  for i := 0 to 999 do ClientDataSet1.AppendRecord([i, i]);
  ClientDataSet1.EnableControls;

  Button1.Enabled := False;
end;

procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
begin
  Inc(Calc);
  DataSet['SUM'] := DataSet['num1'] + DataSet['num2'];

  if DataSet.State = dsInternalCalc then
  begin
    Inc(InternalCalc);
    DataSet['MUL'] := DataSet['num1'] * DataSet['num2'];
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Text := Format('Calc: %d; InternalCalc: %d', [Calc, InternalCalc]);
end;

 
 
 
 
 

 

 

  

测试图:



TDataSetState.State: TDataSetState;
TDataSetState = (
dsInactive,     { 数据集被关闭 }
dsBrowse,       { 浏览模式 }
dsEdit,         { 编辑模式, 意味着 Edit 方法已被调用, 而编辑后的数据尚未被提交 }
dsInsert,       { 插入模式, 即 insert 被调用, 但变化还没有提交 }
dsSetKey,       { 设置键值模式, 意味着 SetKey 被调用, 而 GotoKey 尚未被调用 }
dsCalcFields,   { OnCalcFields 事件已发生, 对记录值的计算正在进行中 }
dsFilter,       { 数据集正在处理一个记录过滤器、查找字段或其他需要用到过滤器的操作 }
dsNewValue,     { 数据集处于 NewValue 属性被访问的临时状态 }
dsOldValue,     { 数据集处于 OldValue 属性被访问的临时状态 }
dsCurValue,     { 数据集处于 CurValue 属性被访问的临时状态 }
dsBlockRead,    { 数据正被写入缓冲区, 此时数据库表中指针的移动并不触发数据感知组件的更新和事件的发生 }
dsInternalCalc, { 一个字段值正在被计算, 以供一个有 fkInterternalCalc 类型的 Fieldkind 属性的字段使用 }
dsOpening       { 数据集处于正在打开状态但是还没有结束, 这种状态发生在数据集被异步打开时 }
);

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2010/01/28/1658768.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
TClientDataSet使用(二)

转自:http://hi.baidu.com/zwl232/blog/item/76f011dfc9543812622798f2.html TClientDataSet    与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的......

天地弦
2007/06/01
0
0
ClientDataSet探讨(1)-介绍

KeyLife富翁笔记 作者: hongxingdl 标题: ClientDataSet探讨(1)-介绍 关键字: midas 分类: 开发经验 密级: 公开 与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,...

天地弦
2004/08/06
0
0
一个ClientDataset的Delta与XML相互转换

一个ClientDataset的Delta与XML相互转换的文章: 大家都知道TClientDataSet的Delta属性保存数据集的变化,但是Delta是OleVariant类型的属性,这样如果用Delphi写Webservice,就有需要把它转成...

vga
2014/02/27
0
18
Android开发数据库三层应用-DataSnap

Android开发数据库三层应用-DataSnap 时间:2013-10-24 13:41:54 点击:4988   核心提示:我觉得Delphi最强大的的功能之一就是开发数据库三层应用的DataSnap,在Android上的实现,首先是完...

vga
2014/06/01
0
0
带有TClientDataSet的delphi应用程序在发布时应注意的问题

这两天,我把我做的拍卖的操作端发布给公司的同事试用,这些机器都没有安装过delphi环境,我的程序所有用到的组件及单元文件都是build在一块儿的,按理说就不需要其他什么文件来支持了。  本...

技术小胖子
2017/11/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

day58-20180816-流利阅读笔记-待学习

苹果市值破万亿,iPhone 会涨价吗? Lala 2018-08-16 1.今日导读 苹果教父乔布斯曾经说过:“活着就是为了改变世界。”虽然他在 56 岁时就遗憾离世,但他极具创新和变革的精神早已深埋进苹果...

aibinxiao
22分钟前
4
0
[雪峰磁针石博客]python3快速入门教程1 turtle绘图-2函数

菲波那契序列: >>> # Fibonacci series:... # the sum of two elements defines the next... a, b = 0, 1>>> while b < 10:... print(b)... a, b = b, a+b...112......

python测试开发人工智能安全
今天
0
0
java环境变量配置最正确的方式

原贴:https://blog.csdn.net/qq_40007997/article/details/79784711,十分详细,亲测有效

kitty1116
今天
0
0
49.Nginx防盗链 访问控制 解析php相关 代理服务器

12.13 Nginx防盗链 12.14 Nginx访问控制 12.15 Nginx解析php相关配置(502的问题) 12.16 Nginx代理 扩展 502问题汇总 http://ask.apelearn.com/question/9109 location优先级 http://blog....

王鑫linux
今天
2
0
Nginx防盗链、访问控制、解析php相关配置、Nginx代理

一、Nginx防盗链 1. 编辑虚拟主机配置文件 vim /usr/local/nginx/conf/vhost/test.com.conf 2. 在配置文件中添加如下的内容 { expires 7d; valid_referers none blocked server_names *.tes......

芬野de博客
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部