Сортировка в базе данных
Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду
Подскажите, пожалуйста, как сделать сортировку в базе, если набор данных отображается в таблице.
procedure TMyBD.FormActivate(Sender: TObject);
// программное подключение к БД
begin
DataSource1.DataSet:=Nakls; // источник данных - таблица
with Session do
begin
ConfigMode := cmSession;
try
{ Если файл данных находится в том же каталоге,
что и выполняемый файл программы, то в программе
путь к файлу данных может быть получен из командной
строки при помощи функции ExtractFilePath(ParamStr(0)).
В приведенном примере файл данных находиться в подкаталоге
DATA каталога программы. }
// создадим временный псевдоним для базы данны
AddStandardAlias( 'PROBA',(ExtractFilePath(ParamStr(0))+'\DATA'),'PARADOX');
Nakls.Active:=True; // откроем базу данных
finally
ConfigMode := cmAll;
end;
end;
end;
// процедура открытия файлов при клике по ячейке
procedure TMyBD.DBGrid1CellClick(Column: TColumn);
begin
if DBGrid1.SelectedField.AsString=Nakls['File'] then
begin
if Nakls.FieldByName('ID').AsInteger=30 then
begin
{Nakls :=}ShellExecute(0,'Open',pchar('c:\h.xmcd'),nil,nil,1);
if not FileExists ( 'c:\h.xmcd' ) then MessageDlg ('Файл не найден',MtError,[mbOK],0); //выдать ошибку если файл не существует
end;
if Nakls.FieldByName('ID').AsInteger=10 then
ShellExecuteA(0, 'Open',pchar( ExtractFilePath(application.exename )+'МНК.xmcd'),nil,nil,1);
if Nakls.FieldByName('ID').AsInteger=20 then
ShellExecuteA(0, 'Open',pchar( ExtractFilePath(application.exename )+'\ModelSupport\1-5.xmcd'),nil,nil,1);
end;
end;
// Пытаюсь сделать сортировку по полю H (высота), которое имеет в наборе повторяющиеся значения
procedure TMyBD.Button1Click(Sender: TObject);
begin
Nakls.AddIndex('indH','H',[]);
Nakls.IndexName:='indH';
end;
end.
Программа при нажатии кнопки сортировки выдает ошибки о том, что индексного поля не существует, или о том, что нельзя открыть таблицу для уникального использования, или о том, что у нее нет памяти на все это дело. SQL-запросы делать нельзя, потому что в хэлпе не нашла, как с помощью них программно обращаться к базе и открываемым через нее файлам. Можно ли как-то исправить проблему?
Спасибо!
procedure TMyBD.FormActivate(Sender: TObject);
// программное подключение к БД
begin
DataSource1.DataSet:=Nakls; // источник данных - таблица
with Session do
begin
ConfigMode := cmSession;
try
{ Если файл данных находится в том же каталоге,
что и выполняемый файл программы, то в программе
путь к файлу данных может быть получен из командной
строки при помощи функции ExtractFilePath(ParamStr(0)).
В приведенном примере файл данных находиться в подкаталоге
DATA каталога программы. }
// создадим временный псевдоним для базы данны
AddStandardAlias( 'PROBA',(ExtractFilePath(ParamStr(0))+'\DATA'),'PARADOX');
Nakls.Active:=True; // откроем базу данных
finally
ConfigMode := cmAll;
end;
end;
end;
// процедура открытия файлов при клике по ячейке
procedure TMyBD.DBGrid1CellClick(Column: TColumn);
begin
if DBGrid1.SelectedField.AsString=Nakls['File'] then
begin
if Nakls.FieldByName('ID').AsInteger=30 then
begin
{Nakls :=}ShellExecute(0,'Open',pchar('c:\h.xmcd'),nil,nil,1);
if not FileExists ( 'c:\h.xmcd' ) then MessageDlg ('Файл не найден',MtError,[mbOK],0); //выдать ошибку если файл не существует
end;
if Nakls.FieldByName('ID').AsInteger=10 then
ShellExecuteA(0, 'Open',pchar( ExtractFilePath(application.exename )+'МНК.xmcd'),nil,nil,1);
if Nakls.FieldByName('ID').AsInteger=20 then
ShellExecuteA(0, 'Open',pchar( ExtractFilePath(application.exename )+'\ModelSupport\1-5.xmcd'),nil,nil,1);
end;
end;
// Пытаюсь сделать сортировку по полю H (высота), которое имеет в наборе повторяющиеся значения
procedure TMyBD.Button1Click(Sender: TObject);
begin
Nakls.AddIndex('indH','H',[]);
Nakls.IndexName:='indH';
end;
end.
Программа при нажатии кнопки сортировки выдает ошибки о том, что индексного поля не существует, или о том, что нельзя открыть таблицу для уникального использования, или о том, что у нее нет памяти на все это дело. SQL-запросы делать нельзя, потому что в хэлпе не нашла, как с помощью них программно обращаться к базе и открываемым через нее файлам. Можно ли как-то исправить проблему?
Спасибо!
Пользуйтесь компонентом EhLib там есть сортировка, просто подгрузите библиотеку "EhLibADO".
Если пользуетесь стандартным компонентом DBGrid, тогда по клику на столбец:
[syntax='Delphi']
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
ss : string;
begin
if dmBase.quW.FieldByName(Column.FieldName).Tag=0 then
begin
ss := ' ASC';
dmBase.quW.FieldByName(Column.FieldName).Tag := 1;
end
else
begin
ss := ' DESC';
dmBase.quW.FieldByName(Column.FieldName).Tag := 0;
end;
dmBase.quW.Sort:=Column.FieldName + ss;
end;
[/syntax]
Если пользуетесь стандартным компонентом DBGrid, тогда по клику на столбец:
[syntax='Delphi']
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
ss : string;
begin
if dmBase.quW.FieldByName(Column.FieldName).Tag=0 then
begin
ss := ' ASC';
dmBase.quW.FieldByName(Column.FieldName).Tag := 1;
end
else
begin
ss := ' DESC';
dmBase.quW.FieldByName(Column.FieldName).Tag := 0;
end;
dmBase.quW.Sort:=Column.FieldName + ss;
end;
[/syntax]
< L3X. (ICQ: 8721378, Mail - l3x@list.ru)
Поясните, пожалуйста, код. Пыталась использовать его в своей программе, но не до конца понимаю, что вы имеете ввиду.
dmBase - это таблица TTable или может быть TDataBase? К какому компоненту это отнести?
quW - это имя поля? или это список полей FieldList?
dmBase.quW.Sort:=Column.FieldName + ss; здесь программа пишет, что левую часть нельзя приравнивать. Возможно это потому, что я не до конца понимаю, что имеется ввиду под dmBase и quW.
Спасибо!
dmBase - это таблица TTable или может быть TDataBase? К какому компоненту это отнести?
quW - это имя поля? или это список полей FieldList?
dmBase.quW.Sort:=Column.FieldName + ss; здесь программа пишет, что левую часть нельзя приравнивать. Возможно это потому, что я не до конца понимаю, что имеется ввиду под dmBase и quW.
Спасибо!
ADOConnection + DataSource + Query
dmBase - Таблица
quW - квери
dmBase - Таблица
quW - квери
< L3X. (ICQ: 8721378, Mail - l3x@list.ru)
Спасибо, но через квери не работает функция открытия файлов из БД... и программное обращение к набору данных тоже ругается..
- Игорь Акопян
- Сообщения: 1440
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
дык а у вас из БД ничего не открывается... Файл лежит на диске, в зависимости от значений в полях открывается.... БД то при чём?

