Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Событие "AfterOpen" в TDBGrid   Найти похожие ветки 

 
AlexAA   (2010-02-24 11:38) [0]

Добрый день!

Как в TDBGrid"e поймать момент выполнения запроса? А еще лучше момент, когда запрос только выполнился и данные получены.
Уточню: DataSet"ом является TADOQuery.


 
12 ©   (2010-02-24 11:59) [1]

ну так наверное и нужно смотреть ADOQuery1AfterOpen


 
AlexAA   (2010-02-24 12:59) [2]


> 12 ©   (24.02.10 11:59) [1]
> ну так наверное и нужно смотреть ADOQuery1AfterOpen


Так в том и дело, что нужно определить событие в TDBGrid"e.

В ADOQuery не подходит.

Другими словами, как grid узнает, о том, что записи загружены и их нужно отобразить?

В исходниках не нашел ничего похожего на то, что Query сообщает grid"y о том, что надо отобразить записи.


 
Медвежонок Пятачок ©   (2010-02-24 13:04) [3]

Так в том и дело, что нужно определить событие в TDBGrid"e.

Чтобы у грида было событие афтероупен, у него сначала должен появиться метод Оупен.
Чтобы был момент когда уже АфтерОупен настало.


 
12 ©   (2010-02-24 13:08) [4]

у грида есть FDataLink: TGridDataLink;
а там
TGridDataLink = class(TDataLink)
 private
   FGrid: TCustomDBGrid;
далее  вызывается FGrid/DataChange


> В ADOQuery не подходит.

почему?


 
Ega23 ©   (2010-02-24 13:39) [5]


> Так в том и дело, что нужно определить событие в TDBGrid"e.
> В ADOQuery не подходит.
>
> Другими словами, как grid узнает, о том, что записи загружены
> и их нужно отобразить?
>
> В исходниках не нашел ничего похожего на то, что Query сообщает
> grid"y о том, что надо отобразить записи.


В общем "академическом" случае - никак. У TDataSet есть метод DisableControls и парный ему EnableControls. Суть такова, что если было выставлено DataSet.DisableControls, то при любых событиях TDataSet (изменение позиции курсора, добавлении-изменении-удалении записей, переоткрытии запроса) данные события не доходят до всех TDataSource, которые "смотрят" на твой TDataSet.
Соответственно, при "включении" TDataSet.EnableControls во все DB-Aware контролы приходит событие OnDataChange.
Поэтому в общем случае узнать нельзя.

ИМХО, это не совсем правильно, что разработчики VCL не ввели дополнительное событие в DataSource (или в DataLink), что в DataSet был вызван EnableControls. Геморроя добавляется очень много, особенно в случае компонентов типа TDBTreeView (когда требуется полный набор данных, зафетченный до конца, дабы дерево правильно можно было построить).


 
Ega23 ©   (2010-02-24 13:45) [6]

А, ну и вдогонку: DataSet понятия не имеет о том, сколько различных контролов на него "смотрит" (и смотрит ли вообще). DataSet знает только список TDataSource, которые "смотрят" на него. И при своих внутренних событиях (если не включено DisableControls) DataSet транслирует эти события всему списку TDataSource.
Соответственно, все TDataSource понятия не имеют о природе компонентов, которые "смотрят" на него, у него есть список TDataLink, которым DataSource перетранслирует полученные события от TDataSet.
Ну а уж как ты свой потомок DataLink организуешь - это твоё личное дело.
К примеру, у меня когда-то давно был написан невизуальный компонент TDBImageList, который работал как стандартный, но картинки сосал из базы.


 
AlexAA   (2010-02-24 14:22) [7]


> Ega23 ©   (24.02.10 13:45) [6]


Спасибо за подробное разъяснение.

Значит мне нужно переделать TGridDataLink под себя.
Потребутеся перекрыть TDataLink.DataEvent.

Реально ли как-то подменить privat"ный FDataLink или придется переписывать весь TCustomDBGrid (такая задача передо мной ставится впервые) ?


 
Ega23 ©   (2010-02-24 14:30) [8]

Я думаю, что тебе для решения твоей частной задачи достаточно будет завязаться на события TDataSource.
Ты лучше опиши саму задачу, бо народу тут опытного дофига, наверняка твою задачу уже кто-то решал.
DBGrid с нуля отрисовывать ты умучаешься, факт.


 
Ega23 ©   (2010-02-24 14:41) [9]

