文档章节

TClientDataSet[9]: 计算字段和 State

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 827
阅读 5
收藏 0
点赞 0
评论 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       { 数据集处于正在打开状态但是还没有结束, 这种状态发生在数据集被异步打开时 }
);

 
 
 
 
 

 

 

  

© 著作权归作者所有

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

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

天地弦 ⋅ 2007/06/01 ⋅ 0

ClientDataSet探讨(1)-介绍

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

天地弦 ⋅ 2004/08/06 ⋅ 0

一个ClientDataset的Delta与XML相互转换

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

vga ⋅ 2014/02/27 ⋅ 18

Android开发数据库三层应用-DataSnap

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

vga ⋅ 2014/06/01 ⋅ 0

带有TClientDataSet的delphi应用程序在发布时应注意的问题

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

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

Redis 源码学习之事件驱动

原文出处:天凉好个秋 基于多路复用技术实现了一套简单的事件驱动库,代码在、以及、和、这几个文件中。其中表示的是的意思。 里面包含两种事件类型:和。 采用多路复用技术,所有的事件都是在...

天凉好个秋 ⋅ 2017/06/11 ⋅ 0

Blink 漫谈系列 - State

什么是State 这个问题似乎有些"弱智"?不管问题的答案是否显而易见,但我还是想简单说一下在Blink里面什么是State?State是指流计算过程中计算节点的中间计算结果或元数据属性,比如 在aggre...

jasonli4 ⋅ 06/08 ⋅ 0

FutureTask类浅析

概述 FutureTask类是可取消式异步计算方法。该类是Future接口的基本实现。可以开启和取消异步计算,查询异步计算结果是否完成,并且抽取出计算结果。计算结果只能在异步计算完成后被获取。异...

hyssop ⋅ 2016/04/29 ⋅ 0

delphi 三层创建

所谓三层: (1) 客户端 (2) 服务器端 (3) 数据库 在数据访问时,使得客户端必须通过服务器来访问数据库。提高了系统的安全性。 在Delphi中可以使用Socket或者Dcom来连接他们相互间的通讯。如...

vga ⋅ 2014/11/25 ⋅ 0

以下sql方式效率问题。

mysql innodb 一张访问非常频繁 数据量比较大的表 A 现在要批量更新10条数据 字段 id主键 state name update A set name=? where id in (1,2,3,4,5,6,7,8,9,10) and state = 1 与 分成10条单...

chi_9 ⋅ 2015/05/05 ⋅ 4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 这样的女人私生活太混乱了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 胖达panda :你经历过体验到人生的大起大落吗?我一朋友在10秒内体验了,哈哈。@小小编辑 请点一首《almost lover》送给他。 《almost love...

小小编辑 ⋅ 44分钟前 ⋅ 7

自己动手写一个单链表

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对...

公众号_好好学java ⋅ 50分钟前 ⋅ 0

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部