修复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]区 ...
随机推荐
- Python操作中缓存Redis
Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- 关于jquery.noConflict()的学习记录
今天无意中看到了jquery.noConfict()的实现方法 代码如下: var // Map over jQuery in case of overwrite _jQuery = window.j ...
- 获取properties配置
1. 使用@Value @Value("${swagger.enable}") 使用Spring的PropertyPlaceholderConfigurer关联 @Val ...
- Python格式符说明
格式化输出 例如我想输出 我的名字是xxxx 年龄是xxxx name = "Lucy"age = 17print("我的名字是%s,年龄是%d"%(name, ...
- Python 调用阿里云 API 收集 ECS 数据
#!/usr/bin/env python # coding: utf-8 # author: Wang XiaoQiang ''' 功能介绍: 1.调用阿里云API,收集所有区域 ECS 信息 2. ...
- Java Socket编程之UDP
UDP编程: 将要传输的数据定义成数据包(Datagram),在数据报中指明所要到达的Socket(主机地址和端口号),然后再将数据报发送出去. 相关操作类: DatagramPacket ...
- Invoke and BeginInvoke(转载:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html)
一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dotnet程序员众所周知的,我在此费点笔墨再次记录到自己的日志,以便日后提醒一下自己. 1 ...
- java反射对实体类取值和赋值,可以写成通过实体类获取其他元素的数据,很方便哦~~~
项目中需要过滤前面表单页面中传过来的实体类的中的String类型变量的前后空格过滤,由于前几天看过一个其他技术博客的的java反射讲解,非常受益.于是,哈哈哈 public static <T& ...
- Opencv3 图片膨胀与腐蚀
#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...
- 410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小
[抄题]: Given an array which consists of non-negative integers and an integer m, you can split the arr ...