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

Вниз

Почему не обновляется RecordCount?   Найти похожие ветки 

 
Ega23 ©   (2005-06-14 19:00) [0]

Имеем следующую ситуацию:

TTreeDataLink = class(TDataLink)
 private
   FTree: TCustomKdrDBTreeView;

 public
   constructor Create(ATree:TCustomKdrDBTreeView);
   procedure DataSetChanged; override;

end;

constructor TTreeDataLink.Create(ATree: TCustomKdrDBTreeView);
begin
 inherited Create;
 FTree:=ATree;
 VisualControl:=True;
end;

//*****************************************************************************

procedure TTreeDataLink.DataSetChanged;
begin
 inherited;
 showmessage(IntToStr(DataSet.RecordCount));
end;

//*****************************************************************************



Я точно знаю, что у данного DataSet"а RecordCount>0 (есть DBGrid, привязанный к этому же DataSet"у).


 
Ega23 ©   (2005-06-14 19:02) [1]

Блин, забыл дописать: ShowMessage всегда -1 показывает. Событие срабатывает при перемещению по DBGrid.


 
Ega23 ©   (2005-06-14 19:17) [2]

Упс-с... Там RecordCount тоже -1...


 
-=XP=- ©   (2005-06-14 19:19) [3]

As implemented in TDataSet, RecordCount is always -1. Ordinarily an application does not access RecordCount at the TDataSet level. Instead a redeclared and implemented RecordCount property in a descendant class is accessed. RecordCount provides a fallback property for derived dataset classes that do not reimplement the property access method.

Кто есть Ваш DataSet?


 
Ega23 ©   (2005-06-14 19:25) [4]

Я уже понял, что RecordCount будет -1.

Проблема такая: мне нужно в DataLink"е увидеть ВСЕ записи (отсортировать определённым образом выборку и нарисовать дерево).
Вопрос стоит так: как увеличить DataLink.BufferCount? Точнее, увеличить-то его просто, обычным сложением. Вопрос на сколько его увеличить? По-идее, нужно поставить
DataLink.BufferCount:=DataLink.DataSet.RecordCount
но он -1...


 
-=XP=- ©   (2005-06-14 19:31) [5]

"В лоб":

function RecordCount(ADataSet: TDataSet): integer;
var
 BM: TBookmark;
begin
 Result := 0;
 ADataSet.DisableControls;
 try
   BM := ADataSet.GetBookmark;
   try
     ADataSet.First;
     while not ADataSet.Eof do
     begin
       Result := Result + 1;
       ADataSet.Next;
     end;
     ADataSet.GotoBookmark(BM);
   finally
     ADataSet.FreeBookmark;
   end;
 finally
   ADataSet.EnableControls;
 end;
end;


:o)

P.S. Так кто же Ваш DataSet?


 
-=XP=- ©   (2005-06-14 19:34) [6]

Некторые DataSet"ы показывают количество записей только при полном прохождении всех записей до конца. Так что может помочь DataSet.Last;


 
Ega23 ©   (2005-06-15 09:01) [7]

2 -=XP=- ©   (14.06.05 19:31) [5]
Так что может помочь DataSet.Last;

Методы DataSet"а, которые двигают курсор, использовать нельзя. Иначе всем остальным компонентам рассылка пойдёт. Причём, даже Disable/EnableControls не поможет.


 
ANB ©   (2005-06-15 09:38) [8]

Странно, чего то тебе не от туда справку кинули, не вижу про -1 :
Indicates the number of records in the internal record buffer maintained by the dataset.

Delphi syntax:

property RecordCount: Integer;

C++ syntax:

__property int RecordCount = {read=GetRecordCount, nodefault};

Description

Read RecordCount to determine the number of actual records in the buffer maintained by the dataset for the Owner of this TDataLink.

In most cases, RecordCount is the same as BufferCount. RecordCount indicates the number of records actually in the record buffer of the dataset, as opposed to the number of records that the dataset can possibly maintain. For example, a data-aware grid with four rows could have one record actually showing data. In this case, BufferCount would be 4, while RecordCount would be 1.


 
ANB ©   (2005-06-15 09:39) [9]

Я нарывался в одаке на проблему, что если выбраны не все записи, до RecordCount показывает, только, сколько выбрал, но не -1, значит это другая проблема. Ща я примерчик у себя попробую . . .


 
Ega23 ©   (2005-06-15 09:43) [10]

