powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
25 сообщений из 39, страница 1 из 2
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043366
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему DataSource.OnDataChange выполняется 2 раза при открытии формы?
Сама процедура, содержащая запрос и его открытие, выполняется один раз на OnShow формы, и после этого OnDataChange - 2 раза.
На открытой форме уже при движении курсора по записям выполняется только один раз для каждой записи.
Нельзя ли сократить количество вызовов процедуры OnDataChange до 1 раза? В ней висит открытие дочерних сеток, и они открываются по нескольку раз, что очень замедляет создание и открытие формы.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043382
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladВ ней висит открытие дочерних сеток

Неудачный выбор ивента. И неудачный способ открытия дочерних запросов. Пересади на
OnAfterScroll и запросы открывай только после вменяемого таймера (1 секунда - нормально).

PS: Посмотри как сделан штатный механизм master-detail в FIB+, например.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043385
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Пересади на OnAfterScroll
Который не срабатывает при открытии пустого датасета.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043388
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И, соответственно, не вызывает открытие пустых дочерних запросов. Именно то, что надо.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043391
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Именно то, что надо.
При условии, что изначально дочерние датасеты были закрыты
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043395
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. если датасет пустой и событие не будут вызывано, то нужно проверять пустой он или нет и принудительно закрывать дочерние
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043410
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
svnvladВ ней висит открытие дочерних сеток

Неудачный выбор ивента. И неудачный способ открытия дочерних запросов. Пересади на
OnAfterScroll и запросы открывай только после вменяемого таймера (1 секунда - нормально).

PS: Посмотри как сделан штатный механизм master-detail в FIB+, например.
Пересадил на FDQuery.AfterScroll - теперь при открытии формы он 50 раз вызывается, на каждую из 50 записей в сетке.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043413
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad, что то напутал, у меня один раз. Может у тебя какие-то события на форме затрагивают AfterScroll ?
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043416
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
Dimitry Sibiryakov
пропущено...

Неудачный выбор ивента. И неудачный способ открытия дочерних запросов. Пересади на
OnAfterScroll и запросы открывай только после вменяемого таймера (1 секунда - нормально).

PS: Посмотри как сделан штатный механизм master-detail в FIB+, например.

Пересадил на FDQuery.AfterScroll - теперь при открытии формы он 50 раз вызывается, на каждую из 50 записей в сетке.

Тебе про таймер тоже написали.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043421
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad
пропущено...

Пересадил на FDQuery.AfterScroll - теперь при открытии формы он 50 раз вызывается, на каждую из 50 записей в сетке.

Тебе про таймер тоже написали.

Но я же не знаю заранее, сколько времени будет создаваться форма. Сделаю 1 секунду, а там записей на 5 секунд, и пойдет каждую из 1000 записей открывать дочерние сетки. Да даже 100 уже много. А если сделать больше таймер, то лишняя пауза.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043422
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad
пропущено...

Пересадил на FDQuery.AfterScroll - теперь при открытии формы он 50 раз вызывается, на каждую из 50 записей в сетке.

Тебе про таймер тоже написали.

А чем OnDataChange не нравится. По учебнику ее используют.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043423
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
ъъъъъ
пропущено...

Тебе про таймер тоже написали.

Но я же не знаю заранее, сколько времени будет создаваться форма. Сделаю 1 секунду, а там записей на 5 секунд, и пойдет каждую из 1000 записей открывать дочерние сетки. Да даже 100 уже много. А если сделать больше таймер, то лишняя пауза.

Хрень пишешь.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043424
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
ъъъъъ
пропущено...

Тебе про таймер тоже написали.

А чем OnDataChange не нравится. По учебнику ее используют.

Делай. Но с таймером.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043440
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad
пропущено...

А чем OnDataChange не нравится. По учебнику ее используют.

Делай. Но с таймером.

В событии пишем
Код: pascal
1.
2.
Timer1.Enabled := false; // Чтобы на каждую запись он сбрасывал истекшее время и начинал заново
Timer1.Enabled := true;


