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

Вниз

Сортировка данных по нажатию на заголовок DBGrid   Найти похожие ветки 

 
duponamk ©   (2015-01-22 04:26) [0]

День добрый, уважаемые.
Нужен совет, как заставить нормально работать сортировку по клику на заголовке DBGrid"а.
Индексы я создал, сортировка по ним из отдельной формы идет как надо.
На форме DBGrid из пакета AlphaControls (прога, соотв., тоже на этих контролах строится).
Для отображения инфы из базы используется 6 полей, соотв., в размер грида полностью помещается инфа 4х полей. 2 последних уползают за край грида.
Так вот, если я нажимаю на заголовках первых 4х столбцов - сортировка происходит нормально. А если тыкнуть на последних 2х заголовках, предварительно прокрутив окно, чтобы они стали видны - прога считает, что я нажал на 4ом столбце и сортирует соответственно.
Сортировка организована так:
...

IndexesList: array[0..5] of string;

...

//Запишем названия индексов в массив
IndexesList[0] := "index_idx";
IndexesList[1] := "opsname_idx";
IndexesList[2] := "region_idx";
IndexesList[3] := "autonom_idx";
IndexesList[4] := "area_idx";
IndexesList[5] := "city_idx";

...

procedure TPstIdxMainForm.GridTitleClick(Column: TColumn);
begin
ShowMessage(IntToStr(Column.Index));
PstIdxDat.Table1.Active := False;
(PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[Column.Index];
PstIdxDat.Table1.Active := True;
end;


Как поправить код, чтобы сортировка отрабатывала на нужных столбцах правильно? Раньше просто этого не надо было, сейчас решил добавить - и задумался :).
Использую Delphi XE4.
PS. Просьба: EhLib, сортировку с помощью SQL запросов, THeaderControl - не предлагать (не то пальто :)).


 
Inovet ©   (2015-01-22 08:01) [1]

if TColumn.Field = МойКолум1 then


 
Inovet ©   (2015-01-22 08:02) [2]

> [1] Inovet ©   (22.01.15 08:01)
> TColumn

Column


 
duponamk ©   (2015-01-22 09:25) [3]


> > [1] Inovet ©   (22.01.15 08:01)
> > TColumn
>
> Column


МойКолум1 - а дальше? С чем, собственно, сравнивать? В процедуру передается только столбец, по которому нажали.


 
duponamk ©   (2015-01-22 09:33) [4]

А по нажатию на последние 2 столбца, прога считает, что нажали на 3-4й столбцы и соответственно их сортирует.


 
junglecat ©   (2015-01-22 09:34) [5]

(PstIdxDat.Source1.Dataset as TABSTable).IndexName := Column.FieldName + "_idx" ?


 
duponamk ©   (2015-01-22 09:45) [6]


> (PstIdxDat.Source1.Dataset as TABSTable).IndexName := Column.
> FieldName + "_idx" ?


Не прокатывает. Я ж говорю, прога при сдвиге грида вправо считает, что последние 2 столбца - это 3-4й, а не 5-6й. Счет столбцов нарушается какого-то лешего. Мне и интересно, как эту бяку побороть?


 
junglecat ©   (2015-01-22 09:52) [7]

type TCrackedGrid = class(TDBGrid)
public
 property LeftCol;
end;

(PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[Column.Index + TCrackedGrid(Grid).LeftCol] ?


 
duponamk ©   (2015-01-22 10:02) [8]


> type TCrackedGrid = class(TDBGrid)
> public
>  property LeftCol;
> end;
>
> (PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[Column.
> Index + TCrackedGrid(Grid).LeftCol] ?


Не проходит.
Я не зря в коде указал вызов ShowMessage. При нажатии на столбец, мне показывается номер столбца, по которому я якобы тыкнул. В данном случае, когда я нажимаю на 5-6й столбцы, ShowMessage выдает мне, что я якобы нажал на 3-4й столбцы, а не 5-6й.
Вот, что называется, и думай, а почему так, а не так как надо?


 
junglecat ©   (2015-01-22 10:08) [9]

а в TCrackedGrid(Grid).LeftCol что в этом случае?


 
Inovet ©   (2015-01-22 16:12) [10]

> [3] duponamk ©   (22.01.15 09:25)
> МойКолум1 - а дальше? С чем, собственно, сравнивать?

А дальше выставляй нужный индекс. Сравнивать с указателем на поле. У тебя поля в датасете созданы в дизайнтайм? Если нет, сравнивай по имени поля.


 
duponamk ©   (2015-01-22 18:09) [11]


> а в TCrackedGrid(Grid).LeftCol что в этом случае?


То же, что и написал постом выше вашего:

> Не проходит.
> Я не зря в коде указал вызов ShowMessage. При нажатии на
> столбец, мне показывается номер столбца, по которому я якобы
> тыкнул. В данном случае, когда я нажимаю на 5-6й столбцы,
>  ShowMessage выдает мне, что я якобы нажал на 3-4й столбцы,
>  а не 5-6й.
> Вот, что называется, и думай, а почему так, а не так как
> надо?



> > [3] duponamk ©   (22.01.15 09:25)
> > МойКолум1 - а дальше? С чем, собственно, сравнивать?
>
> А дальше выставляй нужный индекс. Сравнивать с указателем
> на поле. У тебя поля в датасете созданы в дизайнтайм? Если
> нет, сравнивай по имени поля.


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


 
Inovet ©   (2015-01-22 18:24) [12]

> [11] duponamk ©   (22.01.15 18:09)

В гриде указатели на поля TField а вот в них имя поля есть, но зачем, если эти же поля есть в Датасете вот и сравниванй указатели. Кликнули по заголовку, взял указатель на поле, которое привязано к этому столбцу, сравниваешь со своими. Например:

if      f = datasetFIELD1 then dataset.IndexName := "idx1";
else if f = datasetFIELD2 then dataset.IndexName := "idx2";
else if f = datasetFIELD3 then dataset.IndexName := "idx3";


 
duponamk ©   (2015-01-22 18:33) [13]

Методом научного тыка выяснил: после нажатия на правую часть горизонтального скроллбара, он сдвигает грид вправо и показывает последние 5-6й столбцы грида, как и было велено. После нажатия, например, на 5ом столбце, грид мотается назад к исходному состоянию и в этот момент, скорее всего, и фиксируется нажатие на заголовок. Но в этот момент курсор мыши уже находится над 3им столбцом и, прога считает, что я нажал на 3ИЙ столбец, а не на 5ЫЙ. И идет сортировка по 3ему столбцу.
Как-то так.
Так что поля тут, скорее всего, ни при чем. Скорее, надо каким-то образом ловить этот момент и соответственно его обрабатывать. А вот как...


 
duponamk ©   (2015-01-22 18:35) [14]

if      f = datasetFIELD1 then dataset.IndexName := "idx1";
else if f = datasetFIELD2 then dataset.IndexName := "idx2";
else if f = datasetFIELD3 then dataset.IndexName := "idx3";


Сча попробую.


 
duponamk ©   (2015-01-22 19:04) [15]

Нет, не проходит такой фокус.


 
Inovet ©   (2015-01-22 19:36) [16]

> [15] duponamk ©   (22.01.15 19:04)

Что именно не ппроходит?


 
duponamk ©   (2015-01-23 11:23) [17]


> Что именно не ппроходит?


Вариант с датасетами.


 
brother ©   (2015-01-23 11:25) [18]

надо лучше вазелинить)


 
Inovet ©   (2015-01-23 18:30) [19]

> [17] duponamk ©   (23.01.15 11:23)
> Вариант с датасетами.

Код давай.


 
Плохиш ©   (2015-01-24 00:21) [20]


> Код давай.

Испугаться хочешь?


 
junglecat ©   (2015-01-24 13:41) [21]

а что за грид такой загадочный?
с Rx таких проблем нету

procedure TForm1.RxDBGrid1TitleClick(Column: TColumn);
begin
 ADODataSet1.IndexFieldNames := Column.FieldName;
end;


 
duponamk ©   (2015-01-24 14:07) [22]


> а что за грид такой загадочный?
> с Rx таких проблем нету
>
> procedure TForm1.RxDBGrid1TitleClick(Column: TColumn);
> begin
>  ADODataSet1.IndexFieldNames := Column.FieldName;
> end;


Грид из набора AlphaControls, о чем я писал в первом посте.
RxDBGrid не подходит, хоть он у меня и есть. Не то пальто.
ADO не использую - не нужен для программы.


 
duponamk ©   (2015-01-24 14:10) [23]


> Код давай.



...

IndexesList: array[0..5] of string;

...

//Запишем названия индексов в массив
IndexesList[0] := "index_idx";
IndexesList[1] := "opsname_idx";
IndexesList[2] := "region_idx";
IndexesList[3] := "autonom_idx";
IndexesList[4] := "area_idx";
IndexesList[5] := "city_idx";

...

procedure TPstIdxMainForm.GridTitleClick(Column: TColumn);
begin
//if      f = datasetFIELD1 then dataset.IndexName := "idx1";
//else if f = datasetFIELD2 then dataset.IndexName := "idx2";
//else if f = datasetFIELD3 then dataset.IndexName := "idx3";

PstIdxDat.Table1.Active := False;
if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(0) then
 (PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[0]
else if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(1) then
 (PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[1]
else if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(2) then
(PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[2]
else if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(3) then
 (PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[3]
else if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(4) then
(PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[4]
else if Column.Field = PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(5) then
(PstIdxDat.Source1.Dataset as TABSTable).IndexName := IndexesList[5];
PstIdxDat.Table1.Active := True;
end;


Мог в чем-то напутать, т.к. при нажатии на произвольном столбце вылетает ошибка: Accecc violation at address... и т.д.


 
junglecat ©   (2015-01-24 14:17) [24]

> ошибка: Accecc violation at address

тут отладчик нужен
что-то из PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber может быть nil


 
junglecat ©   (2015-01-24 14:19) [25]

и чем этот вариант принципиально отличается от того, что я в [5] предложил?


 
duponamk ©   (2015-01-24 16:09) [26]


> и чем этот вариант принципиально отличается от того, что
> я в [5] предложил?


Может, и ничем. Тот вариант я тоже пробовал. Он нормально отрабатывает на первых 4х столбцах, которые помещаются в гриде. С 5-6м столбцами, которые находятся за пределами грида и чтобы добраться до них, нужен горизонтальный скроллинг грида - идет затыка с сортировкой. После скролла 5-6й столбцы доступны, можно нажать на заголовках этих столбцов. Вот только после нажатия идет обратный скролл и не фиксируется нажатие на последних столбцах. Уже проверено. Фиксируется нажатие на 3-4й столбцы и соответственно этому идет сортировка. Мне, собственно, это и надо победить.


 
junglecat ©   (2015-01-24 16:43) [27]

AlphaControls 2014 v9.19, TsDBGrid
такой проблемы нету


 
Inovet ©   (2015-01-24 19:54) [28]

> [23] duponamk ©   (24.01.15 14:10)
> PstIdxDat.Source1.DataSet.DataSetField.Fields.FieldByNumber(0)

Двойной клик на датасете может спасти ОРД.


 
duponamk ©   (2015-01-25 15:23) [29]


> AlphaControls 2014 v9.19, TsDBGrid
> такой проблемы нету


Проверю. У меня 9.18.


 
duponamk ©   (2015-01-25 18:07) [30]


> AlphaControls 2014 v9.19, TsDBGrid
> такой проблемы нету


Поставил 9.19.
Проблема осталась.
Зато выяснил еще одно: клик по частично видимому 5му столбцу - сортировка по данному столбцу происходит нормально. А по 6му (крайнему) - он невидим вообще (нужен горизонтальный скролл, чтобы его увидеть) - происходит обратный скролл и фиксируется нажатие на 4й столбец и соответственно этому идет сортировка (по 4му столбцу).


 
junglecat ©   (2015-01-25 18:41) [31]

> Поставил 9.19.
> Проблема осталась.

у меня такого не наблюдается. Что я делаю не так?


 
duponamk ©   (2015-01-25 18:55) [32]


> у меня такого не наблюдается. Что я делаю не так?


У тебя столбцы в гриде видны все? Если да - то таких косяков и не будет.
Попробуй сделать так, чтоб крайний столбец не был виден совсем и нужен был горизонтальный скроллинг грида. И после этого попробуй сделать сортировку по крайнему столбцу. У меня не идет.


 
junglecat ©   (2015-01-25 18:59) [33]

Ну я же не совсем тупой. Конечно, я твою ситуацию воспроизвел


 
duponamk ©   (2015-01-25 19:12) [34]


> Ну я же не совсем тупой. Конечно, я твою ситуацию воспроизвел


Извини, не хотел обидеть.
У меня уже мозги набекрень от этой проблемы.
Если в ближайшее время не удастся ее решить - буду думать в сторону уменьшения ширины столбцов, чтоб они влезли, блин, в грид.
Но у меня не одна такая прога, в которой столбцы вылезают за края грида, и туда тоже со временем хотелось бы эту возможность добавить. А ширину столбцов не везде можно убавить.


 
junglecat ©   (2015-01-25 19:41) [35]

возможно, это какой-то косяк именно XE4
В ХЕ3 все пучком


 
junglecat ©   (2015-01-25 21:10) [36]

такой вариант работает на ура
procedure TForm1.sDBGrid1TitleClick(Column: TColumn);
begin
 ADODataSet1.IndexFieldNames := Column.FieldName;
end;

думаю, тип датасета тут рояли не играет, главное, что FieldName приходит правильный


 
Inovet ©   (2015-01-25 23:36) [37]

> [34] duponamk ©   (25.01.15 19:12)
> У меня уже мозги набекрень от этой проблемы.

Пробуешь, конечно, на чистом проекте, не на рабочем?


 
duponamk ©   (2015-01-26 06:26) [38]


> думаю, тип датасета тут рояли не играет, главное, что FieldName
> приходит правильный


Ты прав, тип датасета роли не играет, если имя поля правильное.


> Пробуешь, конечно, на чистом проекте, не на рабочем?


Может, это и неправильно, но делаю прямо на рабочем проекте: нет времени на создание нового и проверки всего вышепредложенного в новом проекте.

Проблема решилась: установил версию 9.19 AphaControls с AlphaDB-Aware, удалил с формы DBGrid, добавил ее по-новой - глюк исчез. Delphi не обновил в проекте инфу о том, что стоит новый набор компонентов.
Сейчас, насколько я могу судить, все работает как надо.

Спасибо всем за помощь. Тему можно закрывать.



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

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

Наверх




Память: 0.55 MB
Время: 1.301 c
2-1428788906
BBC
2015-04-12 00:48
2017.01.15
Фокусировка PaintBox


2-1426067911
aka
2015-03-11 12:58
2017.01.15
TObject через ссылку


3-1308469793
she-wolf2829
2011-06-19 11:49
2017.01.15
запуск хранимых процедур


2-1424539948
Fox
2015-02-21 20:32
2017.01.15
Интернет ТВ


15-1453995709
Внук
2016-01-28 18:41
2017.01.15
Классовые методы с неклассовыми свойствами





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