![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DevExpress cxGrid [D7]
shadow_hawk © (2013-05-23 19:05:00)Добрый день!
Помогите плизз справиться с задачкой:
Для ускорения навигации в cxGrid включил:
DataController.DataModeController.GridMode := True;
Что получил:
Плюс:
Скорость увеличилась (это и понятно - сколько надо отобразить строк столько и грузится, а не вся таблица целиком, а в ней около 33000 записей)
Минус:
Фильтр больше не работает. В Footer не показывается количество строк (соответствующих фильтру), просто 0.
По фильтру:
У разработчиков увидел намек на то, что надо обрабатывать событие для фильтра - OnBeforeChange, но что там писать??? не пойму :(
Попытался хотя бы количество и номер строки выяснить:
procedure TFormMain.DBTableViewDataControllerFilterBeforeChange(
Sender: TcxDBDataFilterCriteria; ADataSet: TDataSet;
const AFilterText: String);
var
ARecNo, ARecordCount : integer;
begin
if NOT ( FormMain.DBTableView.DataController.FilteredRecordCount = 0 ) then
begin
with DBTableView.DataController do
begin
if IsGridMode then
begin
ARecNo := DataSet.RecNo;
ARecordCount := DataSet.RecordCount;
end;
end;
Caption := ' ARecNo= "' + IntToStr(ARecNo)+
'" ARecordCount= "' + IntToStr(ARecordCount) + '"';
end;
DBTableView.DataController.Summary.FooterSummaryValues[1] := IntToStr(ARecNo);
end;
В заголовке окна вижу - считается правильно - и общее кол-во видно и номер строки. Только общее количество постоянно - фильтр не работает, хотя в области фильтра я вижу строку активного фильтра:
(firma = Тест)
Как было до включения GridMode (и работало):
По правой кнопке выбираю значение ячейки и вызываю процедуры построения и активации фильтра:
procedure TFormMain. MenuItem1Click(Sender: TObject);
begin
if NOT ( FormMain.DBTableView.DataController.FilteredRecordCount = 0 ) then
begin
FilterLike(( DBTableView.Controller.FocusedColumn as TcxGridDBColumn ),
( DBTableView.Controller.FocusedColumn as TcxGridDBColumn ).DataBinding.Field.Text, False );
end;
end;
procedure FilterLike(Col: TcxGridDBColumn; Text: Variant; FlagAddFiltr: Boolean );
begin
Screen.Cursor := crHourGlass;
with FormMain.DBTableView.DataController.Filter do
begin
if NOT FlagAddFiltr then Clear;
AddItem( Root, Col, foLike, Text, Text );
Active := true;
end;
Screen.Cursor := crDefault;
end;
turbouser (2013-05-25 20:47:00) [21]ты хоть понимаешь, зачем вообще этот GridMode нужен?
Inovet (2013-05-25 16:47:00) [22]> [19] Inovet © (25.05.13 16:44)
> q1.FieldByName
q1.ParamByName
Inovet (2013-05-25 16:44:00) [23]Хорошо. А в запросе фильтр с тем же условием работпет? И почему изначально он не использовался?
Через параметр
SELECT ... FROM ... WHERE FIRMA = :FIRMA
перед открытием устанавливаем значение параметра
q1.FieldByName("FIRMA").AsString := 'Название фирмы';
shadow_hawk (2013-05-25 16:04:00) [24]
> TADODataSource.
Увлекся :)
не TADODataSource, а TDataSource.
shadow_hawk (2013-05-25 15:39:00) [25]
> основным в данном сабжевом случае будет TADODataSet.
Окей!
Все так и есть, каюсь не дописал :))
На форме компоненты: TADOConnection, TADOQuery, TADODataSource.
Правда у меня их немного больше: 2 TADOConnection (я работаю с 2 серверами) , и по 18 TADOQuery, TADODataSource, но это в данном случае не имеет же значение?
Мы же рассматриваем только 1 cxGrid. И он использует все компоненты по одному.
Надеюсь мы все выяснили, осталось понять, как это теперь поможет ответить на вопрос про OnBeforeChangeпри GridMode := True?
Inovet (2013-05-25 14:34:00) [26]> [15] shadow_hawk © (25.05.13 14:15)
Так уже понятнее. Для работы с MS SQL Server наиболее родные компонеты из TADO, кроме TADOTable и TADOQuery, последний можно осознанно использовать. Т.е. основным в данном сабжевом случае будет TADODataSet.
shadow_hawk (2013-05-25 14:15:00) [27]
> Их несколько разных. Какие именно?
Я же кажется ответил???
> Стандартный конекшен, стандартный квери, стандартный датасорс.
> , таблицы хранятся на сервере SQL.
Если не так написал-сорри-попробую немного по-другому:
На форме компоненты: TConnection, TQuery, TDataSource.
База данных на Microsoft SQL Server 2005.
И на форме грид cxGrid из DevExpress.
Вопросы остались теже.
Inovet (2013-05-25 13:22:00) [28]> [13] shadow_hawk © (25.05.13 12:29)
> На данный момент я использую стандартные (которые входят
> в поставку delphi 7) компоненты.
Их несколько разных. Какие именно?
> [13] shadow_hawk © (25.05.13 12:29)
> таблицы хранятся на сервере SQL.
Серверов много разных какой именно?
> [13] shadow_hawk © (25.05.13 12:29)
> в cxGrid
Вот с этим дел не имел, понятия не имею, как там он это делает. Но общие принципы уже описал выше.
> [13] shadow_hawk © (25.05.13 12:29)
> то cxGrid берет из таблицы (вернее из датасорс
Вернее из Датасет
> [13] shadow_hawk © (25.05.13 12:29)
> Тест - что бы после применения фильтра отобразить и результат
> и собсвенно строку на которой стоял.
С текущей записью надо работать в Датасет, в гриде данных нет. Если у этого грида есть какие-то встроенные средства для фильтрации и итогов, то он всё равно обращается либо к Датасет, либо отдельные запросы делает, которые, видимо и надо написать.
Боюсь, сейчас выяснится, что используется как-нибудь так - TTable и MS SQL.
В дискуссии втягиваться нет желания. Могу только посоветовать сделать стандартно для данного конкретного сервера, о котором ничего не известно, без использования костылей, потом уже с cxGrid разбираться, скорее всего тогда и он будет работать.
shadow_hawk (2013-05-25 12:29:00) [29]
> > [11] Inovet© (25.05.13 10:07)
> > причём
>
> Это во-вторых.
Этого не понял - если есть смысл то объясните :) если нет, то проехали.
По первому посту:
Мне очень хочется получить ОТВЕТЫ.
И не хочется вдаваться в полемику, я не ПРОГРАММИСТ и даже не программист. А вы (как мне показалось, если ошибаюсь то сорри :)) вместо того, что бы дать ответ, хотите втянуть меня в пустую болтовню. Не надо, меня это не вылечит, и программистом не сделает. Без обид! Мы просто пока разговариваем на разных языках.
Ваши вопросы, возможно по-существу, но я не понимаю, что вы хотите, и возможно, не понимаю, что вы хотите помочь :). Давайте попробуем по-проще. Тогда я смогу ( скорее всего ) ответить на ваши вопросы, а вы на мои.
Ответы, ( исходя из того как я понял ваши вопросы ):
На данный момент я использую стандартные (которые входят в поставку delphi 7) компоненты. И.. использую в качесте грида cxGrid.
Стандартный конекшен, стандартный квери, стандартный датасорс., таблицы хранятся на сервере SQL.
В таблице, с которой сейчас идет война, и которую отображает cxGrid около 13000 записей. Почему я говорил про 33000 - отвечаю. Я храню id в отдельном стобце "номер записи" не ключевом, так просто счетчик записей, т.к. записи не удаляются, то счетчик сооветствует номеру под которым запись попала в таблицу. Когда я заметил (первый раз), что cxGrid стал тормозить, то я перенес часть записей в архивную таблицу, и продолжил работать с оставшейся. Когда накопилось еще около 10000-15000 я опять проделал туже процедуру. В данный момент пришло время опять переносить записи в архив. (А в столбце с номером записи уже видно 33 с копейками тысяч.) Т.е.реально я работаю в cxGrid не более чем с 15000 записей.
Но!
Я узнал, что есть в cxGrid GridMode := True, в этом случае никаких тормозов не наблюдается, ПОТОМУ что cxGrid берет из таблицы (вернее из датасорс а не из таблицы) не все записи, а только те которые нужно отобразить, и подгружает соответственно, то что требуется после перещения в гриде по строкам.
Я воспользовался этим GridMode := True, и:
Стандартный фильтр перестал работать, количество, номер строки, сумирование по столбцу тоже. Да я понимаю, cxGrid поменял стиль работы с датасорс и ему ВОЗМОЖНО неоткуда брать ПРАВИЛЬНЫЕ данные или данные для ПРАВИЛЬНОЙ работы. Я понимаю, что данные эти есть в таблице, но грид их берет не из таблицы, а из датасорс, который берет в свою очередь из квери. Соответственно, если я в квери подам необходимый SQL запрос, то в датасорс будет нужный набор записей, они поступят в cxGrid, и так сказать, сэмулирую функцию фильтра.
Т.е. что бы я сделал в обычном гриде:
1. Создаем фильтр - визуально отображаем текст на каком то месте формы что бы пользователь видел какой фильтр он создал, например (firma = Тест)
2. В квери посылаем SQL запрос обрабатываем и грид отображает результат. Попутно получаю количество строк сооветствующих результату запроса.
А что мне делать в cxGrid? И для чего нужно событие OnBeforeChange, о котором говорит разработчик??? И как мне узнать номер строки на которой я стоял? С которой собственно все и начинается - фильтр строится на основании данных из одной из ячеек этой записи - в примере берем из ячейки название фирмы Тест - что бы после применения фильтра отобразить и результат и собсвенно строку на которой стоял.
И последнее, cxGrid взят из соображений - он обладаем большим набором интуитивно понятного и удобного для пользователя функционала. EhLib тоже есть, но переделывать весь проект? Нее :) И честно говоря не уверен, что получу то что хочу, и уж совсем не уверен, что чего то не потеряю.
Inovet (2013-05-25 10:09:00) [30]> [11] Inovet © (25.05.13 10:07)
> причём
Это во-вторых.
Inovet (2013-05-25 10:07:00) [31]> [10] Shadow_Hawk © (25.05.13 09:29)
Всё, кроме п.4, отдельными запросами, причём в любом гриде. Сабжевый грид не знаю, а например в EhLib есть для этого специальные механизмы тоже на запросах. Номер строки вообще лишён смысла, много раз обсуждалось. Выше писал об этом.
Если хочется странного с номером и счётчиком, то, во-первых, датасет должен уметь это, причём это замедлит работу.
И, раз не слушаешь, читай справку
TDataSet.RecNo
As implemented in TDataSet, the value of RecNo is always -1. Ordinarily an application does not access RecNo at the TDataSet level. Instead a re-implemented RecNo property in a descendant class such as TTable TClientDataSet is accessed. RecNo provides a fallback property for derived datasets that do not support record numbers.
TDataSet.RecordCount
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.
Так понятнее? А ведь ты даже не сказал какой датасет используется.
Shadow_Hawk (2013-05-25 09:29:00) [32]To turbouser
У вас есть ответы на эти вопросы?
>Как при GridMode := True
>1. заставить работать фильтр в cxGrid (самое важно!)
>2. заставить работать счетчик строк (сколько при текущем фильтре)
>3. произвести сумирование значений по определенному столбцу
>4. определить номер строки, на которой стоит курсор
turbouser (2013-05-25 05:48:00) [33]
> shadow_hawk © (24.05.13 18:10) [8]
> Для решения этого вопроса я и завел эту ветку:
Вот никак эта ветка не связана с наличием предварительных параметров выгрузки данных
shadow_hawk (2013-05-24 18:10:00) [34]To Плохиш
А какой еще можно сделать вывод, если фильтр (текст фильтра) есть, а в гриде изменений нет? Это видно визуально и никакой логики не надо - есть столбец, в нем видим значения 1, 2, 3, 4, и т.д. (для примера), строим фильтр, ( тоже для примера) значение в колонке должно быть=4, тогда если фильтр включился, то в этом столбце будут только 4, т.е. из датасета выбирутся все записи удовлетворяющие заданному условию.
То turbouser
>И зачем вообще все это изначально тащить на клиента? Нет критериев выгрузки?
Для решения этого вопроса я и завел эту ветку:
...
Для ускорения навигации в cxGrid включил:
DataController.DataModeController.GridMode := True;
Что получил:
Плюс:
Скорость увеличилась (это и понятно - сколько надо отобразить строк столько и грузится, а не вся таблица целиком, а в ней около 33000 записей)
...
Вопрсы пок остались :)
Как при GridMode := True
1. заставить работать фильтр(самое важно!)
2. заставить работать счетчик строк (сколько при текущем фильтре)
3. произвести сумирование значений по определенному столбцу
4. определить номер строки, на которой стоит курсор
turbouser (2013-05-24 17:29:00) [35]
> не вся таблица целиком, а в ней около 33000 записей
И зачем вообще все это изначально тащить на клиента? Нет критериев выгрузки?
Плохиш (2013-05-24 16:37:00) [36]
> shadow_hawk © (24.05.13 16:10) [5]
Тогда с чего этот вывод
> Количество строк не меняется - значит фильтр не включается
shadow_hawk (2013-05-24 16:10:00) [37]То Плохиш
Это событие ( OnBeforeChange ) происходит после каких либо изменений в фильтре, но до его принятия.
before, Союз
[bɪˈfɔ:]
прежде, чем
скорее, чем
Но, мне кажется, мастера знают, что это и без меня :)
Плохиш (2013-05-24 15:03:00) [38]Для начала надо бы перевести Before на понятный язык, а потом включить логику.
shadow_hawk (2013-05-24 14:50:00) [39]To Kilkennycat
с чего бы датасет.рекордкоунт должен измениться
не должен
почему рассматриваешь DataSet, когда там ADataSet?
это одно и тоже; ADataSet - переменная в процедуре DBTableViewDataControllerFilterBeforeChange
To Inovet
При GridMode := True обработка фильтра происходит в процедуре:
DBTableViewDataControllerFilterBeforeChange
Я это прочитал в ответах разработчика, но там нет примера - просто фраза - что именно там а срабатывает она по событию OnBeforeChangeв фильтре.
Если у cxGrid поставить GridMode := False, то обработку фильтра надо писать руками. Руками я написал и все работает:
MenuItem1Click и FilterLike.
Написать тело процедуры DBTableViewDataControllerFilterBeforeChangeмне не удается правильно. Все мои попытки заканчиваются оверфлоу стека. Что-то зацикливается, как будто я своими действиями вношу изменения в фильтр постоянно и событие OnBeforeChangeсоответственно срабатывает постоянно - круг замкнулся.
Для проверки я добавил в DBTableViewDataControllerFilterBeforeChange
определение строки, на которой стою
ARecNo := DataSet.RecNo;
и сколько всего строк в датасете при учете фильтра
ARecordCount := DataSet.RecordCount;
Так демонстрирует разработчик, при GridMode := True.
При запуске программы на cxGrid в области фильтра уже есть строка фильтра и включенный чекбокс фильтра.
Ключаю, отключаю чекбокс, перемещаюсь по гриду и вижу, что срабатывает процедура DBTableViewDataControllerFilterBeforeChange, т.к. в capnion формы вижу чему равно количество строк и на какой я стою в данный момент. Количество строк не меняется - значит фильтр не включается, но это и визуально видно - список не меняется, и не происходит отобрадение в футтере это же самое количество, т.е. и футтер не работает, кроме того при вызове фильтра по определенной колонке нет списка втречающихся в этой колонке значений. (справа от заголовка в каждой колонке есть стрелочка вниз- по ней жмем и видим список значений - при GridMode := True он пустой)
В общем, все проблемы описаны. :)
Inovet (2013-05-24 09:58:00) [40]> [0] shadow_hawk © (23.05.13 19:05)
> ARecNo := DataSet.RecNo;
> ARecordCount := DataSet.RecordCount;
Первое совсем плохо. Второе будет работать только при определённых условиях, но ты же не грузишь все за раз...