在一个项目中,使用DBGrideh,当使用自带的内存数据集时,对于Footers添加的求平均值,一直显示为0,其他汇总数据都是可以的,而切换使用TClientDataSet或者TADODataSet,所有汇总数据包括平均值都有值。

打开相关部分源码查看了下,发现DBGrideh自带的内存数据集关于汇总平均数这块,竟然没有处理……,什么情况?

原始相关函数:

procedure TCustomMemTableEh.GetAggregatedValuesForRange(FromBM, ToBM: TUniBookmarkEh;
FieldName: String; var ResultArr: TAggrResultArr; AggrFuncs: TAggrFunctionsEh);
var
FromRN, ToRN: Integer;
i: Integer;
v: Variant;
VarTypeNum: Integer;
FieldIndex: Integer;
begin
ResultArr[agfSumEh] := Null;
ResultArr[agfCountEh] := ;
ResultArr[agfAvg] := Null;
ResultArr[agfMin] := Null;
ResultArr[agfMax] := Null;
if not Active then Exit;
if FromBM <> NilBookmarkEh then
if UniBookmarkValid(FromBM)
then FromRN := UniBookmarkToRecNo(FromBM)
else Exit
else
FromRN := ;
if ToBM <> NilBookmarkEh then
if UniBookmarkValid(ToBM)
then ToRN := UniBookmarkToRecNo(ToBM)
else Exit
else
ToRN := RecordCount; if (FieldName = '') and (AggrFuncs = [agfCountEh]) then
begin
for i := FromRN- to ToRN- do
ResultArr[agfCountEh] := ResultArr[agfCountEh] + ;
Exit;
end; if FRecordsView.MemTableData.DataStruct.FindField(FieldName) = nil then
Exit;
VarTypeNum := FRecordsView.MemTableData.DataStruct.FieldByName(FieldName).GetVarDataType;
FieldIndex := FRecordsView.MemTableData.DataStruct.FieldIndex(FieldName);
for i := FromRN- to ToRN- do
begin
v := FRecordsView.RecordView[i].Rec.Value[FieldIndex, dvvValueEh];
if not VarIsNullEh(v) then
begin
if (agfCountEh in AggrFuncs) or (agfAvg in AggrFuncs) then
ResultArr[agfCountEh] := ResultArr[agfCountEh] + ; //当设置求平均值时,此处仅仅做了一次记数累计
if (VarTypeNum in [varSmallint, varInteger, varSingle, varDouble, varCurrency,
{$IFDEF EH_LIB_6}
varShortInt, varWord, varInt64, varLongWord,
{$ENDIF}
varByte, varDate]) or (VarTypeNum = varFMTBcd) then
begin
if (agfSumEh in AggrFuncs) and (VarTypeNum <> varDate) then
if VarIsNullEh(ResultArr[agfSumEh])
then ResultArr[agfSumEh] := v
else ResultArr[agfSumEh] := ResultArr[agfSumEh] + v; if agfMin in AggrFuncs then
if VarIsNullEh(ResultArr[agfMin]) then
ResultArr[agfMin] := v
else if ResultArr[agfMin] > v then
ResultArr[agfMin] := v; if agfMax in AggrFuncs then
if VarIsNullEh(ResultArr[agfMax]) then
ResultArr[agfMax] := v
else if ResultArr[agfMax] < v then
ResultArr[agfMax] := v;
end
end;
end; if agfMax in AggrFuncs then //求平均值,此处的触发条件竟然是 agfMax ....
if not VarIsNullEh(ResultArr[agfSumEh]) then
ResultArr[agfAvg] := ResultArr[agfSumEh] / ResultArr[agfCountEh]; //此处因为没有在agfAvg时对agfSumEh 求和汇总,该值应为0;
end;

修改方法:

1、打开MemTableEh.pas

2、找到GetAggregatedValuesForRange函数,修改成如下:

procedure TCustomMemTableEh.GetAggregatedValuesForRange(FromBM, ToBM: TUniBookmarkEh;
FieldName: String; var ResultArr: TAggrResultArr; AggrFuncs: TAggrFunctionsEh);
var
FromRN, ToRN: Integer;
i: Integer;
v: Variant;
VarTypeNum: Integer;
FieldIndex: Integer;
begin
ResultArr[agfSumEh] := Null;
ResultArr[agfCountEh] := ;
ResultArr[agfAvg] := Null;
ResultArr[agfMin] := Null;
ResultArr[agfMax] := Null;
if not Active then Exit;
if FromBM <> NilBookmarkEh then
if UniBookmarkValid(FromBM)
then FromRN := UniBookmarkToRecNo(FromBM)
else Exit
else
FromRN := ;
if ToBM <> NilBookmarkEh then
if UniBookmarkValid(ToBM)
then ToRN := UniBookmarkToRecNo(ToBM)
else Exit
else
ToRN := RecordCount; if (FieldName = '') and (AggrFuncs = [agfCountEh]) then
begin
for i := FromRN- to ToRN- do
ResultArr[agfCountEh] := ResultArr[agfCountEh] + ;
Exit;
end; if FRecordsView.MemTableData.DataStruct.FindField(FieldName) = nil then
Exit;
VarTypeNum := FRecordsView.MemTableData.DataStruct.FieldByName(FieldName).GetVarDataType;
FieldIndex := FRecordsView.MemTableData.DataStruct.FieldIndex(FieldName);
for i := FromRN- to ToRN- do
begin
v := FRecordsView.RecordView[i].Rec.Value[FieldIndex, dvvValueEh];
if not VarIsNullEh(v) then
begin
if (agfCountEh in AggrFuncs) or (agfAvg in AggrFuncs) then
ResultArr[agfCountEh] := ResultArr[agfCountEh] + ;
if (VarTypeNum in [varSmallint, varInteger, varSingle, varDouble, varCurrency,
{$IFDEF EH_LIB_6}
varShortInt, varWord, varInt64, varLongWord,
{$ENDIF}
varByte, varDate]) or (VarTypeNum = varFMTBcd) then
begin
if ((agfSumEh in AggrFuncs) or (agfAvg in AggrFuncs)) and (VarTypeNum <> varDate) then //此处修改
if VarIsNullEh(ResultArr[agfSumEh])
then ResultArr[agfSumEh] := v
else ResultArr[agfSumEh] := ResultArr[agfSumEh] + v; if agfMin in AggrFuncs then
if VarIsNullEh(ResultArr[agfMin]) then
ResultArr[agfMin] := v
else if ResultArr[agfMin] > v then
ResultArr[agfMin] := v; if agfMax in AggrFuncs then
if VarIsNullEh(ResultArr[agfMax]) then
ResultArr[agfMax] := v
else if ResultArr[agfMax] < v then
ResultArr[agfMax] := v;
end
end;
end; if agfAvg in AggrFuncs then //此处修改
if not VarIsNullEh(ResultArr[agfSumEh]) then
ResultArr[agfAvg] := ResultArr[agfSumEh] / ResultArr[agfCountEh];
end;

