![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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 ручками пишешь и считаешь?