Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не работают Lookup-поля, если есть поля вида fkInternalCalc ! [D6, IB6.x]


kaif ©   (2004-07-15 21:08:00) 

Ненормально работают Lookup-поля, если в DataSet есть поля вида fkInternalCalc
 При употреблении вычисляемых полей в базе данных IB столкнулся со странной вещью.
Компоненты IBDataSet перестали изменять значения lookup-полей полей в момент редактирования. Целый день не мог понять, что происходит, пока не обнаружил, что если в наборе данных имеется хотя бы одно поле с FieldKind=fkInternalCalc, то поля fkLookup при изменении ключевых значений (KeyFields) не отображают значений LookupResulField, а продолжают отображать старые значения, полученные еще при открытии запроса.

 Трассировка показала, что проблема заключается в файле db.pas Delphi.

1. Метод TField.CalcLookupValue формирует значение поля вида fkLookup
procedure TField.CalcLookupValue;
begin
 if FLookupCache then
   Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
 else if (FLookupDataSet <> nil) and FLookupDataSet.Active then
   Value := FLookupDataSet.Lookup(FLookupKeyFields,
     FDataSet.FieldValues[FKeyFields], FLookupResultField);
end;


2. Этот метод вызывается в методе TDataSet.CalculateFields
procedure TDataSet.CalculateFields(Buffer: PChar);
var
 I: Integer;
begin
 FCalcBuffer := Buffer;
 if (State <> dsInternalCalc) and (IsUniDirectional = False) then
 begin
   ClearCalcFields(CalcBuffer);
   for I := 0 to FFields.Count - 1 do
     with FFields[I] do
       if FieldKind = fkLookup then
          CalcLookupValue;
 end;
 DoOnCalcFields;
end;


3. А этот в свою очередь вызывается в местной процедуре UpdateCalcFields метода TDataSet.DataEvent

procedure TDataSet.DataEvent(Event: TDataEvent; Info: Longint);

 procedure UpdateCalcFields;
 begin
   if State <> dsSetKey then
   begin
     if FInternalCalcFieldsand (TField(Info).FieldKind = fkData) then
       RefreshInternalCalcFields(ActiveBuffer)
      elseif (FCalcFieldsSize <> 0) and FAutoCalcFields and
       (TField(Info).FieldKind = fkData) then
        CalculateFields(ActiveBuffer);
     TField(Info).Change;
   end;
 end;

.........


 Если  FInternalCalcFields = True (а это так, если хотя бы одно поле имеет вид fkInternalCalc), то CalculateFields после elseне вызывается и значение lookup-полей не обновляются. Если заменить elseточкой с запятой, то ошибка исчезает.
 Но весь вопрос в том, правильно ли исправлять db.pas? Или нужно добавлять что-то в IBX, чтобы принудительно вызывать метод CalculateFields в какой-то момент, несмотря на то, что
свойство InternalCalcFields = True?  Нигде в Help не сказано, что при InternalCalcFields = True поля типа lookup не будут
работать правильно. Поэтому я считаю это ошибкой в самой Delphi.
 Кто сталкивался с подобной проблемой? Версия Delphi 6 (в других пока не смотрел).


Johnmen   (2004-07-16 12:20:00) [1]

>kaif ©  

Лично я не сталкивался.
Думаю, если очень надо, то исходники можно подправлять. Не взирая на крик души от АП "Не трогай генофонд !"
:)))


kaif   (2004-07-16 12:11:00) [2]

Неужели никто не сталкивался?


Наверх

Титульная страница Поиск, карта сайта Написать письмо