修复DBGrideh使用TMemTableEh在Footers求平均值为0的Bug的更多相关文章

  1. python 录入姓名和成绩, 并且求平均值

    lst = []while 1: a = input("请输入学生的姓名和成绩(姓名_成绩), 输入Q退出录入:") if a.upper() == "Q": ...

  2. PAT-乙级-1054. 求平均值 (20)

    1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...

  3. excl剔除不合格数据求平均值

    excl剔除不合格数据求平均值 trimmean函数 正态分布: CONFIDENCE.NORM 函数

  4. 深度学习原理与框架-图像补全(原理与代码) 1.tf.nn.moments(求平均值和标准差) 2.tf.control_dependencies(先执行内部操作) 3.tf.cond(判别执行前或后函数) 4.tf.nn.atrous_conv2d 5.tf.nn.conv2d_transpose(反卷积) 7.tf.train.get_checkpoint_state(判断sess是否存在

    1. tf.nn.moments(x, axes=[0, 1, 2])  # 对前三个维度求平均值和标准差,结果为最后一个维度,即对每个feature_map求平均值和标准差 参数说明:x为输入的fe ...

  5. JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出

    rs = require("readline-sync"); let arr = []; console.log("请输入数组的长度:"); let arr_l ...

  6. Linux下的计算命令和求和、求平均值、求最值命令梳理

    在Linux系统下,经常会有一些计算需求,那么下面就简单梳理下几个常用到的计算命令 (1)bc命令bc命令是一种支持任意精度的交互执行的计算器语言.bash内置了对整数四则运算的支持,但是并不支持浮点 ...

  7. PAT 乙级 1054 求平均值 (20) C++版

    1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...

  8. C# Linq to Entity Lamda方式分组并求和求平均值

    1.单字段分组并求和: var list = data.GroupBy(g => g.GoodsId).Select(e => new { GoodsId = e.Key, Qty = e ...

  9. PAT 1054 求平均值 (20)(代码+思路+测试用例)

    1054 求平均值 (20)(20 分) 本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是[-1000,1000]区 ...

随机推荐

  1. nginx作用

    图解nginx作用:

  2. 【CentOS 6.5】 安装VNCServer及配置,注销处理

    如果没有安装VNCServer,只有在机器上登录进桌面后才可以通过VNC连接,否则连不上... 安装: yum install tigervnc-server   运行并设置密码: vncserver ...

  3. TCP粘包拆包场景

    TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输的时候,在网络中的byte其实就像是河水,TCP就像一个搬运工,将这流水从一端转送到另一端,这时又分两种情况: 1)如 ...

  4. 项目通过nginx强转为https访问后,代码中重定向的连接又变成了http协议,导致点击页面按钮,后台逻辑处理完后重定向报错了

    修改如下,需要在nginx对应的server下的location中增加配置,使重定向的地址协议取当前链接的协议,而不是nginx访问tomcat的协议,因为nginx访问tomcat是http的,并没 ...

  5. Windows下DOS命令大全(经典收藏)

    copy \\ip\admin$\svv.exe c:\ 或:copy\\ip\admin$\*.* 复制对方admini$共享下的srv.exe文件(所有文件)至本地C: xcopy 要复制的文件或 ...

  6. jira 安装

    jira jira是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪(bug管理).客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域.同禅道等类似. 安装前准备 ...

  7. IE WebDeveloper--IE浏览器web调试工具

    目前市面上比较火爆的浏览器内核提供商,有微软的IE.mozilla的firefox.谷歌的chrome.苹果的safari.IE浏览器下的项目过去占比非常大,近年随着其他浏览器厂商发展势头迅猛,过去的 ...

  8. openLDAP 2

    一.安装OPENLDAP 二.打开安装目录中的文件 slapd.conf 三.安装完成后退出 编辑文本,输入以下内容,并命名为test.ldif dn: dc=company objectClass: ...

  9. Eclipse快捷键大全(补充)

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+Shift+O 自动导入所需要的包(这个用的次数也相当多)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增 ...

  10. [C++] How to prevent memory leaks

    How to prevent memory leaks ? overload new/delete