Модераторы: alexs, Модераторы
function TRxColumnFooter.ErrorTestValue: boolean;
var
  F: TField;
begin
  Result := True;
  if ValueType in [fvtSum, fvtAvg, fvtMax, fvtMin] then
  begin
    F := TRxDBGrid(FOwner.Grid).DataSource.DataSet.FieldByName(FFieldName);
    if Assigned(F) then
    begin
      if F.DataType in [ftDate, ftTime, ftDateTime, ftTimeStamp] then
      begin
        if (FValueType in [fvtMax, fvtMin]) and not (F.IsNull) then
        begin
          if not (F.IsNull) and (FTestValue = F.AsDateTime) then
            Result := False
          else
          if (F.DataSet.RecordCount <> 0) and (F.OldValue <> null) then
          begin
            case FValueType of
              fvtMax: FTestValue := Max(FTestValue, TDateTime(F.OldValue));
              fvtMin: FTestValue := Min(FTestValue, TDateTime(F.OldValue));
            end;
          end;
        end;
      end
      else
      if (FValueType in [fvtMax, fvtMin]) and not (F.IsNull) and (FTestValue = F.AsFloat) then
        Result := False
      else
      begin
        case FValueType of
          fvtSum:
            if F.DataSet.RecordCount = 0 then
            begin
{              if not F.IsNull then
                FTestValue := FTestValue - F.AsFloat;}
              { TODO -oalexs : need rewrite this code - where difficult! }
            end
            else
            begin
                     if not F.IsNull then
                        if F.OldValue <> null then
                           FTestValue := FTestValue + Float(F.OldValue);
                        if not F.IsNull then
                           FTestValue := FTestValue - F.AsFloat;
            end;
          fvtMax:
            if (F.DataSet.RecordCount <> 0) and (F.OldValue <> null) then
              FTestValue := Max(FTestValue, Float(F.OldValue));
          fvtMin:
            if (F.DataSet.RecordCount <> 0) and (F.OldValue <> null) then
              FTestValue := Min(FTestValue, Float(F.OldValue));
        end;
      end;
    end;
  end;
end;procedure TRxDBGrid.UpdateActive;
begin
  if FInProcessCalc > 0 then
    exit;
  inherited UpdateActive;
  if FInProcessCalc < 0 then
  begin
    FInProcessCalc := 0;
    CalcStatTotals;
  end
  else
  if Assigned(FFooterOptions) and FFooterOptions.Active and (FFooterOptions.RowCount > 0) and
       DatalinkActive and (DataSource.DataSet.State = dsBrowse) then
    CalcStatTotals; //здесь вылетает ошибка
end;procedure TRxDBGrid.CalcStatTotals;
var
  P: TBookmark;
  DS: TDataSet;
  i: integer;
  APresent: boolean;
begin
  if (not (FFooterOptions.Active and DatalinkActive)) or (Columns.Count = 0) or
       (DataSource.DataSet.RecordCount<=0)  //проверка наличия строк
   then
    Exit;
  //Дополнительно проверим - а стоит ли делать пробег по данным - есть ли агрегатные функции
  APresent := False;
  for i := 0 to Columns.Count - 1 do
  begin
    APresent := TRxColumn(Columns[i]).Footer.FValueType in
      [fvtSum, fvtAvg, fvtMax, fvtMin];
    if APresent then
      break;
  end;   
...
function TRxColumnFooter.GetStatTotal: string;
var
  F: TField;
begin
  if (FFieldName <> '') and TRxDBGrid(FOwner.Grid).DatalinkActive and
    (TRxDBGrid(FOwner.Grid).DataSource.DataSet.RecordCount <> 0) then
  begin
    F := TRxDBGrid(FOwner.Grid).DataSource.DataSet.FieldByName(FFieldName);
    if Assigned(F) then
    begin
     if F.DataType in [ftSmallint, ftLargeint, ftInteger, ftWord, ftFloat, ftCurrency,
        ftDate, ftTime, ftDateTime, ftTimeStamp] then
      begin
        if F.DataType in [ftDate, ftTime, ftDateTime, ftTimeStamp] then
        begin
          if FValueType in [fvtSum, fvtAvg] then
            Result := ''
          else
          if FTestValue = 0 then
            Result := ''
          else
          if FDisplayFormat = '' then
            Result := DateToStr(FTestValue)
          else
            Result := FormatDateTime(FDisplayFormat, FTestValue);
        end
        else
        if F.DataType in [ftSmallint, ftInteger, ftWord] then
        begin
          if FDisplayFormat = '' then
            Result := IntToStr(Round(FTestValue))
          else
            Result := Format(FDisplayFormat, [Round(FTestValue)]);
        end
        else
        begin
          if FDisplayFormat <> '' then
            Result := FormatFloat(FDisplayFormat, FTestValue)
          else
          if F.DataType = ftCurrency then
            Result := FloatToStrF(FTestValue, ffCurrency, 12, 2)
          else
            Result := FloatToStr(FTestValue);
        end;
      end
      else
        Result := '';
    end
    else
      Result := '';
  end
  else
    Result := '';
end;  



 я понимаю что эту проблему решать мне, у меня вопрос именно практический
 я понимаю что эту проблему решать мне, у меня вопрос именно практическийкаким образом формируется FTestValue?
    for i := 0 to Columns.Count - 1 do
      TRxColumn(Columns[i]).Footer.ResetTestValue;

Но в последних комитах я убрал из TRxDBGrid.UpdateActive пересчёт итогов. Сейчас этот метод грида изменяется на каждое изменение положения курсора в наборе данных. Получается лишние вызовы и глюки при движению по гриду, содержимое которого превышает размер самого грида.
Ещё не придумал как обойти...
 раскомментировал данную строку, итоги в detail таблицах стал считать (это когда по master гриду ходишь), но гриды действительно глючат в таком режиме... как быть?
 раскомментировал данную строку, итоги в detail таблицах стал считать (это когда по master гриду ходишь), но гриды действительно глючат в таком режиме... как быть? 
 

alexs писал(а):Когда началось?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1