修复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;

 

你可能感兴趣的:(table)