Сейчас перечитал твой вопрос. Вобщем, попробуй завязаться на TDataSource.OnStateChange, где проанализируй свойство State.
Но, опять же, это не избавит тебя от проблемы TDataSet.DisableControls/ TDataSet.EnableControls


 
AlexAA   (2010-02-24 14:44) [10]

Да, действительно случай частный.
Ловить открытие датасета нужно для построения некоева подкомпонента для внутренних нужд. В этом подкомпоненте парсится весь текст запроса на составные части. В общем эти данные нужны только в двух случаях: 1) При поднятии формы выбора полей сортировки. 2) При клике с альтом на заголовоке.

Просто не хотелось каждый раз чистить подкомпонент и заполнять снова. Хотя процессорного время на это уходит не так уж много.


 
Anatoly Podgoretsky ©   (2010-02-24 14:52) [11]


> Так в том и дело, что нужно определить событие в TDBGrid"e.
>
>
> В ADOQuery не подходит.

А в TDBGrid"e нет ни данных, ни зпросов. AfterOpen датасета как раз нужное событие. Датасет уже открыт *выполнен запрос и открыта таблица.


 
Ega23 ©   (2010-02-24 14:54) [12]


> Ловить открытие датасета нужно для построения некоева подкомпонента
> для внутренних нужд. В этом подкомпоненте парсится весь
> текст запроса на составные части. В общем эти данные нужны
> только в двух случаях: 1) При поднятии формы выбора полей
> сортировки. 2) При клике с альтом на заголовоке.
>


Понятно. Вобщем так, ИМХО - подход в корне неверный, т.к. я вполне могу вместо текста "Select .... from .... Order By ....." вызывать какую-нибудь хранимку.
Это раз.
Никто не застрахован от запроса Select Фамилия + " " + Имя + " " + Отчество as ФИО Order By Фамилия, Имя, Отчество
Т.е. сортировка по трём реальным полям в БД, но в финальном наборе данных - одно поле.
Это два.
Посмотри в сторону TDBGrid.Columns[Index].FieldName
Это три.


 
AlexAA   (2010-02-24 15:31) [13]


> т.к. я вполне могу вместо текста "Select .... from ....
> Order By ....." вызывать какую-нибудь хранимку.
> Это раз.
> Никто не застрахован от запроса Select Фамилия + " " + Имя
> + " " + Отчество as ФИО Order By Фамилия, Имя, Отчество
> Т.е. сортировка по трём реальным полям в БД, но в финальном
> наборе данных - одно поле.
> Это два.
> Посмотри в сторону TDBGrid.Columns[Index].FieldName
> Это три.


Вот как раз от пункта 3 пытаюсь уйти, т.к. если "select t1.Name as Name1, t2.Name as Name2 from t1, t2 where... order by TDBGrid.Columns[1].FieldName" выдаст ошибку на сервере.

Пункт 1 и 2 не принципиален, т.к. grid не на отдачу(продажу), а для меня.


 
AlexAA   (2010-02-24 15:33) [14]

еще нужен алиас таблицы. как раз этим и занимается класс "TSQLFields"


 
Ega23 ©   (2010-02-24 15:36) [15]


> еще нужен алиас таблицы. как раз этим и занимается класс
> "TSQLFields"


Посмотри на такую конструкцию

Select T1.Field1, T2.Field2
 from Table1 T1, Table2 T2
 where ....
 Order By 1;


 
AlexAA   (2010-02-25 08:45) [16]


> Посмотри на такую конструкцию
>
> Select T1.Field1, T2.Field2
>  from Table1 T1, Table2 T2
>  where ....
>  Order By 1;


Тоже врядли подойдет, потому что колонки могут перемещаться, а после перемещения уже не представится возможным определить точно по какой колонке была сортировка. Хотя этот способ действительно упростит жизнь, например можно хранить список TList на TColumns, по которым осуществляется сортировка + нужно донавернуть TList по поводу направления сортировки(Asc, Desc)


 
Ega23 ©   (2010-02-25 08:48) [17]

А ещё у TADODataSet есть свойство Sort


 
sniknik ©   (2010-02-25 09:36) [18]

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


 
12 ©   (2010-02-25 10:04) [19]


> Ловить открытие датасета нужно для построения некоева подкомпонента
> для внутренних нужд

а что если добавить в этот подкомпанент ссылку на ADOQuery и чиститься/парсится по возникновению события афтеопен привязанного к нему ADOQuery


 
12 ©   (2010-02-25 11:05) [20]

