DBGridEh + onDataChange + TForm.Create = проблема.

Вопросы стыковки визуальных компонент (DataControls, EhGrid, VirtualTreeView, DevExpress и т.п.) с данными из БД.

Модераторы: kdv, CyberMax

Ответить
S.H.S
Сообщения: 65
Зарегистрирован: 25 ноя 2005, 02:18

DBGridEh + onDataChange + TForm.Create = проблема.

Сообщение S.H.S » 04 дек 2007, 00:18

П О М О Г И Т Е !!!
Есть DBGridEh, он привязан к DataSet через DataSource, у которого есть событие onDataChange:

Код: Выделить всё

procedure TFDM1.DtSrcCtrlODataChange(Sender: TObject; Field: TField);
begin
 if QrCtrlO.State = dsBrowse then
  FCtrl_O.DBGrdCtrlO.Hint:=QrCtrlOSERIAL_NUM.AsString;
end;
Динамически создаем форму с DBGridEh и в событии Create делаем DataSet.Active:=True;
И где то между этим Active и появлением грида вылазит это:
Access violation at addres... (я думаю все писать нет смысла).
Мои подозрения, что не успевает создатся DBGridEh, так как я пробовал DataSet.Active:=True поставить на нажатие кнопки после создания формы, то все OK.
Помогите, очень нужно, дело не в Hint, это я для примера.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 04 дек 2007, 07:20

Все что делается визуально нужно не в OnCreate, а в OnShow засовывать тогда.

DataSet.Active:=True; можно в OnCreate засунуть, но предварительно убрав у него обработку событий, которую потом надо все равно присвоить в OnShow или в самой обработке отлавливать ошибки и разные состояния.

S.H.S
Сообщения: 65
Зарегистрирован: 25 ноя 2005, 02:18

Сообщение S.H.S » 04 дек 2007, 09:54

К сожалению, не так все просто.
Я пробовал ставить и в onShow и даже в onActivate, но ошибка таже.
Пробовал и так:

Код: Выделить всё

 DataSet.DisableControls;
 try
  DataSet.Active:=True;
 finally
  DataSet.EnableControls;
 end;
Но все без изменений.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 04 дек 2007, 11:45

А отладчик это AV ловит? Смотрите Call Stack.

S.H.S
Сообщения: 65
Зарегистрирован: 25 ноя 2005, 02:18

Сообщение S.H.S » 05 дек 2007, 01:14

Я просмотрел Call Stack, а так же прогнал через чудодейственную программу-компонент EurekaLog. Я знаю, что вызывает исключение, но это мне никак не помогло :(.
На вершине стека, естественно, моя функция:
FCtrl_O.DBGrdCtrlO.Hint:=QrCtrlOSERIAL_NUM.AsString;
Далее идет:
inherited DataEvent(Event,Info) (это DB.pas); из процедуры procedure TFIBCustomDataSet.DataEvent(Event: TDataEvent; Info: Longint); (это FIBDataSet)
Вот.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 05 дек 2007, 01:54

S.H.S писал(а):Я знаю, что вызывает исключение, но это мне никак не помогло :(.
Судя по тому, что происходит AV, происходит обращение к несозданному компоненту. Что мешает найти этот компонент и сделать проверку его существования через Assigned()?

S.H.S
Сообщения: 65
Зарегистрирован: 25 ноя 2005, 02:18

Сообщение S.H.S » 05 дек 2007, 02:48

И снова, к сожалению. Я и это пробовал. Здесь ясно, что возможно еще не создан DBGridEh. Но Assigned выдает True.

Вот чтобы не быть голословным небольшой пример:
http://depositfiles.com/files/2596464
Прошу прощения, что на depositfiles, но ничего другово в голову не пришло.
В примере нужно только подставить свою (любую) базу и таблицу прописать в SelectSQL.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 05 дек 2007, 08:01

Наверное еще всетаки не создан грид.

И вот какое решение.

Код: Выделить всё

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
if not form1.Visible then exit;

 if pFIBDataSet1.State = dsBrowse then
  form1.DBGridEh1.Hint:=pFIBDataSet1NUM.AsString;

end;
Или такое:

Код: Выделить всё

procedure TForm1.FormCreate(Sender: TObject);
begin
DBGridEh1:=nil;
pFIBDataSet1.Open;
end;

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
if DBGridEh1=nil then exit;

 if pFIBDataSet1.State = dsBrowse then
  form1.DBGridEh1.Hint:=pFIBDataSet1NUM.AsString;

end;

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 05 дек 2007, 08:05

Оригинально:

Код: Выделить всё

procedure TForm3.Button1Click(Sender: TObject);
begin
 Form1:=TForm1.Create(nil);
 Form1.Show;
end;

Код: Выделить всё

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
 if pFIBDataSet1.State = dsBrowse then
  form1.DBGridEh1.Hint:=pFIBDataSet1NUM.AsString;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 pFIBDataSet1.Open;
end;
Присвоение Form1 произойдет только после создания формы, а ты при конструировании ссылаешься на Form1. Отсюда и AV.
Лечение:

Код: Выделить всё

 if pFIBDataSet1.State = dsBrowse then
  DBGridEh1.Hint:=pFIBDataSet1NUM.AsString;
И на будущее: не ссылайся на себя через переменную.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2007, 09:39

не удержался - нафига в FormCreate писать DataSet.Open?

S.H.S
Сообщения: 65
Зарегистрирован: 25 ноя 2005, 02:18

Сообщение S.H.S » 05 дек 2007, 11:48

Ну вот налетели. :) В трех строчках пять ошибок. :) :) :).
Я писал уже в полудреме. (2:48 am) Так что извиняйте за некоторый бред.
И на будущее: не ссылайся на себя через переменную.
Я ошибся, просто в оригинале датасеты стоят на датамодуле.
не удержался - нафига в FormCreate писать DataSet.Open?
Кстати, нет разницы для этой ошибке, что в onCreate что в OnShow.

Вот пример более точный:
http://depositfiles.com/files/2599551

Всё разобрался ВСЕМ СПАСИБО.

P.S. dsBrowse - это статус, как я думал раньше, срабатывает только при навигации по записям. А какая навигация без формы. Значит где-то в FIB или DB.pas не стоит DisableControls. (Не кидайте помидорами если я не прав :))

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 05 дек 2007, 12:50

S.H.S писал(а):P.S. dsBrowse - это статус, как я думал раньше, срабатывает только при навигации по записям. А какая навигация без формы.
Легко. При Open/Close датасета, например :).
S.H.S писал(а):Значит где-то в FIB или DB.pas не стоит DisableControls. (Не кидайте помидорами если я не прав :))
Читать про DisableScrollEvents/EnableScrollEvents.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2007, 13:42

значит где-то в FIB или DB.pas не стоит DisableControls.
кому оно там надо? че-то у тебя с логикой...

Ответить