А в событии OnTimer пишем
Код: pascal
1.
2.
Timer1.Enabled := false;
*** вызов дочерней сетки ***


Правильно?
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043449
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad,

да.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043459
Softologic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
ъъъъъ
пропущено...

Делай. Но с таймером.

В событии пишем
Код: pascal
1.
2.
Timer1.Enabled := false; // Чтобы на каждую запись он сбрасывал истекшее время и начинал заново
Timer1.Enabled := true;



А в событии OnTimer пишем
Код: pascal
1.
2.
Timer1.Enabled := false;
*** вызов дочерней сетки ***



Правильно?

Да, я также у себя делал. Рабочая схема
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043513
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно ли запихать ADQuery.Open в Thread, чтобы вообще ничего не препятствовало скроллингу? Сейчас иногда происходит затык, если в момент скроллинга начала перерисовываться нижняя сетка. Или будут проблемы с Synchronize?
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043514
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
Можно ли запихать ADQuery.Open в Thread, чтобы вообще ничего не препятствовало скроллингу? Сейчас иногда происходит затык, если в момент скроллинга начала перерисовываться нижняя сетка. Или будут проблемы с Synchronize?

Про таймер же написали.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043517
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решал проблему в табеле сотрудников. Хотелось отображать фото, но если делать на AfterScroll то всё очень медленно, при контекстном поиске AfterScroll срабатывает на каждую запись, да и просто фото довольно тяжёлые, для того чтобы запрашивать на каждую запись при быстром скролинге.
Решение.
Заводите переменные "Запрашиваемый ключ", "Текущий отображаемый ключ" и "Время установки запрашиваемого ключа".
Заводите таймер, у меня на 200 миллисекунд, в котором проверяете, что запрашиваемый отличается от текущего.
В AfterScroll устанавливаете "Запрашиваемый ключ" и "Время установки запрашиваемого ключа".
В таймере проверяете если "Запрашиваемый ключ" <> "Текущий отображаемый ключ" и прошла дельта времени, то делаете свою работу (переоткрываете detail датасеты), устанавливаете "Текущий отображаемый ключ" := "Запрашиваемый ключ". Работает довольно неплохо.
Код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
procedure Tfrm1CTimeSheet.dbgCtrlColEnter(Sender: TObject);
begin
  inherited;
  dbgCtrlCellSelectionChanged;
end;

procedure Tfrm1CTimeSheet.mtCtrlCrossAfterScrollEv(DataSet: TDataSet);
begin
  dbgCtrlCellSelectionChanged;
end;

procedure Tfrm1CTimeSheet.dbgCtrlCellSelectionChanged;
var
  Col :TColumnEh;
  dv :TDynVarEh;
begin
  if not mtCtrlCross.IsEmpty and not mtCtrlCrossWorker.IsNull
    then FRequestCtrlDetailWorkerId := mtCtrlCrossWorker.AsInteger
    else FRequestCtrlDetailWorkerId := 0;
  Col := dbgCtrl.Columns[dbgCtrl.Col-1];
  dv := Col.DynProps.FindDynVar(cstDvDateColumn);
  if (dv <> nil)
    then FRequestCtrlDetailDate := dv.AsDateTime
    else FRequestCtrlDetailDate := 0;
  FRequestCtrlDetailReqTime := Now();
end;

procedure Tfrm1CTimeSheet.tmrRefreshDetailsTimer(Sender: TObject);
begin
  inherited;
  RefreshCtrlDetails;
end;