Покритикуйте. Ногами тоже можно :)

 TMyParse = class
   FQ:TADOQuery;
   foo:procedure(ds:tdataset);
 public
   Constructor Create(AQ:TadoQuery);
   procedure Parse(DataSet: TDataSet);
 end;

-----
procedure TForm1.Button1Click(Sender: TObject);
var MP:TMyParse;
begin
  MP:=TMyParse.Create(ADOQuery1);
end;

constructor TMyParse.Create(AQ: TadoQuery);
begin
 FQ:=AQ;
 foo:=addr(FQ.AfterOpen);
 FQ.AfterOpen:=Parse;
end;

procedure TMyParse.Parse(DataSet: TDataSet);
begin
showmessage("TMyParse.Parse work");
if addr(foo) <> nil then foo(DataSet);
end;


 
Ega23 ©   (2010-02-25 11:12) [21]


> Покритикуйте. Ногами тоже можно :)


Нафига FQ нужно?


 
12 ©   (2010-02-25 11:23) [22]


> Нафига FQ нужно?

всмысле Create(var ADOQuery1); ?


 
Ega23 ©   (2010-02-25 12:43) [23]


> всмысле Create(var ADOQuery1); ?


А зачем var? Ты собираешься менячть значение указателя ADOQuery1?


 
12 ©   (2010-02-25 12:50) [24]


> А зачем var? Ты собираешься менячть значение указателя ADOQuery1?

дык у меня FQ.AfterOpen:=Parse;
а можно  что_передали. AfterOpen:=Parse; тогда var и без FQ

но не нравится что-то мне это. Чувствую что фигня :)


 
Ega23 ©   (2010-02-25 13:13) [25]


> дык у меня FQ.AfterOpen:=Parse;


И чо? А у меня плита газовая.


 
12 ©   (2010-02-25 13:21) [26]

получил ADOQUERY. Надо его метод афтеопен дополнить
можно FQ направить на ADOQUERY и работать с FQ
можно с самим переданным ADOQUERY, но тогда как var его передавать


 
Ega23 ©   (2010-02-25 13:31) [27]


> можно с самим переданным ADOQUERY, но тогда как var его
> передавать


Уверен?


 
12 ©   (2010-02-25 14:01) [28]

работает

type
 TForm1 = class(TForm)
   ADOConnection1: TADOConnection;
   ADOQuery1: TADOQuery;
   DataSource1: TDataSource;
   DBGrid1: TDBGrid;
   Button1: TButton;
   Button2: TButton;
   Button3: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure ADOQuery1AfterOpen(DataSet: TDataSet);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
TMyParse = class
 // FQ:TADOQuery;
  foo:procedure(ds:tdataset);
public
  Constructor Create(var AQ:TadoQuery);
  procedure Parse(DataSet: TDataSet);
end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TMyParse }

procedure TForm1.Button1Click(Sender: TObject);
var MP:TMyParse;
begin
 MP:=TMyParse.Create(ADOQuery1);
end;

constructor TMyParse.Create(var AQ: TadoQuery);
begin
//FQ:=AQ;
foo:=addr(AQ.AfterOpen);
AQ.AfterOpen:=Parse;
end;

procedure TMyParse.Parse(DataSet: TDataSet);
begin
showmessage("TMyParse.Parse work");
if addr(foo) <> nil then foo(DataSet);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ADOQuery1.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ADOQuery1.open;
end;

procedure TForm1.ADOQuery1AfterOpen(DataSet: TDataSet);
begin
showmessage("");
end;


 
Ega23 ©   (2010-02-25 15:16) [29]


> 12 ©   (25.02.10 14:01) [28]
>
> работает


Не сомневаюсь. А если var убрать из конструктора?  :)))


 
имя   (2010-02-25 15:48) [30]

Удалено модератором
Примечание: п. 5 правил



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.059 c
2-1268752361
Lionelles
2010-03-16 18:12
2010.08.27
Вычисления в БД на Delphi


15-1272622758
JohnKorsh
2010-04-30 14:19
2010.08.27
Как определить, какая программа использует файл.


2-1268243885
Haidukzz
2010-03-10 20:58
2010.08.27
Form1.Label_nr_$i.Caption := Hello World ; ?


2-1274423388
pro_xaoc
2010-05-21 10:29
2010.08.27
Какой код лучше?


15-1269360123
TUser
2010-03-23 19:02
2010.08.27
Генетика и геномика человека





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский