修复DBGrideh使用TMemTableEh在Footers求平均值为0的Bug
在一个项目中,使用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的更多相关文章
- python 录入姓名和成绩, 并且求平均值
lst = []while 1: a = input("请输入学生的姓名和成绩(姓名_成绩), 输入Q退出录入:") if a.upper() == "Q": ...
- PAT-乙级-1054. 求平均值 (20)
1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...
- excl剔除不合格数据求平均值
excl剔除不合格数据求平均值 trimmean函数 正态分布: CONFIDENCE.NORM 函数
- 深度学习原理与框架-图像补全(原理与代码) 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 ...
- JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出
rs = require("readline-sync"); let arr = []; console.log("请输入数组的长度:"); let arr_l ...
- Linux下的计算命令和求和、求平均值、求最值命令梳理
在Linux系统下,经常会有一些计算需求,那么下面就简单梳理下几个常用到的计算命令 (1)bc命令bc命令是一种支持任意精度的交互执行的计算器语言.bash内置了对整数四则运算的支持,但是并不支持浮点 ...
- PAT 乙级 1054 求平均值 (20) C++版
1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...
- C# Linq to Entity Lamda方式分组并求和求平均值
1.单字段分组并求和: var list = data.GroupBy(g => g.GoodsId).Select(e => new { GoodsId = e.Key, Qty = e ...
- PAT 1054 求平均值 (20)(代码+思路+测试用例)
1054 求平均值 (20)(20 分) 本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是[-1000,1000]区 ...
随机推荐
- C++何时使用引用
- idea展现目录清晰方式
- 1001.害死人不偿命的(3n+1)猜想
题目截图: 思路: 简单模拟.具体见另一篇博客. 代码: /* 1001.害死人不偿命的(3n+1)猜想 */ #include <stdio.h> #include <string ...
- objective-C中的"非正式协议"和“正式协议”
objective-C中的接口与泛型 先承认我是标题党,因为在obj-c的世界中,官方根本没有"接口"与"泛型"这样的说法. 不过在obj-c中有二个与之接近的 ...
- sql中问号是干什么的??
第一次在后台 程序中遇到sql语句中的问号: /** * * 方法描述 : 通过账号id更新该账号状态 * @param state 状态 * @param id 账号id */ @Modifying ...
- MySQL数据库篇之初识数据库
主要知识点: 一.数据库概述 二.mysql安装与基本管理 1️⃣ 数据库概述 1.什么是数据(Data)? 描述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字.图片,图像.声音. ...
- JAVA中集合转数组遍历
JAVA中集合的遍历的一种方法时集合转数组遍历,也是就调用Collection中的toArray(). 代码: public static void main(String[] args) { ...
- Codeforces 712D DP
题意:有2个人玩游戏,他们都有个初始值a和b, 游戏进行t轮, 每次可以选择加上一个[-k, +k]之间的数字,问有多少种方案a的和严格大于b的和. 思路:如果不考虑多于这个条件,只是询问有多少种方案 ...
- 53-C++ CH08 01
http://lx.lanqiao.cn/problem.page?gpid=T407 算法训练 C++ CH08 01 时间限制:1.0s 内存限制:256.0MB 问题描述 已 ...
- Redis学习(1)——下载与配置[转]
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主 ...