Песня о зависшем Windows: Кликну, а в ответ - тишина.
Кyсочек кода, чтобы повесить на clickable столбец RxGrid, показывающий
RxQuery с опpеделенным макpосом %Order. Работать не бyдет (без модyлей), но в
качестве идеи может быть полезен.
unit vgRXutil;
interfaceuses
SysUtils, Classes, DB, DBTables, rxLookup, RxQuery;
{ TrxDBLookup }procedure RefreshRXLookup(Lookup: TrxLookupControl);
procedure RefreshRXLookupLookupSource(Lookup: TrxLookupControl);
function RxLookupValueInteger(Lookup: TrxLookupControl): Integer;
{ TRxQuery }{ Applicatable to SQL's without SELECT * syntax }{ Inserts FieldName into first position in '%Order' macro and refreshes query }procedure HandleOrderMacro(Query: TRxQuery; Field: TField);
{ Sets '%Order' macro, if defined, and refreshes query }procedure InsertOrderBy(Query: TRxQuery; NewOrder: string);
{ Converts list of order fields if defined and refreshes query }procedure UpdateOrderFields(Query: TQuery; OrderFields: TStrings);
implementationuses
vgUtils, vgDBUtl, vgBDEUtl;
{ TrxDBLookup refresh }type
TRXLookupControlHack = class(TrxLookupControl)
property DataSource;
property LookupSource;
property Value;
property EmptyValue;
end;
procedure RefreshRXLookup(Lookup: TrxLookupControl);
var
SaveField: string;
beginwith TRXLookupControlHack(Lookup) dobegin
SaveField := DataField;
DataField := '';
DataField := SaveField;
end;
end;
procedure RefreshRXLookupLookupSource(Lookup: TrxLookupControl);
var
SaveField: string;
beginwith TRXLookupControlHack(Lookup) dobegin
SaveField := LookupDisplay;
LookupDisplay := '';
LookupDisplay := SaveField;
end;
end;
function RxLookupValueInteger(Lookup: TrxLookupControl): Integer;
beginwith TRXLookupControlHack(Lookup) dotryif Value <> EmptyValue then
Result := StrToInt(Value)
else
Result := 0;
except
Result := 0;
end;
end;
procedure InsertOrderBy(Query: TRxQuery; NewOrder: string);
var
Param: TParam;
OldActive: Boolean;
OldOrder: string;
Bmk: TPKBookMark;
begin
Param := FindParam(Query.Macros, 'Order');
ifnot Assigned(Param) then
Exit;
OldOrder := Param.AsString;
if OldOrder <> NewOrder thenbegin
OldActive := Query.Active;
if OldActive then
Bmk := GetPKBookmark(Query, '');
try
Query.Close;
Param.AsString := NewOrder;
try
Query.Prepare;
except
Param.AsString := OldOrder;
end;
Query.Active := OldActive;
if OldActive then
SetToPKBookMark(Query, Bmk);
finallyif OldActive then
FreePKBookmark(Bmk);
end;
end;
end;
procedure UpdateOrderFields(Query: TQuery; OrderFields: TStrings);
var
NewOrderFields: TStrings;
procedure AddOrderField(S: string);
beginif NewOrderFields.IndexOf(S) < 0 then
NewOrderFields.Add(S);
end;
var
I, J: Integer;
Field: TField;
FieldDef: TFieldDef;
S: string;
begin
NewOrderFields := TStringList.Create;
with Query dotryfor I := 0 to OrderFields.Count - 1 dobegin
S := OrderFields[I];
Field := FindField(S);
if Assigned(Field) and (Field.FieldNo > 0) then
AddOrderField(IntToStr(Field.FieldNo))
elsetry
J := StrToInt(S);
if J < FieldDefs.Count then
AddOrderField(IntToStr(J));
exceptend;
end;
OrderFields.Assign(NewOrderFields);
finally
NewOrderFields.Free;
end;
end;
procedure HandleOrderMacro(Query: TRxQuery; Field: TField);
var
Param: TParam;
Tmp, OldOrder, NewOrder: string;
I: Integer;
C: Char;
TmpField: TField;
OrderFields: TStrings;
begin
Param := FindParam(Query.Macros, 'Order');
ifnot Assigned(Param) or Field.Calculated or Field.Lookup then
Exit;
OldOrder := Param.AsString;
I := 0;
Tmp := '';
OrderFields := TStringList.Create;
try
OrderFields.Ad(Field.FieldName);
while I < Length(OldOrder) dobegin
Inc(I);
C := OldOrder[I];
if C in FieldNameChars then
Tmp := Tmp + C;
if (not (C in FieldNameChars) or (I = Length(OldOrder))) and (Tmp <> '')
thenbegin
TmpField := Field.DataSet.FindField(Tmp);
if OrderFields.IndexOf(Tmp) < 0 then
OrderFields.Add(Tmp);
Tmp := '';
end;
end;
UpdateOrderFields(Query, OrderFields);
NewOrder := OrderFields[0];
for I := 1 to OrderFields.Count - 1 do
NewOrder := NewOrder + ', ' + OrderFields[1];
finally
OrderFields.Free;
end;
InsertOrderBy(Query, NewOrder);
end;
end.
Для отсортирования данных в DBGrid при клике на заголовок столбца можно использовать следующие шаги:
Создайте обработчик события OnColumnClick для DBGrid.
В этом обработчике проверьте, является ли кликнутый столбец тем, который вы хотите отсортировать.
Если это так, то вызовите метод SortByField для DBGrid и передайте имя поля в качестве параметра.
Вот пример кода:
procedureTForm1.DBGrid1ColumnClick(Sender:TObject;Column:TColumn);beginifColumn.Field.FieldName='YourFieldName'then// замените на имя вашего поляbeginDBGrid1.SortByField('YourFieldName');// замените на имя вашего поляend;end;
Этот код отсортирует данные в DBGrid по указанному полю при клике на его заголовок.
Также убедитесь, что поле является типом, который может быть отсортирован (например, не вычисляемым или полем поиска).
Если вам нужно отсортировать данные в порядке возрастания/убывания в зависимости от состояния столбца, можно использовать метод DBGrid1.Sort:
procedureTForm1.DBGrid1ColumnClick(Sender:TObject;Column:TColumn);beginifColumn.Field.FieldName='YourFieldName'then// замените на имя вашего поляbeginifDBGrid1.SortOrder=soAscendingthenDBGrid1.Sort:='Descending'elseDBGrid1.Sort:='';end;end;
Этот код будет переключать порядок сортировки между возрастанием и убыванием при клике на заголовок столбца.
Как заставить DBGrid сортировать данные по щелчку на заголовке столбца: в статье описано, как создать свой код для функции HandleOrderMacro, которая будет изменять макрос "%Order" при клике на заголовок столбца в DBGrid.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.