zoukankan      html  css  js  c++  java
  • 修复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;
  • 相关阅读:
    贪心——poj百炼3468:电池寿命
    贪心——部分背包
    C++编程规范
    调和级数求和
    人工神经网络
    Latex各种符号
    poj1088 滑雪,dp
    数据挖掘建模过程
    Java MyEclipse:The type java.lang.CharSequence cannot be resolved. It is indirectly referen
    Java调用阿里云短信接口发送手机验证码
  • 原文地址:https://www.cnblogs.com/jupt/p/4278605.html
Copyright © 2011-2022 走看看