От перестановки двух эквивалентных ошибок результат не меняется (коммутативность эквивалентных ошибок). - В.Тихонов. Теория ошибок.
Предисловие
Пользуясь случаем, поздравляю своих немногочисленных замечательных подписчиц с МЖД, то есть с 8 марта.
Благодаря вам, уважаемые дамы, мы можем ещё один понедельник не ходить на работу или в институт, а заняться чем-либо более полезным - например, прибраться в квартире, в голове или на жёстком диске. :)
А вот чтобы прибраться в Базе Данных - без сортировки не обойтись...
Базы Данных с нуля
Сортировка набора данных
Сортировка записей Базы Данных предназначена для упорядочивания всех записей Базы Данных по
определенному полю в порядке возрастания или в порядке убывания. По умолчанию все записи набора
данных не отсортированы и находятся в том порядке, в каком они были добавлены в БД. С отсортированным
набором данных работать удобней. Отсортировать набор данных можно также сразу по нескольким полям,
при этом происходит упорядочивание записей по первому указанному полю, а затем на основании
"полученных данных" уже по второму.
Наборы данных Table и Query сортируются различными способами. Начнем с сортировки
набора данных Table. Специальных методов для сортировки набора данных Table не
существует. Сортировка происходит при указании текущего индекса, то есть записи БД сортируются
на основании текущего индекса. Если указать другой индекс, то записи сразу же будут отсортированы
заново на основании нового указанного индекса.
Для задания текущего индекса существуют два метода IndexName и IndexFieldName. В качестве
параметра в методе IndexName указывается имя уже созданного индекса, а в методе
IndexFieldName - имя или имена полей, по которым должен быть "построен" индекс. Не нужно
забывать, что при совместном использовании сразу двух этих методов, происходит взаимное
их исключение, то есть установка значения одного приводит к исключению значения другого. Если
попытаться указать не существующее поле, то это приведет к исключительной ситуации. Рассмотрим
небольшой пример, в котором задаются индексы для двух наборов данных рассмотренными методами:
procedure TForm1.ButtonSetIndexClick(Sender: TObject);
begin
Table1.IndexName:='indTown';
Table2.IndexFieldNames:='Code;Name';
end;
Обратите внимание на то, что для набора данных Table2 задается индекс сразу для двух полей
Базы Данных. В этом случае поля БД нужно перечислить через символ ';' (точку с запятой).
Обычно все индексы создаются на этапе разработки таблицы Базы Данных, но иногда требуется создать
один или несколько индексов динамически, то есть во время выполнения программы. Для этого служит
метод AddIndex. Чтобы создать новый индекс необходимо указать имя создаваемого индекса,
указать поле, по которому строится индекс, и задать возможные параметры. Если требуется создать
индекс сразу по нескольким полям, то имена полей нужно также перечислить через точку с запятой.
Если указать не существующее поле БД, то это приведет к исключительной ситуации. Перед созданием
нового индекса набор данных должен быть обязательно закрыт. Рассмотрим пример создания нового
индекса:
Для удаления индекса используется метод DeleteIndex. В качестве параметра необходимо указать
имя созданного индекса. При попытке указать не существующий индекс, также возникнет исключительная
ситуация. Перед удалением индекса набор данных также должен быть закрыт. Рассмотрим пример
удаления индекса:
procedure TForm1.ButtonDeleteIndexClick(Sender: TObject);
begin
Table1.Close;
Table1.DeleteIndex('indFam');
Table1.Open;
end;
При помощи свойства IndexFieldCount можно узнать сколько полей входит в состав текущего
индекса. Для обновления информации об индексе используется метод UpDate свойства
IndexDefs. При помощи этого же свойства и метода Count можно узнать общее число
индексов для текущей Базы Данных.
procedure TForm1.ButtonDeleteIndexClick(Sender: TObject);
begin
// Обновляем информацию об индексах
Table1.IndexDefs.Update;
// Выводим число полей в текущем индексе
ShowMessage(IntToStr(Table1.IndexFieldCount));
//Выводим общее число индексов
ShowMessage(IntToStr(Table1.IndexDefs.Count));
end;
На практике для организации функции сортировки в своей программе удобней создать отдельную
форму, на которой расположить некоторое количество переключателей. Каждый переключатель будет
отвечать за свой индекс. И при выборе пользователем определенного переключателя База Данных
будет отсортирована по соответствующему полю. Вот примерно так это будет выглядеть:
procedure TForm1.ButtonSortClick(Sender: TObject);
begin
Case RadioGroup1.ItemIndex Of
0: Table1.IndexName:='indCode';
1: Table1.IndexName:='indName';
2: Table1.IndexName:='indFam';
3: Table1.IndexName:='indBirthDay';
4: Table1.IndexName:='indTown';
End;
Case RadioGroup2.ItemIndex Of
0: Table2.IndexFieldNames:='Code';
1: Table2.IndexFieldNames:='Name';
2: Table2.IndexFieldNames:='Fam';
3: Table2.IndexFieldNames:='BirthDay';
4: Table2.IndexFieldNames:='Town';
End;
end;
Для набора данных Query сортировка производиться намного проще. Она производиться при
помощи SQL-запроса. Для сортировки набора данных служит команда ORDER BY, которую нужно
включить в запрос. Для сортировки набора данных по убыванию служит параметр DESC,
означающий Descending (по убыванию). Вот простой пример сортировки:
//Сортировка по полю Code (по возрастанию)
procedure TfSort.ButtonSort1Click(Sender: TObject);
begin
Query1.Active:=False;
Query1.SQL.Clear;
Query1.SQL.Add('SELECT * FROM Base\Base.db ORDER BY Code');
Query1.Active:=True;
end;
//Сортировка по полю Name (по убыванию)
procedure TfSort.ButtonSort2Click(Sender: TObject);
begin
Query1.Active:=False;
Query1.SQL.Clear;
Query1.SQL.Add('SELECT * FROM Base\Base.db ORDER BY Name DESC');
Query1.Active:=True;
end;
На практике удобней также расположить на форме несколько переключателей, соответствующих полям
Базы Данных и еще два переключателя для задания направления сортировки. И при нажатии на кнопку
отсортировать набор данных на основании выбранных переключателей. Рассмотрим это на примере:
...
Var OrdBy : String; // Переменная для указания конкретного поля
Str : String; // Переменная для указания конечного выражения запроса
...
// Один из переключателей, соответствующий полю Code
procedure TfSort.rbCodeClick(Sender: TObject);
begin
OrdBy:='ORDER BY Code';
end;
...
// Сортировка по возрастанию
procedure TfSort.rbUpClick(Sender: TObject);
begin
Str:=OrdBy;
end;
// Сортировка по убыванию
procedure TfSort.rbDownClick(Sender: TObject);
begin
Str:=OrdBy + ' DESC';
end;
// Кнопка для выполнения созданного запроса
procedure TfSort.btnOKClick(Sender: TObject);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('SELECT * FROM Base\Base.db' + Str);
Query1.Open;
end;
А теперь попробую объяснить как это работает. При выборе пользователем некоторого переключателя,
соответствующего некоторому полю Базы Данных, переменной OrdBy присваивается команда
сортировки с указанием имени поля, то есть 'ORDER BY Code'. При выборе переключателя для сортировки по убыванию переменной
Str присваивается значение готовой команды для сортировки с параметром DESC, то есть
'ORDER BY Code DESC'. Если же выбран переключатель для сортировки по возрастанию, то
переменной Str просто присваивается значение переменной OrdBy, без указания параметра
DESC.
Любые комментарии, жалобы, пожелания и сообщения об ошибках настоятельная просьба
присылать на e-mail.
Все вопросы, пожелания и предложения ссылкообмена ведущему рассылки, прошу слать на e-mail: urisff@inbox.ru
Все статьи публикуются здесь только с разрешения (или рекомендации) автора.
Если вы хотите опубликовать здесь свою статью, то сделайте это, переслав её мне.
В случае, если вы будете использовать приведённые в этой рассылке материалы, не забудьте сделать ссылку на эту рассылку.