2013-07-28 3 views
10

У меня есть ClientDatSet с несколькими полями fkInternalCalc. CDS не связан ни с одним провайдером; вместо этого он заполняется на лету. Как я могу заставить CDS пересчитать все «исчисляемые» поля? Я не могу позвонить Refresh(), потому что у вас нет провайдера для обновления данных. Единственный способ, с которым я пришел, заключался в том, чтобы перемещаться по всем записям, что не самый лучший способ.Как заставить Client DataSet пересчитать расчетные и внутренние расчетные поля?

PS: Я прочитал this question и this post, но я надеюсь на более элегантный способ.

+0

Итак, закрытие - открытие набора данных не работает? –

+0

@SertacAkyuz Я еще не пробовал. Не закрывает ли клиентский набор данных все данные в нем? –

+0

Несомненно. ......... –

ответ

8

Я достигаю этого с помощью вспомогательного помощника (отделяется здесь до необходимого), что позволяет вызывать защищенные методы без каких-либо взломов. Обязательно проверьте на DataSet.State = dsInternalCalc внутри полей OnCalcFields для полей fkInternalCalc.

type 
    TClientDataSetHelper = class helper for TClientDataSet 
    public 
    function AssureEditing: Boolean; 
    procedure InternalCalc; 
    end; 

function TClientDataSetHelper.AssureEditing: Boolean; 
begin 
    result := not (State in [dsEdit, dsInsert]); 
    if result then 
    Edit; 
end; 

procedure TClientDataSetHelper.InternalCalc; 
var 
    needsPost: Boolean; 
    saveState: TDataSetState; 
begin 
    needsPost := AssureEditing; 
    saveState := setTempState(dsInternalCalc); 
    try 
    RefreshInternalCalcFields(ActiveBuffer); 
    finally 
    RestoreState(saveState); 
    end; 
    if needsPost then 
    Post; 
end; 

Это может быть легко расширена для обычных расчетных полей с помощью CalculateFields. Хотя это не обязательно, поскольку расчетные поля пересчитываются всякий раз, когда меняется любое другое поле данных.

+0

Я пробовал это и получаю * "[dcc32 Error] dMyDataModule.pas (151): E2389 Защищенный член TDataSet.RefreshInternalCalcFields здесь недоступен *. – GolezTrol

+0

@GolezTrol, выглядит как ошибка. Работает в XE3, но не в XE7 и XE8 (в настоящее время нельзя проверить XE4 на XE6). Другие защищенные члены прекрасно доступны: «setTempState», «RestoreState». Только что сообщено как RSP-11337. –

+0

Чтобы сузить его, я был на XE5. Спасибо за тестирование! Я решил это сейчас, используя более классический помощник класса: typecasting для локально определенного 'THackClientDataSet = class (TClientDataSet)'. – GolezTrol

-1

Это немного взломанный, но он работает!

DBGrid.Height := 30; 
DBGrid.Height := 200; // Refresh all Rows after first 
CalculatedProc(DataSet); // Refresh first calculated fields. (Write name of your calculate procedure) 
+0

Как это улучшает уже принятый ответ? –

+0

1. Использовал функцию по умолчанию Delphi 2. Кадр 3. Простой –

+0

4. Быстрее, чем использовать состояния изменения! –

Смежные вопросы