2 ANB ©   (15.06.05 09:38) [8]
In most cases, RecordCount is the same as BufferCount. RecordCount indicates the number of records actually in the record buffer of the dataset, as opposed to the number of records that the dataset can possibly maintain. For example, a data-aware grid with four rows could have one record actually showing data. In this case, BufferCount would be 4, while RecordCount would be 1.

Это TDataLink.RecordCount


 
ANB ©   (2005-06-15 09:51) [11]

У меня работает правильно :

var dl : TDataLink;
. . .
 ShowMessage(IntToStr(dl.DataSource.DataSet.RecordCount));
и
 ShowMessage(IntToStr(dl.DataSet.RecordCount));
- выдают правильные результаты.
А вот ShowMessage(IntToStr(dl.RecordCount)); и ShowMessage(IntToStr(dl.BufferCount)); - вертают всегда 1. Что то у тебя с родным дейтасетом. Проверь его отдельно.


 
ANB ©   (2005-06-15 09:53) [12]


> would be 1.
>
> Это TDataLink.RecordCount
Там же 1, а не -1. Странно, на примере в обоих Count получилось 1, хотя в дейтасете - 9.


 
ANB ©   (2005-06-15 09:59) [13]


> Событие срабатывает при перемещению по DBGrid.
- вообще то не должно срабатывать при перемещении по гриду. Странно.


 
-=XP=- ©   (2005-06-15 10:00) [14]

Еще раз.

function TDataSet.GetRecordCount: Longint;
begin
 Result := -1;
end;
(С) VCL

Возвращаемое значение зависит от унаследованного класса.
Посему еще раз вопрос: Какой класс Вашего DataSet"а?


 
Ega23 ©   (2005-06-15 10:04) [15]

Какой класс Вашего DataSet"а?

Может быть любой. Это для ДБ-компонента делается. Может быть и ADOQuery, TQuery, TTable, TClientDataSet etc.
Нужно универсальное решение.


 
Ega23 ©   (2005-06-15 10:10) [16]

2 ANB ©   (15.06.05 09:59) [13]
- вообще то не должно срабатывать при перемещении по гриду. Странно.

Я пишу свой компонент - TDBTreeView. Вот приблизительный код:


TTreeDataLink = class(TDataLink)
 private
   FTree: TCustomKdrDBTreeView;

 public
   constructor Create(ATree:TCustomKdrDBTreeView);
   procedure DataSetChanged; override;
   procedure ActiveChanged; override;

end;

TCustomKdrDBTreeView = class(TCustomTreeView)
 private
   FDataLink: TTreeDataLink;
   FKeyField: String;
   FDisplayField: String;
   FParentField: String;
   FDataSource: TDataSource;
   procedure SetFDataSource(const Value: TDataSource);

 protected

   property DataSource:TDataSource Read FDataSource Write SetFDataSource;
   property DisplayField:String Read FDisplayField Write FDisplayField;
   property KeyField:String Read FKeyField Write FKeyField;
   property ParentField:String Read FParentField Write FParentField;

 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;

end;



Создаю его на форме. Также на форме лежит DBGrid. И DBGrid и мой компонент "смотрят" на один и тот же DataSource.


 
ANB ©   (2005-06-15 11:06) [17]


> Ega23 ©   (15.06.05 10:10) [16]
- а ну да, я хэлп невнимательно прочитал. Попробуй отдельной кнопкой посмотреть RecordCount дэйтасета и вывести ShowMessage(IntToStr(dl.DataSource.DataSet.RecordCount));
Сообщи результат.


 
Ega23 ©   (2005-06-15 11:21) [18]

2 ANB ©   (15.06.05 11:06) [17]

procedure TFMain.Button1Click(Sender: TObject);
begin
ShowMessage("Grid. "+IntToStr(RxDBGrid1.DataSource.DataSet.RecordCount)+#13+
            "Link. "+IntToStr(Link.DataSource.DataSet.RecordCount));
end;



Результат: Grid. -1
          Link. -1


 
sniknik ©   (2005-06-15 12:07) [19]

DataSet.Last;
уже же предлагалось.

> Методы DataSet"а, которые двигают курсор, использовать нельзя. Иначе всем остальным компонентам рассылка пойдёт. Причём, даже
> Disable/EnableControls не поможет.
поможет,
тебе же не надо делать это постоянно, один раз при открытии (либо для твоего случая на DataSetChanged на случай не полного фетча записей в новозаданном рекордсете, сделал, вернул курсор на место никто и заметит (если данных не много ;))


 
Ega23 ©   (2005-06-15 12:22) [20]

