17.11.2019, 12:33 [+3 UTC]
в нашей команде: 3 977 чел. | участники онлайн: 7 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.77 (31.05.2019)
JS-v.1.34 | CSS-v.3.35

Общие новости:
28.04.2019, 09:13

Форум:
16.11.2019, 20:23

Последний вопрос:
17.11.2019, 12:05
Всего: 150984

Последний ответ:
17.11.2019, 02:39
Всего: 259420

Последняя рассылка:
17.11.2019, 10:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
21.02.2010, 17:19 »
DimasaN
Круто Большой Рахмат так просто и круто ну и ну !!!!!!!!вот это да !!!!!!!!!!!!!!! [вопрос № 176820, ответ № 259630]
23.04.2010, 04:19 »
Иванов Анатолий Николаевич
Отлично!!! Благодарю за помощь. С уважением, Анатолий. [вопрос № 177912, ответ № 260968]
20.10.2017, 20:07 »
zuihin.c@mail.ru
Спасибо огромное! не знал как подступиться, выручили . [вопрос № 191508, ответ № 275392]

РАЗДЕЛ • Pascal / Delphi / Lazarus

Создание программ на языках Pascal, Delphi и Lazarus.

[администратор рассылки: Зенченко Константин Николаевич (Старший модератор)]

Лучшие эксперты в этом разделе

Gluck
Статус: 7-й класс
Рейтинг: 873
Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 565
puporev
Статус: Профессионал
Рейтинг: 306

Перейти к консультации №:
 

Консультация онлайн # 187705
Раздел: • Pascal / Delphi / Lazarus
Автор вопроса: Владимир (Посетитель)
Отправлена: 05.01.2014, 18:06
Поступило ответов: 1

Здравствуйте! У меня возникли сложности с таким вопросом: В процессе создания программы использую DBGrid. Для удобства пользования решил сделать сортировку в отображаемой таблице. Отыскал интересный вариант сортировки. Ссылка на описание сортировки.

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
{$J+}
 const PreviousColumnIndex : integer = -1;
{$J-}
begin
  if DBGrid1.DataSource.DataSet is TCustomADODataSet then
  with TCustomADODataSet(DBGrid1.DataSource.DataSet) do
  begin
    try
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
    except
    end;

    Column.title.Font.Style := 
    Column.title.Font.Style + [fsBold];
    PreviousColumnIndex := Column.Index;

    if (Pos(Column.Field.FieldName, Sort) = 1)
    and (Pos(' DESC', Sort)= 0) then
      Sort := Column.Field.FieldName + ' DESC'
    else
      Sort := Column.Field.FieldName + ' ASC';
  end;
end;


У меня несколько вопросов.
1- Если возможно объясните как пошагово код работает. Ибо не просто заниматся копипастом, а еще и разобратся.
2- Сортировка работает, но при следующем пуске программы отображение в DBGrid1 опять идет по id базы данных.
Как сделать чтобы отображалось по последней сортировке (настройки программы сохраняются в ini файл при закрытии программы WriteParams).
Получается что при пуске программы читается по чем сортировка в DBGrid1?
Вот понаписал!

Состояние: Консультация закрыта

Ответ # 272631 от Филатов Евгений Геннадьевич

Здравствуйте, Владимир!

Начну с ответа на второй вопрос.

Объявляем глобальную переменную, в которой хранится номер столбца предыдущей сортировки
PreviousColumnIndex : integer = -1;

Пусть данные последней сортировки сохраняются в ini-файл командой
IniFile.WriteInteger('-----0-DBGrid1-----','Index', PreviousColumnIndex);
При этом в переменной PreviousColumnIndex уже хранится какое-либо неотрицательное значение ( т.е. индекс уже выбран )

В случае первого добавления кода в программу в ini-файле такого значения не будет, поэтому может выскочить ошибка. Чтобы этого избежать нужно изменить начальное значение переменной
PreviousColumnIndex : integer = 0;
Тогда если значения нет, то будет задана сортировка по первому столбцу по возрастанию. В дальнейшем после сохранения значения в файле будет работать нормально.

После первой прорисовки формы необходимо запустить код

if DBGrid1.DataSource.DataSet is TCustomADODataSet then
//На самом деле, эта проверка необязательна. Если есть 100% уверенности,
//что в источниках данных используется только ADO подключение, то можно
//убрать проверку. Но ошибкой наличие проверки не будет.

begin

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

//Заносим в переменную номер столбца сортировки из ini-файла
PreviousColumnIndex := IniFile.ReadInteger('-----0-DBGrid1-----','Index', PreviousColumnIndex);
//Возможно, при первом запуске нужно будет заредактировать эту строку, т.к. в ini-файле еще нет такого параметра и может выскочить ошибка.

//Выделяем заголовок столбца новой сортировки
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style:=
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style + [fsBold];

//Запускаем сортировку по возрастанию, взяв имя поля из таблицы
TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort :=
DBGrid1.Columns[PreviousColumnIndex].FieldName + ' ASC';

end;


Далее работает обработка события нажатия на заголовок столбца таблицы ( это ответ на первый вопрос ) .

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
//Входным параметром является стобец таблицы
begin
//Проверяем, что источник данных является источником ADO
if DBGrid1.DataSource.DataSet is TCustomADODataSet then
//Не будем использовать оператор With для сокращения записей чтобы было видно, где какой объект задействован
begin
//Т.к. в переменной может храниться неверное значение, или она еще не определена, то делаем обработку возможной ошибки
try
//Отменяем выделение заголовка столбца предыдущей сортировки
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
except
//Если возникла ошибка, ничего не делаем и выполняем последующие операторы
end;
//Устанавливаем выделение заголовка нажатого стобца
Column.title.Font.Style := Column.title.Font.Style + [fsBold];
//Заносим в переменную выделенный столбец, чтобы знать, какому заголовку потом отменять выделение
PreviousColumnIndex := Column.Index;
//Здесь двойная проверка. В первой проверяется, является ли текущая сортировка уже по выбранному столбцу и в случае верного результата проверяется наличие в сортировке ключевого слова DESC ( по убыванию ) .
if (Pos(Column.Field.FieldName, TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort) = 1)
and (Pos(' DESC', TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort)= 0) then
//Если сортировка уже по текущему столбцу и не по убыванию, то устанавливаем
TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort := Column.Field.FieldName + ' DESC'
else
//Во всех остальных случаях устанавливаем сортировку по выбранному столбцу по возрастанию
TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort := Column.Field.FieldName + ' ASC';
end;
end;

Кажется все.

С уважением.


Консультировал: Филатов Евгений Геннадьевич
Дата отправки: 12.01.2014, 13:55

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 187705

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 1

= общий = | 06.01.2014, 15:26 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Владимир:

1)Самой сортировки в коде нет, она спрятана в методе SORT. В данном коде только формирование данных для "SQL-запроса" в метод SORT и работа со стилем имени колонки.
Если уже вибиралось поле сортировки раньше, стиль отображения заголовка колонки сбрасывается:

DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=. . .

Устанавливается новый стиль отображения заголовка колонки и новая текущая колонка сортировки:
Column.title.Font.Style :=. . .
PreviousColumnIndex:=. . .

Данные для запроса "имя колонки и убывание/возрастание:"
Sort:=. . .


2)
© Цитата: Владимир
Получается что при пуске программы читается по чем сортировка в DBGrid1

Да. Если индексное поле базы не совопадает с последним использованным полем сортировки, нужно будет проводить принудительную сортировку по нужному полю.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Владимир
Посетитель

ID: 352040

# 2

= общий = | 06.01.2014, 16:42 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Зенченко Константин Николаевич:

По первому вопросу понятно. Спасибо, разъяснили.
По второму вопросу. У меня в базе несколько таблиц. Основная таблица "S1" в ней поле "ID" с типом данных "счетчик". Все таблицы связаны с этим полем. И сортировка DBGrid1 у меня получается идет по "ID". Исходя из Вашего ответа мне нужно сохранить последнее использованное поле сортировки, и при запуске приложения из сохраненных настроек взять последнее поле и принудительно отсортировать.
Исходя из всего изложенного, что мне сохранять в ini файл с настройками?

=====
Пользуюсь Delphi Enterprise Version7.

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 3

= общий = | 06.01.2014, 16:51 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Владимир:

Что Вас больше устраивает. К примеру: PreviousColumnIndex или FieldName

-----
Последнее редактирование 06.01.2014, 16:51 Зенченко Константин Николаевич (Старший модератор)

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Владимир
Посетитель

ID: 352040

# 4

= общий = | 06.01.2014, 17:36 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Зенченко Константин Николаевич:

Это касаемо DBGrid1 сохранение? Потому как когда пишу код, после DBGrid1 ставлю точку, и нет PreviousColumnIndex ни FieldName
Так у меня происходит запись, чтение ширины колонки DBGrid1.

IniFile.WriteInteger('-----0-DBGrid1-----','2-0',DBGrid1.Columns.Items[0].Width);

DBGrid1.Columns.Items[0].Width:=IniFile.ReadInteger('-----0-DBGrid1-----','2-0',DBGrid1.Columns.Items[0].Width);
А как сюда прикрутить PreviousColumnIndex?

=====
Пользуюсь Delphi Enterprise Version7.

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 5

= общий = | 08.01.2014, 13:39 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Владимир:

© Цитата: Владимир
Потому как когда пишу код, после DBGrid1 ставлю точку, и нет ...

Просто, Вы не там смотрите эти записи. В коде используется следующий оператор:
© Цитата:
О п е р а т о р w i t h

Оператор with используется для сокращения записи при обращении к полям записей или к свойствам и методам объекта. В этих случаях применение with позволяет избежать повторных ссылок на объект в последующих операторах. Оператор with может записываться следующим образом:
with <объект> do <оператор>;
В операторе,следующем за ключевым словом do, можно для полей, свойств и методов объекта, указанного как <объект>, не включать ссылки на этот объект. При этом каждый идентификатор в операторе, который совпадает с именем поля, свойства, метода объекта, трактуется как относящийся к этому объекту и к нему неявно добавляется ссылка на этот объект.


Т.е. искать нужно после DBGrid1.DataSource.DataSet...

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Филатов Евгений Геннадьевич

# 6

= общий = | 08.01.2014, 14:10
Владимир:

в теории, сохранить данные о последней сортировке в ini-файл реально, как и потом их считать в переменную. я таким образом сохраняю имя последнего пользователя, запускающего программу. а потом после первого открытия формы или при активации запустить процедуру сортировки с данными из ini-файла.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Филатов Евгений Геннадьевич

# 7

= общий = | 10.01.2014, 19:25
Владимир:

По вопросу сохранения данных о сортировке в ini-файл.

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

Объявляем глобальную переменную, в которой хранится номер столбца предыдущей сортировки
PreviousColumnIndex : integer = -1;

Пусть данные последней сортировки сохраняются в ini-файл командой
IniFile.WriteInteger('-----0-DBGrid1-----','Index', PreviousColumnIndex);
При этом в переменной PreviousColumnIndex уже хранится какое-либо неотрицательное значение ( т.е. индекс уже выбран )

После первой прорисовки формы необходимо запустить код

if DBGrid1.DataSource.DataSet is TCustomADODataSet then
//На самом деле, эта проверка необязательна. Если есть 100% уверенности,
//что в источниках данных используется только ADO подключение, то можно
//убрать проверку. Но ошибкой наличие проверки не будет.

//Можно добавить оператор
// with TCustomADODataSet(DBGrid1.DataSource.DataSet) do
//чтобы в дальнейшем работать с методами и свойствами объекта
// DBGrid1.DataSource.DataSet
//но это немного запутает описание программы, поэтому пишем полные имена

begin

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

//Заносим в переменную номер столбца сортировки из ini-файла
PreviousColumnIndex := IniFile.ReadInteger('-----0-DBGrid1-----','Index', PreviousColumnIndex);

//Выделяем заголовок столбца новой сортировки
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style:=
DBGrid1.Columns[PreviousColumnIndex].title.Font.Style + [fsBold];

//Запускаем сортировку, взяв имя поля из таблицы
TCustomADODataSet(DBGrid1.DataSource.DataSet).Sort :=
DBGrid1.Columns[PreviousColumnIndex].FieldName + ' ASC';

end;

А дальше сортировка настраивается в процедуре при нажатии на заголовок столбца как в примере. Главное не забыть сохранить в ini-файл значение номера столбца сортировки. Можно еще и направление сортировки сохранить – ASC или DESC.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Владимир
Посетитель

ID: 352040

# 8

= общий = | 11.01.2014, 18:09 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Благодарю за подсказку, буду пробовать реализовать в своем проекте. На данный момент вынужден отложить работу, в командировку уезжаю.

=====
Пользуюсь Delphi Enterprise Version7.

Филатов Евгений Геннадьевич

# 9

= общий = | 11.01.2014, 23:00
Владимир:

К сожалению, до закрытия вопроса осталось чуть больше суток. Поэтому завтра днем составлю ответ из сообщений мини-форума, если ув. Зенченко Константин Николаевич не сформирует.

=====
Пользуюсь Delphi Enterprise Version7.

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.14449 сек.

© 2001-2019, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.77 от 31.05.2019
Версия JS: 1.34 | Версия CSS: 3.35