procedure Tfrm1CTimeSheet.RefreshCtrlDetails;
begin
  if ((FRequestCtrlDetailWorkerId <> FCurrentCtrlDetailWorkerId) or (FRequestCtrlDetailDate <> FCurrentCtrlDetailDate))
    and (MilliSecondsBetween(FRequestCtrlDetailReqTime, Now()) >= tmrRefreshDetails.Interval div 2) then
  begin
    if (FRequestCtrlDetailWorkerId <> FCurrentCtrlDetailWorkerId) then
    begin
      if (FRequestCtrlDetailWorkerId > 0) and FCtrlPhotoVisible then
      begin
        fdqCtrlPhoto.ParamByName('work_id').AsInteger := FRequestCtrlDetailWorkerId;
        if fdqCtrlPhoto.Active
          then fdqCtrlPhoto.Refresh
          else fdqCtrlPhoto.Open;
      end else
        fdqCtrlPhoto.Close;
    end;

    FCurrentCtrlDetailWorkerId := FRequestCtrlDetailWorkerId;
    FCurrentCtrlDetailDate := FRequestCtrlDetailDate;
  end;
end;


Если зажать стрелку вниз или PageDown, то скролинг будет работать быстро, а детейлы обновятся после остановки.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043519
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad
Можно ли запихать ADQuery.Open в Thread, чтобы вообще ничего не препятствовало скроллингу? Сейчас иногда происходит затык, если в момент скроллинга начала перерисовываться нижняя сетка. Или будут проблемы с Synchronize?

Про таймер же написали.

Сделал уже. Если момент скроллинга попадает на начало перерисовки нижней сетки, то происходит зависание до конца перерисовки. Раньше на каждую запись зависало, теперь только в этом случае.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043520
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
istrebitel
Решал проблему в табеле сотрудников.
Если зажать стрелку вниз или PageDown, то скролинг будет работать быстро, а детейлы обновятся после остановки.

Преимущество перед таймером, что не надо ждать секунду до перерисовки?
Или если у вас тоже таймер, то в чем отличие от просто таймера на OnDataChange?
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043524
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
Преимущество перед таймером, что не надо ждать секунду до перерисовки?

Нет, смотрите, вся отрисовка у нас в главном потоке, поэтому если она началась, то всё, ждём завершения.

svnvlad
Или если у вас тоже таймер, то в чем отличие от просто таймера на OnDataChange?

Да в принципе тоже самое вид сбоку. Просто у меня там 2 различающихся события: изменился сотрудник - надо обновить и фото и проходы, изменилась дата - обновляем только проходы. И я подстелил соломки, думал задать разные дельты времени ожидания, для фото побольше, но и так хорошо работает.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043525
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
istrebitel
svnvlad
Преимущество перед таймером, что не надо ждать секунду до перерисовки?

Нет, смотрите, вся отрисовка у нас в главном потоке, поэтому если она началась, то всё, ждём завершения.

Это вы про Thread что ли?
Наиболее сильное зависание происходит именно на команде ADQuery.Open на дочерней сетке, потому что там медленный запрос. Сама отрисовка происходит быстро. Или без разницы, все равно Thread не получится?
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043528
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В теории надо померить сколько занимает ответ от БД, и сколько отрисовка. Если (и скорее всего) подтупливает ответ, то как вариант делать запрос в потоке.
Просто сделать DataSet.Open внутри другого потока, наверно, не получится, т.к. датасет будет генерировать события, которые грид будет пытаться отрисовать. Можно конечно попробовать Disable/EnableControls, но думаю всё равно AV будет сыпать. Как вариант можно в главном потоке отвязывать DataSet от DataSource, запускать открытие датасета в потоке. После открытия проверять, что запрашиваемые данные не изменились (если изменились заново переоткрываем датасет с новыми параметрами) и если всё ок, то через Synchronize привязываем датасет назад. Колонки в гриде надо создать заранее, иначе будет пересоздавать каждый раз.
Поток создавать в Create формы, а информацию, что изменились запрашиваемые параметры передавать через TEvent.
...
Рейтинг: 0 / 0
DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
    #40043529
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подчиненный датасет должен обновляться мгновенно, ведь он ограничен значением мастер-ключа. Что у вас там тормозит.
...
Рейтинг: 0 / 0
25 сообщений из 39, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DataSource.OnDataChange - почему выполняется 2 раза при новом открытии формы?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]