2 sniknik ©   (15.06.05 12:07) [19]

Тут вот какая фишка: есть DBTree, есть некий графический план. Есть DataSet, в котором имеется следующая информация:
ZoneID, ZoneParentID, ZoneName, ZoneGraph. Последнее поле - BLOB, в котором лежит информация - набор точек для рисования полигона, цвет полигона и т.п.
Нужно: при открытии DataSet"а заполнить дерево, а также на графическом плане отрисовать все зоны по правилам из DataSet"а.
При перемещении по DataSet"у нужно выделять нужную зону на граф.плане и фокусироваться на нужный узел в DBTree.
При этом инициатором неремещения курсора DataSet"а может служить как граф.план (ткнули мышкой в зону), так и DBTree (выбрали какой-то нод), а также сторонний DB-компанент (DBGrid или DBNavigator, например).


 
ANB ©   (2005-06-15 12:26) [21]


> Ega23 ©   (15.06.05 11:21) [18]
Попробуй так :
ShowMessage("DataSet. "+IntToStr(MyDataSet.RecordCount));
И опубликуй тип дейтасета. Возможно, товй тип не юзает RecordCount, как уже писал  
> -=XP=- ©   (15.06.05 10:00) [14]


 
Ega23 ©   (2005-06-15 12:36) [22]

И опубликуй тип дейтасета. Возможно, товй тип не юзает RecordCount, как уже писал  

Это вполне возможно. Но вот в DBGrid"е же как-то сделано, что с любым DataSet"ом работать можно? Не вопрос, я сейчас заточу компонент исключительно под ADOQuery, который вроде всегда RecordCount возвращает. Но как быть со всеми остальными? С каким-нибудь TdxQuery?


 
ANB ©   (2005-06-15 13:03) [23]


> Ega23 ©   (15.06.05 12:36) [22]

1. Ты не написал ответ на мой вопрос 21 (-1 или правильное число).
2. Грид сам не всегда правильно узнает RecordCount (видел лично, например, в связке с одаком, если не все записи профетчены)
4. Чтобы сделать, как в гриде - надо лезть в его исходники. Это после обеда.


 
sniknik ©   (2005-06-15 13:13) [24]

Ega23 ©   (15.06.05 12:22) [20]
раздели операции, присвоение датасета должно делатся единожды, не при каждом тычке мыши.

> Но вот в DBGrid"е же как-то сделано, что с любым DataSet"ом работать можно?
не обращал внимания на поведение скрола? когда рекордсет с неопределяемым количеством там всего 3 положения, иначе более деталезированное. (т.е. они это учитывают)


 
Ega23 ©   (2005-06-15 13:36) [25]

2 ANB ©   (15.06.05 13:03) [23]
1. Ты не написал ответ на мой вопрос 21 (-1 или правильное число).

Попробовал на TRXQuery и на TADOQuery.
В первом случае RecordCount возвращается корректно, если в выборке нет BLOB"ов. Во втором случае RecordCount корректен всегда. Сейчас попробую с TQuery.

2 sniknik ©   (15.06.05 13:13) [24]
не обращал внимания на поведение скрола? когда рекордсет с неопределяемым количеством там всего 3 положения, иначе более деталезированное. (т.е. они это учитывают)

правильно. DBGrid устанавлевает BufferCount в TGridDataLink"е равным количеству видимых строк грида. В моём случае надо получить ВСЕ строки.


 
ANB ©   (2005-06-15 13:56) [26]

Это, а зачем тебе вообще TGridDataLink ? Не проще напрямую к дейтасету или дэйтасурсу подключаться (Имхо)?


 
sniknik ©   (2005-06-15 14:01) [27]

> В моём случае надо получить ВСЕ строки.
единственный способ получить "ВСЕ строки" это фетч ВСЕГО рекордсета на клиента, что в общем случае достигается переходом на последнюю строку (ну не у всех есть метод FetchAll/клиентский курсор/етс.).

от этого и пляши, если хочеш универсальности. все остальное это танцы с бубном.


 
sniknik ©   (2005-06-15 14:03) [28]

ANB ©   (15.06.05 13:56) [26]
проблема у него не в DataLink-е, а в том что упорно не хочет признавать реальность. ;о) (имхо)
ну а разница на прямом подключении? если количество строк все одно нужно.


 
ANB ©   (2005-06-15 14:06) [29]


> sniknik ©   (15.06.05 14:03) [28]
- а зачем ему тогда количество строк ???? Если хочет в дереве отображать весь НД, так надо по любому Last при загрузке делать, чтобы все профетчить.


 
-=XP=- ©   (2005-06-15 14:14) [30]

