在一个项目中,使用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. GDI/GDI+这些破事

    本文是杂篇,纯属笔记,想到哪写到那! 1.获取像素的RGB以及填充 CPaintDC dc(m_hWnd); COLORREF color=dc.GetPixel(,); int R=GetRValu ...

  2. linux weather

  3. i++的原子性问题

    一.什么是原子性 简单的可以理解为:操作是不可再分割的,比如: int i=0; 但是i++的操作是可以再分的,比如: i++ //分解后 i=i+i 上面的代码在多线程环境下取值是有问题的,比如: ...

  4. 使用copy函数输出容器中的内容

    container<type> c; 输出语句为:copy(c.begin(), c.end(), ostream_iterator<type>(cout, " &q ...

  5. mysql 锁 事务隔离级别

    主题 最近在看mysql相关的书籍.实验了一些内容.分享一下,主要是关于事务隔离级别(read-committed和repeatable-read)和锁相关的. 很多网上文章上都能搜索到 read-c ...

  6. com.mysql.jdbc.exceptions.jdbc4.CommunicationsException/com.atomikos.datasource.ResourceException异常解决

    tomcat+mysql部署,每天早晨第一次访问web项目,出现mysql的连接timeout异常:com.mysql.jdbc.exceptions.jdbc4.CommunicationsExce ...

  7. 数据库连接池--druid

    数据库连接池常用的有:dbcp,c3p0,druid 代码仓库(https://github.com/) package com.huawei.test; import java.sql.Connec ...

  8. 在SharePoint解决方案中使用JavaScript (2) – 模块化

    本文是在SharePoint中使用JavaScript的第二篇文章,前面的文章包括: 在SharePoint解决方案中使用JavaScript (0) 在SharePoint解决方案中使用JavaSc ...

  9. java基础强化——深入理解反射

    目录 1.从Spring容器的核心谈起 2. 反射技术初探 2.1 什么是反射技术 2.2 类结构信息和java对象的映射 3 Class对象的获取及需要注意的地方 4. 运行时反射获取类的结构信息 ...

  10. VUE+WebPack游戏设计:欲望都市城市图层的设计