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

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

DBLookupComboBox и его потомки


Desdechado ©   (2003-07-30 11:17:00) 

Пишу компонент-наследник, ибо раздражает такое поведение, когда при отсутствии ключа в справочнике он показывает пустое поле.
Вопрос: как узнать (событие или еще что-то), что нужный ключ из просматриваемой таблицы DataSource отсутствует в справочнике ListSource?
Можно ли сделать к этому событию внешний обработчик, чтобы при необходимости перечитать справочник?


Desdechado   (2003-07-30 17:09:00) [1]

2 ЮЮ © (30.07.03 12:40)
Спасибо за наводку, стормозил - можно же переопределять методы деда, а не только отца :)
В итоге получилось так (хотя за абсолютную корректность не поручусь):
function TfvDBLookupComboBox.LocateKey(): Boolean;
var
xKeySave: Variant;
begin
result := False;
if( FRefreshing ) then
Exit;
with( ListLink.DataSet ) do
try
xKeySave := KeyValue;
if( Active and ( not VarIsNull( KeyValue ) ) ) then
if( Locate( KeyField, KeyValue, [] ) ) then
begin
result := True;
KeyValue := xKeySave;
end
else if( FListRefreshable ) then
begin
FRefreshing := True;
Close;
Open;
FRefreshing := False;
if( Locate( KeyField, KeyValue, [] ) ) then
begin
result := True;
KeyValue := xKeySave;
end
else
DatabaseError( rc_DataKeyNotInList, Self );
end
else
( rc_DataKeyNotInList, Self)

2 ЮЮ © (30.07.03 12:40)
Спасибо за наводку, стормозил - можно же переопределять методы деда, а не только отца :)
В итоге получилось так (хотя за абсолютную корректность не поручусь):
function TfvDBLookupComboBox.LocateKey(): Boolean;
var
xKeySave: Variant;
begin
result := False;
if( FRefreshing ) then
Exit;
with( ListLink.DataSet ) do
try
xKeySave := KeyValue;
if( Active and ( not VarIsNull( KeyValue ) ) ) then
if( Locate( KeyField, KeyValue, [] ) ) then
begin
result := True;
KeyValue := xKeySave;
end
else if( FListRefreshable ) then
begin
FRefreshing := True;
Close;
Open;
FRefreshing := False;
if( Locate( KeyField, KeyValue, [] ) ) then
begin
result := True;
KeyValue := xKeySave;
end
else
DatabaseError( rc_DataKeyNotInList, Self );
end
else
DatabaseError( rc_DataKeyNotInList, Self );
except
end; // try & with
end;

FRefreshing нужно потому, что при Open вызывается опять LocateKey и будет зацикливание


ЮЮ   (2003-07-30 12:40:00) [2]

Смотрим метод предка:

function TDBLookupControl.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active and
FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
begin
Result := True;
FKeyValue := KeySave;
end;
except
end;
end;

Перекрываем своим

function T DesdechadoDBLookupСombobox.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active then
( FKeyFieldName, FKeyValue, [])

Смотрим метод предка:

function TDBLookupControl.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active and
FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
begin
Result := True;
FKeyValue := KeySave;
end;
except
end;
end;

Перекрываем своим

function TDesdechadoDBLookupСombobox.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active then
if FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
begin
Result := True;
FKeyValue := KeySave;
end
else
begin
// здесь переоткрываем FListLink.DataSet и делаем Locate
end;
except
end;
end;


Desdechado   (2003-07-30 12:30:00) [3]

2 ЮЮ © (30.07.03 11:56)
> основной запрос ты переоткрыл, коль попали записи с пустыми полями
Записи не с пустыми полями, а заполненные легитимными кодами из справочника. Но программа о них еще не знает. А надо, чтоб узнала. И хотелось бы именно через TDBLookupComboBox, поскольку он все равно такой поиск соответствий проводит.


Desdechado   (2003-07-30 12:13:00) [4]

2 Sergey13 © (30.07.03 11:56)
Только не надо ерничать. Лучше бы дело посоветовал.
Справочники большие и их много, а лишний траффик ни к чему.

2 ЮЮ © (30.07.03 11:56)
Дело в том, что TDBLookupComboBox - это всего лишь визуальный наследник другого класса, который весь такой lookup-поиск попрятал в private-методах. От него наследоваться тоже смысла нет, а дублировать иерархию классов в своем модуле только ради этой фишки не очень хочется.
Основной запрос может быть разный в разных местах программы, а справочник к нему может быть и один.


ЮЮ   (2003-07-30 11:56:00) [5]

>Вопрос: как узнать (событие или еще что-то), что нужный ключ из просматриваемой таблицы DataSource отсутствует в справочнике ListSource?

Ты же пишешь наследника, значит смотри код методов родителя, где что-то заставляет это "писать"(искать), а если пишется "пусто", а поле не пусто, там и переоткрывай источник. Если метод можно перекрыть, перекрой, и делай, что хочешь.

>чтобы при обнаружении его устарелости (кто-то с другого рабочего места пополнил справочник) происходило перечитывание, но только в этом случае, а не каждый раз.

Но основной запрос ты же переоткрыл, коль попали записи с пустыми полями, почему бы при этом не переоткрывать запросы к справочникам?


Sergey13   (2003-07-30 11:56:00) [6]

То все гриды у людей сами не обновлялись. Теперь очередь до комбобоксов дошла. 8-)


Desdechado   (2003-07-30 11:34:00) [7]

Нет, справочник грузится однажды при входе в программу.
Хотелось бы, чтобы при обнаружении его устарелости (кто-то с другого рабочего места пополнил справочник) происходило перечитывание, но только в этом случае, а не каждый раз.


Соловьев   (2003-07-30 11:21:00) [8]


> когда при отсутствии ключа в справочнике он показывает пустое
> поле.

что же это за справочник? ты id ручками пишешь и считаешь?


Наверх

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