Форум: "Начинающим";
Текущий архив: 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
Время: 0.101 c