修复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] := 0; 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 := 1; 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-1 to ToRN-1 do ResultArr[agfCountEh] := ResultArr[agfCountEh] + 1; 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-1 to ToRN-1 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] + 1; //当设置求平均值时,此处仅仅做了一次记数累计 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] := 0; 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 := 1; 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-1 to ToRN-1 do ResultArr[agfCountEh] := ResultArr[agfCountEh] + 1; 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-1 to ToRN-1 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] + 1; 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;
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。