Не проще напрямую к дейтасету или дэйтасурсу подключаться (Имхо)?

DataLink используется для оповещения пользователя DataSource в случае изменений в НД. Пользователей данных много, DataSource - один. :)

Трехуровневое дерево:

DataSet - DataSource - DataLink - Пользователь данных
                      DataLink - Пользователь данных

         DataSource - DataLink - Пользователь данных
                      DataLink - Пользователь данных
                      DataLink - Пользователь данных

         DataSource - DataLink - Пользователь данных
                      DataLink - Пользователь данных


 
sniknik ©   (2005-06-15 14:23) [31]

ANB ©   (15.06.05 14:06) [29]
про что и сказ. а все записи нужны обязательно, иначе узлы/листья дерева будут неполные/разнородные в разные моменты открытия рекордсета.
(ну скажем родитель в начале рекордсета, а детки в конце, а возможно и наоборот)


 
Ega23 ©   (2005-06-15 14:28) [32]

Вот -=XP=- ©  [30] правильно всё написал.
Проблема в том, что когда я в своём дереве сделаю Last это же событие отловит мой графический план. Который тоже должен сделать Last (а иначе он не сможет при изменении НД все зоны отрисовать).
И вот в этом месте они входят в клинч.

Если есть другие способы, то с удовольствием их выслушаю. Ибо задача уже задолбала, шеф волком смотрит.


 
sniknik ©   (2005-06-15 14:48) [33]

> Проблема в том, что когда я в своём дереве сделаю Last это же событие отловит мой графический план.
DisabledControls. если его у тебя еще нет, самое время о нем подумать. (вернее правильную обработку уже имеющегося)

> И вот в этом месте они входят в клинч.
и переменную которая позволяет делать Last в дереве только 1 раз тоже нельзя завести?


 
Ega23 ©   (2005-06-15 14:57) [34]

DisabledControls. если его у тебя еще нет, самое время о нем подумать. (вернее правильную обработку уже имеющегося)

А разве можно свою обработку enable/disableControls реализовать? Вообще-то я об этом не подумал... Сейчас посмотрю...


 
Ega23 ©   (2005-06-15 15:01) [35]

Так. Переписать методы не получится. Можно попробовать с DataSet.State поиграться. Но возникает вопрос - а как потом Event послать?


 
ANB ©   (2005-06-15 16:56) [36]

Хм. Есть мысля.
При перезагрузке дерева (открытие или рефреш дейтасета, например) :
1. Запоминаешь дэйтасет
2. Отвязываешь от него дэйтасурс
3. Делаешь дэйтасет.ласт, дэйтасет.First
4. Загружаешь дерево напрямую из дейтасета
5. Подключаешь дейтасет обратно в дейтасурс.
У меня была как то давно проблема, когда надо было гулять по НД, при этом все моргало, а создавать отдельный дейтасурс было влом. Вот так и спасся.


 
-=XP=- ©   (2005-06-15 17:01) [37]

ANB ©   (15.06.05 16:56) [36]

Точно-точно, прям как в Disable/Enable Controls. :)


 
Ega23 ©   (2005-06-15 18:27) [38]

ANB ©   (15.06.05 16:56) [36]

Интересное решение. Но вот в чём вопрос: будет ли это "бегание" синхронным или асинхронным? Т.е. если я "захватил" обработку этого датасета, будут ли остальные компаненты на его изменение реагировать?


 
ANB ©   (2005-06-16 09:28) [39]

Как, интересно, они будут реагировать, если они к сурсу привязаны, а ты его от дейтасета отвязал ? Откуда они узнают, что что то происходит ?


 
Ega23 ©   (2005-06-16 09:39) [40]

А-а-а! DataSource от DataSet"а отвязать!
Немножко не так понял.
Щас попробую!



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

Форум: "Базы";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.047 c
4-1117626873
AlexTregubov
2005-06-01 15:54
2005.07.31
Как нарисовать рамку вокруг TEdit?


1-1120763531
Kastusik
2005-07-07 23:12
2005.07.31
Перерисовка в TListView


14-1121020009
Фонарь
2005-07-10 22:26
2005.07.31
Кто и как придумывает слова?


1-1121361600
Igor_thief
2005-07-14 21:20
2005.07.31
Что за компонент?


1-1121331079
Гость2
2005-07-14 12:51
2005.07.31
удаление файлов в папке





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский