Topic: TableGrid.dbGetSQLStatemen

есть две формы - главная и вторичная. на второй форме есть грид. на событии OnShow второй формы висит код типа:

 var tgMeasurementSQLQuery: string;
...
tgMeasurementSQLQuery := frmMeasurement.tgMeasurement.dbGetSQLStatement;
ShowMessage(tgMeasurementSQLQuery);

однако при показе второй формы месседж выскакивает совершенно пустым. почему?
задача стоит - сохранить запрос с изначальным заполнением грида сразу после показа формы, так как потом всякие фильтра могут изменить содержимое грида вплоть до изменения колонок с данными

2 (edited by sibprogsistem 2018-08-07 20:24:05)

Re: TableGrid.dbGetSQLStatemen

дело в том, что  dbGetSqlStatement работает только после поиска то гриду

Post's attachments

Attachment icon test.rar 3.92 kb, 331 downloads since 2018-08-07 

Re: TableGrid.dbGetSQLStatemen

то есть надо тогда заполнять грид в исходное состояние при помощи скрипта и SQL-запроса?

Re: TableGrid.dbGetSQLStatemen

я не пробовал но все же, сделайте для начала через фильтр
Form1.TableGride.dbFilter := параметры фильтра;
повесте его на событии OnShow

Если грид  заполнен кнопкой с действием "SQL запрос", то в место dbGetSqlStatement  нужно использовать dbSQL

Re: TableGrid.dbGetSQLStatemen

так в том-то и дело, что в грид у меня настраивается вывод данных по умолчанию через свойства в инспекторе объектов в самой IDE... а фильтра уже меняют его состояние и наполнение. в том числе - меняют местами столбцы и даже другие столбцы добавляют. в том-то весь и прикол - вернуть грид в состояние "по умолчанию".

Re: TableGrid.dbGetSQLStatemen

просто поместите на форму кнопку поиск
в поиске задайте заполнение грид
скройте кнопку
повесте клик на OnShow
не каки других параметров не нужно

Re: TableGrid.dbGetSQLStatemen

хм... интересно... спасибо за костыль)

8 (edited by m.prokhachev 2018-08-16 15:43:06)

Re: TableGrid.dbGetSQLStatemen

sibprogsistem wrote:

просто поместите на форму кнопку "поиск"
в поиске задайте заполнение грида
скройте кнопку
повесьте клик на OnShow
никаких других параметров не нужно

Хреновый костыль, в общем... Так как все равно требуется указать компонент, участвующий в поиске. Обычно я указываю сам грид на форме... Но если два-три раза подряд нажать, то в итоге в гриде одна запись и остается... Причем обычно самая первая по id в таблице БД.

Вот если бы можно было НЕ указывать компоненты, участвующие в поиске - тогда было бы здорово... Может, Дмитрий повесит туда по умолчанию какую-нить опцию, которая не будет встраивать конструкцию WHERE <условие>?..

9 (edited by m.prokhachev 2018-08-29 07:59:21)

Re: TableGrid.dbGetSQLStatemen

Хм... Вроде бы проблема решилась так:

procedure form_buttonWithActionSearch_OnClick (Sender: TObject; var Cancel: boolean);
begin
  form.TableGrid.dbFilter := '';
end;

то есть в OnClick кнопки с действием "поиск", которая на самом деле должна возвращать грид в исходное состояние (как при первом показе формы), надо прописать обнуление конструкции WHERE в автоматически формируемом SQL-запросе
Потестирую какое-то время, если обнаружится недостаток - отпишусь.

Re: TableGrid.dbGetSQLStatemen

в самом компоненте не обязательно что-то указывать можно  edit поставить просто опятже скрытый и ничего в него не писать или chekbox или оной другой компонент просто оставить пустым , получится то же что и dbFilter = '' ;
точно не помню но при каком-то варианте с dbFilter = '' ;  вазникает проблема, грид начинает только по этому скрипту работать  и другие варианты поиска не отображает, потому я такие кастыли ставлю..

Re: TableGrid.dbGetSQLStatemen

Получать SQL запрос, который был использован для заполнения грида лучше всего в событии OnChange, оно возникает сразу после заполнения компонента данными.

procedure Form1_TableGrid1_OnChange (Sender: TObject);
begin
    ShowMessage(Form1.TableGrid1.dbGetSqlStatement);
end;
Dmitry.

12 (edited by m.prokhachev 2018-08-29 08:00:30)

Re: TableGrid.dbGetSQLStatemen

m.prokhachev wrote:

Хм... Вроде бы проблема решилась так:

procedure form_buttonWithActionSearch_OnClick (Sender: TObject; var Cancel: boolean);
begin
  form.TableGrid.dbFilter := '';
end;

то есть в OnClick кнопки с действием "поиск", которая на самом деле должна возвращать грид в исходное состояние (как при первом показе формы), надо прописать обнуление конструкции WHERE в автоматически формируемом SQL-запросе
Потестирую какое-то время, если обнаружится недостаток - отпишусь.

Все равно через некоторое время происходит какая-то фигня... В итоге остается одна строка в гриде. И хоть убейся об стену...
Буду пробовать вариант Дмитрия.

13 (edited by m.prokhachev 2018-08-30 14:33:36)

Re: TableGrid.dbGetSQLStatemen

В общем-то, я все бьюсь над своей проблемкой небольшой.
Напомню: есть таблица на форме, есть два малость изменяющих в нем состав колонок и число колонок выпадающих списка, есть кнопка Reset, которая по идее приводит таблицу в первичное состояние для ликвидации "последствий" работы выпадающих списков, сама Reset имеет действие "поиск", в настройках действия которого прописаны параметры изначального заполнения таблицы на форме.
Так вот, так как

procedure form_buttonReset_WithActionSearch_OnClick (Sender: TObject; var Cancel: boolean);
begin
  form.TableGrid.dbFilter := '';
end;

через некоторое время срабатывать перестает, я начал изучать взаимодействие этих выпадающих списков (ComboBox'ов) и кнопки Reset с таблицей на форме.
Написал такой код:

var tgSQLQuery: string;
...
procedure frm_tg_OnChange (Sender: TObject);
begin
  // при первом показе frm получим исходный SQL-запрос
  if tgSQLQuery = '' then tgSQLQuery := frm.tg.dbGetSqlStatement;
end;

procedure frm_btnReset_OnClick (Sender: TObject; var Cancel: boolean);
begin
  frm.tg.dbItemID := -1;
  frm.tg.dbFilter := '';
  if frm.cb1.dbItemID <> -1 then frm.cb1.dbItemID := -1;
  if frm.cb2.dbItemID <> -1 then frm.cb2.dbItemID := -1;
end;

procedure frm_cb2_OnChange (Sender: TObject);
begin
  if frm.cb2.dbItemID = -1 then
    frm.tg.dbGetSqlStatement := tgSQLQuery;
end;

procedure frm_cb1_OnChange (Sender: TObject);
begin
  if frm.cb1.dbItemID = -1 then
    frm.tg.dbGetSqlStatement := tgSQLQuery;
end;
...
begin
  tgSQLQuery := '';
end.

и получается так, что если не выделять строку в таблице на форме, то все работает нормально, при возвращении выпадающих списков на пустое значение и при нажатии кнопки Reset все работает...
НО стоит только выделить строку в таблице - так нажатие кнопки Reset приводит лишь к отображению выделенной строки в таблице. При этом установка в выпадающих списках пустого значения работает нормально и при выделенной строке в таблице. Как так-то?
Напоминаю, что кнопка Reset имеет действие "поиск" и использует в качестве компонента, участвующего в поиске, саму таблицу на форме. Собственно, и вывод результата своих действий производит в эту же таблицу.

Re: TableGrid.dbGetSQLStatemen

form.TableGrid.dbFilter := '';
у меня эта часть кода полностью блокирует все остольные фильтры и у Вас видимо то же смое

Re: TableGrid.dbGetSQLStatemen

sibprogsistem wrote:

form.TableGrid.dbFilter := '';
у меня эта часть кода полностью блокирует все остольные фильтры и у Вас видимо то же смое

даже если я комментирую эту строку - ситуация не меняется.

Re: TableGrid.dbGetSQLStatemen

Не могли бы вы описать подробней, что пытаетесь сделать? какая цель? Также приложите ваш проект.

Dmitry.

17 (edited by m.prokhachev 2018-08-31 19:53:30)

Re: TableGrid.dbGetSQLStatemen

Есть frmMeasurement, на ней два ComboBox с ForeignKey и FieldName, также они завязаны при помощи Increm. Search на две скрытые визуально кнопки с действием "Поиск". Кроме того, имеется видимая кнопка Reset с действием "Поиск", которая "отменяет" действие ComboBox'ов и приводит таблицу tgMeasurement в "исходное" состояние (на момент первичного открытия frmMeasurement). Собственно, вся диспозиция.
Код приведен выше, его я специально даю абстрактно, без привязки к конкретным именам форм и компонентов формы, однако повторюсь и здесь:

var tgSQLQuery: string;
...
procedure frm_tg_OnChange (Sender: TObject); // таблица, в куда выводится результат ComboBox'ов и кнопки Reset
begin
  // при первом показе frm получим исходный SQL-запрос
  if tgSQLQuery = '' then tgSQLQuery := frm.tg.dbGetSqlStatement;
end;

procedure frm_btnReset_OnClick (Sender: TObject; var Cancel: boolean);
begin
  frm.tg.dbItemID := -1;
  frm.tg.dbFilter := '';
  if frm.cb1.dbItemID <> -1 then frm.cb1.dbItemID := -1; 
  if frm.cb2.dbItemID <> -1 then frm.cb2.dbItemID := -1;
end;

procedure frm_cb2_OnChange (Sender: TObject);  // связанный через Increm. Search с скрытой кнопкой btn2 с действием "Поиск"
begin
  if frm.cb2.dbItemID = -1 then
    frm.tg.dbGetSqlStatement := tgSQLQuery;
end;

procedure frm_cb1_OnChange (Sender: TObject); // связанный через Increm. Search с скрытой кнопкой btn1 с действием "Поиск"
begin
  if frm.cb1.dbItemID = -1 then
    frm.tg.dbGetSqlStatement := tgSQLQuery;
end;
...
begin
  tgSQLQuery := '';
end.

Собственно, проблема как раз и состоит в том, что если не выделить в таблице на форме какую-нить строку, то все взаимодействует как и задумывалось - нажатие кнопки Reset возвращает таблицу на форме в "исходное" состояние, то же происходит и при выборе пустых значений в обоих ComboBox'ах.
НО  стоит только выделить строку в таблице - так нажатие кнопки Reset приводит лишь к отображению выделенной строки в таблице. При этом установка в выпадающих списках пустого значения тоже работает лишь по настройке связанных с ComboBox'ами кнопками с действием "Поиск".
Не смотря на весь приведенный код, где строками

  frm.tg.dbItemID := -1;
  frm.tg.dbFilter := '';

я пытаюсь снять выделение строки в таблице и очистить фильтры, если таковые имеются, чтобы они не влияли на SQL-запрос кнопки Reset.
UPD1. Такое впечатление, что код

procedure frm_tg_OnChange (Sender: TObject);
begin
  // при первом показе frm получим исходный SQL-запрос
  if tgSQLQuery = '' then tgSQLQuery := frm.tg.dbGetSqlStatement;
end;

срабатывает каждый раз при изменении таблицы на форме при помощи ComboBox'ов, хотя такое не должно быть, так как во второй и последующие события OnCnange таблицы переменная tgSQLQuery не пустая.
UPD1.1. Да, переменная tgSQLQuery меняет свое значение КАЖДЫЙ раз при наступлении OnChange таблицы на форме. Решение - ввод дополнительного флага булевского типа:

var tgSQLQuery_Flag: boolean;
...
procedure frm_tg_OnChange (Sender: TObject);
begin
  // при первом показе frm получим исходный SQL-запрос ПО ЗАДУМКЕ!!!
  if not tgSQLQuery_Flag then
    begin
      tgSQLQuery := frmMeasurement.tgMeasurement.dbGetSqlStatement;
      tgSQLQuery_Flag := True;
    end;
end;
...
begin
  tgSQLQuery_Flag := False;
  ...
end.

но это не решает проблему работы кода не так, как задумывается, при выделенной строке в таблице на форме...
UPD2. Вижу проблему некорректной работы кода (не так, как хотелось бы, как задумывалось) в том, что не снимается выделение со строки в таблице на форме. Попробовал изменить код так:

procedure frm_cb2_OnChange (Sender: TObject);
begin
  if frm.cb2.dbItemID = -1 then
    begin
      frm.tg.dbItemID := -1;
      frm.tg.dbGetSqlStatement := tgSQLQuery;
    end;
end;

procedure frm_cb1_OnChange (Sender: TObject);
begin
  if frm.cb2.dbItemID = -1 then
    begin
      frm.tg.dbItemID := -1;
      frm.tg.dbGetSqlStatement := tgSQLQuery;
    end;
end;

и результата - ноль... Все та же работа не так, как задумывалось. Как убрать выделение строки в таблице?
UPD3. Понял, что дурак... Переделал код так:

procedure frm_btnReset_OnClick (Sender: TObject; var Cancel: boolean);
begin
  frm.tg.dbItemID := -1;
  frm.tg.dbFilter := '';
  if frm.cb1.dbItemID <> -1 then frm.cb1.dbItemID := -1;
  if frm.cb2.dbItemID <> -1 then frm.cb2.dbItemID := -1;
end;

procedure frm_cb2_OnChange (Sender: TObject);
begin
  if frm.cb2.dbItemID = -1 then
    begin
      frm.tg.ClearRows;
      frm.btnReset.Click;
    end;
end;

procedure frm_cb1_OnChange (Sender: TObject);
begin
  if frm.cb1.dbItemID = -1 then
    begin
      frm.tg.ClearRows;
      frm.btnReset.Click;
    end;
end;

Во-первых, избавили от события OnChange таблицы на форме, во-вторых, избавились от переменных tgSQLQuery и tgSQLQuery_Flag. При этом установка ComboBox'ов в пустое значение работает даже при выделенной строке в таблице, что и требовалось. Осталось лишь заставить нормально работать кнопку Reset при выделенной строке в таблице, ибо продолжается некорректная работа Reset при выделенной строке в таблице.

18 (edited by m.prokhachev 2018-08-31 20:17:10)

Re: TableGrid.dbGetSQLStatemen

В общем, я даже не дурак, а идиот (хотя могу сослаться на незнание работы MVD как таковой), но таки получилось полностью решить проблему. Полный рабочий код выглядит так:

procedure frm_btnReset_OnClick (Sender: TObject; var Cancel: boolean);
begin
  frm.tg.ClearRows;
  if frm.cb1.dbItemID <> -1 then frm.cb1.dbItemID := -1;
  if frm.cb2.dbItemID <> -1 then frm.cb2.dbItemID := -1;
end;

procedure frm_cb2_OnChange (Sender: TObject);
begin
  if frm.cb2.dbItemID = -1 then frm.btnReset.Click; 
end;

procedure frm_cb1_OnChange (Sender: TObject);
begin
  if frm.cb1.dbItemID = -1 then frm.btnReset.Click;
end;

и без всяких дополнительных переменных, флажков и прочая... Все гораздо проще. А дело было в frm.tg.ClearRows...