Спасибо.
Да, файл лежит на диске. В БД вписаны комментарии и прочие поля, по которым затем надо будет произвести сортировку. А файлы должны открываться при клике на ячейку данного поля. Для каждой ячейки свой файл. Если БД представлена через TTable, то есть возможность открыть нужные файлы, но нет возможности произвести сортировку в сетке DBGrid. Если БД представлена через query, то есть возможность произвести сортировку, но ячейки никак не реагируют на нажатие на них и не открывают файлы...
Да, файл лежит на диске. В БД вписаны комментарии и прочие поля, по которым затем надо будет произвести сортировку. А файлы должны открываться при клике на ячейку данного поля. Для каждой ячейки свой файл. Если БД представлена через TTable, то есть возможность открыть нужные файлы, но нет возможности произвести сортировку в сетке DBGrid. Если БД представлена через query, то есть возможность произвести сортировку, но ячейки никак не реагируют на нажатие на них и не открывают файлы...
- Игорь Акопян
- Сообщения: 1440
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
Секунду. Если вы открываете файл с диска при клике в ячейке, то работает метод OnClick грида.
Оно никак не зависит от способа получения данных в этот грид. Покажите что не выходит если там квери. Кмк, надо двигаться в этом направлении
Оно никак не зависит от способа получения данных в этот грид. Покажите что не выходит если там квери. Кмк, надо двигаться в этом направлении


Спасибо. Во всем виновата моя невнимательность. Процедуры надо было не просто в коде описать, но и задать их в Events DBGrid. Теперь работает сортировка, открываются файлы. Работает навигатор. Есть возможность редактировать поля в режиме выполнения программы. Но после того, как выполняется сортировка, исчезает возможность редактировать поля и добавлять или удалять строки. Программа выдает исключение о том, что таблица работает только для чтения. Если сортировку не выполнять, то никаких исключений не появляется при изменении значения полей.
[syntax='Delphi']
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBTables, Grids, DBGrids, ExtCtrls, OleCtnrs, shellapi, StdCtrls,
DBCtrls, Mask;
type
TForm1 = class(TForm)
Database1: TDatabase;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Query1: TQuery;
Query1ID: TIntegerField;
Query1File: TStringField;
Query1Comment: TStringField;
Query1H: TFloatField;
DBNavigator1: TDBNavigator;
procedure DBGrid1DblClick(Sender: TObject);
procedure DBGrid1CellClick(Column: TColumn);
procedure DBGrid1TitleClick(Column: TColumn);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if DBGrid1.SelectedField=Query1.Fields[1] then
begin
case Query1.FieldByName('ID').AsInteger of
10: //Если при клике в данной строке значение поля ID=10
//открываем файл
ShellExecute(0, 'Open',pchar( ExtractFilePath(application.exename )+'МНК.xmcd'),nil,nil,1);
20: //Если при клике в данной строке значение поля ID=20
//открываем другой файл другим способом задания адреса
ShellExecute(0, 'Open',pchar( ExtractFilePath(application.exename )+'\ModelSupport\1-5.xmcd'),nil,nil,1);
30: begin //При этом если в данной строке значение поля ID=30
if FileExists ('c:\h.xmcd') then
begin
//открываем файл, который лежит по данному адресу **** это если надо открыть файл по указанному пути, а не фиксированный
ShellExecute(0,'Open',pchar('c:\h.xmcd'),nil,nil,1);
end
else //выдать ошибку если файл не существует
MessageDlg ('Файл не найден',MtError,[mbOK],0);
end;
end;
end;
end;
//Сортировка по нажатию на шапку колонки
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
try
if Column.FieldName='H' then //если поле, по шапке которого был произведён клик
begin // - H, то выполняем сортировку по этому полю
Query1.Close; // закрываем базу данных
Query1.SQL.Clear;
//подготавливаем запрос
Query1.SQL.Add('select * from "Nakls.db" ORDER BY H ');
//собственно SQL запрос
Query1.Open;
//выполняем запрос
end;
finally
end;
try
if Column.FieldName='Comment' then //если поле, по шапке которого был произведён клик
begin // - Comment, то выполняем сортировку по этому полю
Query1.Close; // закрываем базу данных
Query1.SQL.Clear;
//подготавливаем запрос
Query1.SQL.Add('select * from "Nakls.db" ORDER BY Comment Asc');
//собственно SQL запрос
Query1.Open;
//выполняем запрос
end;
finally
end;
end;
// Правка поля при двойном клике на нем
procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
Query1.Edit;
end;
end.
[/syntax]
Есть ли какое-то свойство, которое можно поменять после сортировки, чтобы вновь вернуть возможность редактирования полей и добавления/удаления ячеек?
Спасибо!
[syntax='Delphi']
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBTables, Grids, DBGrids, ExtCtrls, OleCtnrs, shellapi, StdCtrls,
DBCtrls, Mask;
type
TForm1 = class(TForm)
Database1: TDatabase;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Query1: TQuery;
Query1ID: TIntegerField;
Query1File: TStringField;
Query1Comment: TStringField;
Query1H: TFloatField;
DBNavigator1: TDBNavigator;
procedure DBGrid1DblClick(Sender: TObject);
procedure DBGrid1CellClick(Column: TColumn);
procedure DBGrid1TitleClick(Column: TColumn);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if DBGrid1.SelectedField=Query1.Fields[1] then
begin
case Query1.FieldByName('ID').AsInteger of
10: //Если при клике в данной строке значение поля ID=10
//открываем файл
ShellExecute(0, 'Open',pchar( ExtractFilePath(application.exename )+'МНК.xmcd'),nil,nil,1);
20: //Если при клике в данной строке значение поля ID=20
//открываем другой файл другим способом задания адреса
ShellExecute(0, 'Open',pchar( ExtractFilePath(application.exename )+'\ModelSupport\1-5.xmcd'),nil,nil,1);
30: begin //При этом если в данной строке значение поля ID=30
if FileExists ('c:\h.xmcd') then
begin
//открываем файл, который лежит по данному адресу **** это если надо открыть файл по указанному пути, а не фиксированный
ShellExecute(0,'Open',pchar('c:\h.xmcd'),nil,nil,1);
end
else //выдать ошибку если файл не существует
MessageDlg ('Файл не найден',MtError,[mbOK],0);
end;
end;
end;
end;
//Сортировка по нажатию на шапку колонки
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
try
if Column.FieldName='H' then //если поле, по шапке которого был произведён клик
begin // - H, то выполняем сортировку по этому полю
Query1.Close; // закрываем базу данных
Query1.SQL.Clear;
//подготавливаем запрос
Query1.SQL.Add('select * from "Nakls.db" ORDER BY H ');
//собственно SQL запрос
Query1.Open;
//выполняем запрос
end;
finally
end;
try
if Column.FieldName='Comment' then //если поле, по шапке которого был произведён клик
begin // - Comment, то выполняем сортировку по этому полю
Query1.Close; // закрываем базу данных
Query1.SQL.Clear;
//подготавливаем запрос
Query1.SQL.Add('select * from "Nakls.db" ORDER BY Comment Asc');
//собственно SQL запрос
Query1.Open;
//выполняем запрос
end;
finally
end;
end;
// Правка поля при двойном клике на нем
procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
Query1.Edit;
end;
end.
[/syntax]
Есть ли какое-то свойство, которое можно поменять после сортировки, чтобы вновь вернуть возможность редактирования полей и добавления/удаления ячеек?
Спасибо!
- Игорь Акопян
- Сообщения: 1440
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
В БДЕ были какие-то ограничения чтобы запрос был редактируемым (Live query) в справке гляньте, нет под рукой.
Если выполнить эти условия не удастся, то придётся обходить. Например, по даблклику открывать окно с обычными контролами, которые проинициализировать значениями из БД, после редактирования выполнить запрос на обновление нужной записи и после закрытия окна перечитать исходный запрос, при необходимости запомнить строку на которой стояли и перепрыгнуть на неё снова. Это как вариант.
Если выполнить эти условия не удастся, то придётся обходить. Например, по даблклику открывать окно с обычными контролами, которые проинициализировать значениями из БД, после редактирования выполнить запрос на обновление нужной записи и после закрытия окна перечитать исходный запрос, при необходимости запомнить строку на которой стояли и перепрыгнуть на неё снова. Это как вариант.
