Сортировка в базе данных

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
Ryumka
Сообщения: 14
Зарегистрирован: 06 окт 2009, 13:26

Подскажите, пожалуйста, как сделать сортировку в базе, если набор данных отображается в таблице.

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-запросы делать нельзя, потому что в хэлпе не нашла, как с помощью них программно обращаться к базе и открываемым через нее файлам. Можно ли как-то исправить проблему?

Спасибо!
BHy4ok
Сообщения: 237
Зарегистрирован: 01 май 2007, 09:03
Откуда: г.Находка
Контактная информация:

Пользуйтесь компонентом 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]
< L3X. (ICQ: 8721378, Mail - l3x@list.ru)
Ryumka
Сообщения: 14
Зарегистрирован: 06 окт 2009, 13:26

Поясните, пожалуйста, код. Пыталась использовать его в своей программе, но не до конца понимаю, что вы имеете ввиду.

dmBase - это таблица TTable или может быть TDataBase? К какому компоненту это отнести?

quW - это имя поля? или это список полей FieldList?

dmBase.quW.Sort:=Column.FieldName + ss; здесь программа пишет, что левую часть нельзя приравнивать. Возможно это потому, что я не до конца понимаю, что имеется ввиду под dmBase и quW.

Спасибо!
BHy4ok
Сообщения: 237
Зарегистрирован: 01 май 2007, 09:03
Откуда: г.Находка
Контактная информация:

ADOConnection + DataSource + Query
dmBase - Таблица
quW - квери
< L3X. (ICQ: 8721378, Mail - l3x@list.ru)
Ryumka
Сообщения: 14
Зарегистрирован: 06 окт 2009, 13:26

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

дык а у вас из БД ничего не открывается... Файл лежит на диске, в зависимости от значений в полях открывается.... БД то при чём?
Изображение
Ryumka
Сообщения: 14
Зарегистрирован: 06 окт 2009, 13:26

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

Секунду. Если вы открываете файл с диска при клике в ячейке, то работает метод OnClick грида.
Оно никак не зависит от способа получения данных в этот грид. Покажите что не выходит если там квери. Кмк, надо двигаться в этом направлении ;)
Изображение
Ryumka
Сообщения: 14
Зарегистрирован: 06 окт 2009, 13:26

Спасибо. Во всем виновата моя невнимательность. Процедуры надо было не просто в коде описать, но и задать их в 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]


Есть ли какое-то свойство, которое можно поменять после сортировки, чтобы вновь вернуть возможность редактирования полей и добавления/удаления ячеек?

Спасибо!
Аватара пользователя
Игорь Акопян
Сообщения: 1440
Зарегистрирован: 13 окт 2004, 17:11
Откуда: СПБ
Контактная информация:

В БДЕ были какие-то ограничения чтобы запрос был редактируемым (Live query) в справке гляньте, нет под рукой.
Если выполнить эти условия не удастся, то придётся обходить. Например, по даблклику открывать окно с обычными контролами, которые проинициализировать значениями из БД, после редактирования выполнить запрос на обновление нужной записи и после закрытия окна перечитать исходный запрос, при необходимости запомнить строку на которой стояли и перепрыгнуть на неё снова. Это как вариант.
Изображение
Ответить