Форум: "Базы";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
ВнизEhLib + сортировка Найти похожие ветки
← →
JohnS (2004-10-11 14:23) [0]Hello All
Я в
DbGridEn поставил AutoSortMarket:=true
DbGridEn.Columns[i].Title.TitleButton:=true
А сортирует почемуто только по возрастанию, значок сортировки в заголовке столбца не рисует :-(
Что еще надо поставить ??
← →
Johnmen © (2004-10-11 14:27) [1]Ничего ставить не надо. Надо сортировать.
← →
JohnS (2004-10-11 15:09) [2]
> Ничего ставить не надо. Надо сортировать.
сортирует почемуто только по возрастанию, значок сортировки в заголовке столбца не рисует :-(
← →
Johnmen © (2004-10-11 15:16) [3]
> сортирует почемуто только по возрастанию
Кто сортирует ?
← →
KSergey © (2004-10-11 15:22) [4]Вы не указали этот самый значек! Только разрешили сортировку пользователем. А мож и еще чего пропускаю....
Чтобы программно отсортировать - надо еще колонке (колонкам) проставить Title.SortMarker и Title.SortIndex
Вот пример кода, заставляющий грид отсортироваться по выделенным колонкам. Код в наследнике этого грида, так что делайте на это поправку{******************************************************************************
* Сортировать по выделенным столбцам
* Собственно сортировки не происходит, просто проставляет маркеры сортировки
* Вход:
* AForward =TRUE - сортировать по возрастанию,
* =FALSE - сортировать по убыванию
* IsSortEmptySel =TRUE - сортировать при пустом выделении,
* =FALSE - не сортировать при пустом выделении
******************************************************************************}
procedure TdoDBGrid.SortBySelectedCols(const AForward: Boolean{=TRUE}; const IsSortEmptySel: Boolean{=FALSE});
var
n,i: Integer;
NewSortMark: TSortMarkerEh;
begin
if NOT IsSortEmptySel AND (Selection.Columns.Count < 1) then Exit;
// сначала скинуть у всех столбцов признак сортировки
ClearSortMarker;
// теперь установить у выделенных
if AForward then NewSortMark := smDownEh
else NewSortMark := smUpEh;
with Selection.Columns do
begin
i := 1;
for n := 0 to Count-1 do
begin
if TestSortFldType(Items[n].Field) then
begin
Items[n].Title.SortIndex := i;
Items[n].Title.SortMarker := NewSortMark;
if NOT (dghMultiSortMarking in OptionsEh) then // если по многим столбцам нельзя сортровать -
Break; // то на первом подходящем и прекратить
Inc(i);
end;
end;
end; // with Selected.Columns
ApplayMarkedSorting; // свиснуть гриду, что не хило бы посортировать, если сумеет, конечно
end;
{******************************************************************************
* Заставить грид сортироваться согласно отмеченным столбцам сортировки
* Это небольшая надстройка над DoSortMarkingChanged, но устанавливается
* флаг, который проверяется в этой ф-ции
******************************************************************************}
procedure TdoDBGrid.ApplayMarkedSorting;
var
OptionsAhSav: TDBGridEhOptions;
begin
OptionsAhSav := OptionsEh;
try
OptionsEh := OptionsEh + [dghAutoSortMarking];
DoSortMarkingChanged; // гридовский обработчик сортировки
finally
OptionsEh := OptionsAhSav;
end;
end;
← →
JohnS (2004-10-11 15:52) [5]
> KSergey
Что то сложно . Кстати я кажется понял . Если в запросе написать
Select * from Table , то все ОК. Если написать Select * from Table Order by Field1 DESC , то начинаются глюки при сортировке .
← →
jack128 © (2004-10-11 15:53) [6]KSergey © (11.10.04 15:22) [4]
> DoSortMarkingChanged
> dghAutoSortMarking
Ура!!! Я велосипед изобрел!!! :-)) .. Или :-((
← →
KSergey © (2004-10-11 15:57) [7]> [6] jack128 © (11.10.04 15:53)
Не понял.. Вы себе или мне? ;)
← →
KSergey © (2004-10-11 15:58) [8]> [5] JohnS (11.10.04 15:52)
Сортировка какая? Серверная или клиентская? Движек какой - ADO?
← →
jack128 © (2004-10-11 15:59) [9]JohnS (11.10.04 15:52) [5]
Хе, нормальный запрос.. Только эти запросмы нужно же генерить автоматически. Вот как я это делаю..// Вставляет в запрос сортировку по полям Fields. Если Fields[i].Object = nil,
// то сортировка по убыванию, иначе по возростанию
function GenerateOrderSQL(SQL, Fields: TStrings; ReplaceExists: boolean): boolean;
var
s: string;
OrderByClauseStart: Integer;
i: Integer;
OrderByClause: string;
begin
Result := False;
s := SQL.Text;
if s = "" then Exit;
OrderByClauseStart := Pos("ORDER BY", UpperCase(s));
if (OrderByClauseStart >= 1) and not ReplaceExists then Exit;
if OrderByClauseStart >= 1 then
s := copy(s, 1, OrderByClauseStart + Length("ORDER BY") - 1) + " "
else
s := s + " ORDER BY ";
OrderByClause := "";
for i := 0 to Fields.Count - 1 do
begin
OrderByClause := OrderByClause + Fields[i];
if Fields.Objects[i] = nil then OrderByClause := OrderByClause + " DESC, "
else OrderByClause := OrderByClause + ", ";
end;
Delete(OrderByClause, Length(OrderByClause) - 1, 2);
SQL.Text := s + OrderByClause;
end;
// И вот где это вызывается.. Правда сортировка сразу по нескольким полям запрещена. Но тут те нужно совместить мой код и код KSergey"яprocedure TBaseDBElementFrame.GridTitleBtnClick(Sender: TObject;
ACol: Integer; Column: TColumnEh);
var
Id: Integer;
IdField: TField;
Fields: TStringList;
FieldName: string;
begin
if not IbDataSet.Active then Exit;
FieldName := Column.FieldName;
if not AllowFieldOrder(FieldName) then Exit;
IdField := IbDataSet.FindField("ID");
if Assigned(IdField) then Id := IdField.AsInteger;
IbDataSet.DisableControls;
try
IbDataSet.Close;
Fields := TStringList.Create;
try
if Column.Title.SortMarker = smUpEh then
Column.Title.SortMarker := smDownEh
else
Column.Title.SortMarker := smUpEh;
Fields.AddObject(FieldName, TObject(Column.Title.SortMarker = smUpEh));
GenerateOrderSQL(IbDataSet.SelectSQL, Fields, True);
finally
Fields.Free;
end;
IbDataSet.Open;
if Assigned(IdField) then
IbDataSet.Locate("ID", Id, []);
finally
IbDataSet.EnableControls;
end;
end;
KSergey © (11.10.04 15:57) [7]
себе естественно.. См мой код в этом посте.. Обработчик OnTitleClick..
← →
KSergey © (2004-10-11 16:01) [10]> [9] jack128 © (11.10.04 15:59)
Ой.... ;)
Гляньте в каталог DataService после распаковки. Там уже все сделано ;)
← →
jack128 © (2004-10-11 16:05) [11]KSergey © (11.10.04 15:58) [8]
Что то я попыытался их использовать, но у мя нечего не получилось.. Там через ртти ищется свойство SQL, которое модифицируется, а так как в IBDataSet такого свойства нет, то никакой сортировки и нет.. А IBQuery использовать, да и изменять исходники не охота.. Ктому же уже своя реализация написана..
← →
Zacho © (2004-10-11 16:12) [12]jack128 © (11.10.04 16:05) [11]
Странно... А у меня всё получилось, и без копаний в исходниках, и что такое RTTI я вАБще не знаю :)))
На самом деле, там есть только один недочёт: чтобы это работало, в запросе нельзя использовать *
← →
jack128 © (2004-10-11 16:20) [13]Zacho © (11.10.04 16:12) [12]
Это в какой версии EhLib?? в третьей вообще эти фичи используются, только для TIbQuery
unit EhLibIBX;
{$I EhLib.Inc}
interface
uses
DbUtilsEh, IBQuery;
implementation
initialization
RegisterDatasetFeaturesEh(TSQLDatasetFeaturesEh, TIBQuery);
end.
и даже если написать RegisterDatasetFeaturesEh(TSQLDatasetFeaturesEh, TIbDataset); то ИМХО не будет работать по указаной выше причине..
← →
Zacho © (2004-10-11 16:26) [14]jack128 © (11.10.04 16:20) [13]
Точно сейчас cказать не могу, примерно - в версии 3.какая_то_там, но скорей всего и в более ранних, ибо TIBQuery я не использую принципиально :), а сортировкой в TDBGridEh пользуюсь давно.
← →
KSergey © (2004-10-11 17:26) [15]> [13] jack128 © (11.10.04 16:20)
Ну так и дописать свой механизм для используемого случая по аналогии ;) И радоваться ;)
← →
jack128 © (2004-10-11 17:30) [16]KSergey © (11.10.04 17:26) [15]
я ж на велосипедах специализируюсь -)) Будет время и желание - переделаю под стандарт EhLib. Хотя вот Zacho говорит, что него и так работает..
← →
JohnS (2004-10-12 07:51) [17]> KSergey Запрос клиенский , движок ADO , компонент ADoDataSet.
> jack128 Я вроде понял так, что сортируется не готовый запрос , а создается новый ?
← →
KSergey © (2004-10-12 08:11) [18]> [17] JohnS (12.10.04 07:51)
> > KSergey Запрос клиенский , движок ADO , компонент ADoDataSet.
Я вроде понял так, что сортируется не готовый запрос , а создается новый ?
Тогда у вас есть выбор. ADO умеет сортировать локально. Только это не касается LookUp и Calculated полей. Вернее, для LookUp - можно только по ID сортировать, ну а про Calculated ADO и вовсе не в курсе, понятное дело.
Единственное, в EhLib на сей счет есть. по-моему, ошибочка. Я лично переделал для себя ф-цию SortDataInADODataSet из модуля EhLibADO (это для локальной сортировки; где для серверной (т.е. с переформированием SQL-запроса - что-то я уже забыл; а может для ADO и вовсе нет, но мерещится, что видел).
Если кому интересно.{KSM} - отмечены добавленные или поправленные мною строки
В случае LookUp полей ищется в выборке поле с таким же написнованием, как указано в поле для отображения LookUp поля (для возможности сортировки по видимому пользователем значению; если не наудено - сортируем фактически по ID)
unit EhLibADO;
....
procedure SortDataInADODataSet(Grid: TCustomDBGridEh; DataSet: TCustomADODataSet);
var
s: String;
i: Integer;
{KSM} Fld: TField;
begin
s := "";
for i := 0 to Grid.SortMarkedColumns.Count - 1 do
begin
{KSM} //s := s + Grid.SortMarkedColumns[i].FieldName;
{KSM} Fld := Grid.SortMarkedColumns[i].Field;
{KSM} if Assigned(Fld) then
{KSM} begin
{KSM} case Fld.FieldKind of
{KSM} fkData: s := s + Fld.FieldName;
{KSM} fkLookup: // в случае lookup поля сортировать или по полю, которое отображается и есть в имеющемся DataSet,
{KSM} begin // или по полю ID
{KSM} if DataSet.FindField(Fld.LookupResultField) = nil then
{KSM} s := s + Fld.KeyFields
{KSM} else
{KSM} s := s + Fld.LookupResultField;
{KSM} end;
{KSM} else
{KSM} continue;
{KSM} end;
if Grid.SortMarkedColumns[i].Title.SortMarker = smUpEh
then s := s + " DESC, "
else s := s + ", ";
{KSM} end;
end;
DataSet.Sort := Copy(s, 1, Length(s) - 2);
end;
← →
JohnS (2004-10-12 10:50) [19]Так оказывается вобще все просто :
Если я пишу например в запросе "select * from AptChange order by date
То при сортировке кликанием мыши в
procedure ApplySortingForSQLBasedDataSet (unit DbUtilsEh)
Формируется такая фигня !!!
"select * from AptChange order by cdate"#$D#$A"ORDER BY 7"#$D#$A
← →
KSergey © (2004-10-12 11:52) [20]> [19] JohnS (12.10.04 10:50)
а) у вас включена не локальная сортировка
б) вы пользуетесь не ADO-ориентированной сортировкой.
Хотя, про "фигня" - я не понял: это в смысле хорошо или плохо?
← →
JohnS (2004-10-12 12:52) [21]
> Хотя, про "фигня" - я не понял: это в смысле хорошо или
> плохо?
Это плохо :-)
А дело было вот в чем, я просто добавил в
procedure ApplySortingForSQLBasedDataSet(Grid: TCustomDBGridEh; DataSet: TDataSet;
UseFieldName: Boolean; IsReopen: Boolean; SQLPropName: String);
...........
if Pos("order by",LowerCase(SQLPropValue))>0 then
...............
SQl.Text:= Copy(SQLPropValue,1,Pos("order by",LowerCase(SQLPropValue))-1)
else
SQL.Text := SQLPropValue;
..........
То есть если запрос ИЗНАЧАЛЬНО отсортирован , то вырезать Order by .
← →
Pentium133 © (2004-10-12 15:06) [22]где то у меня валяется модуль EhLibFIB, но там это все реализованно для FIB
-------------
EhLib v3.4
Register object that sort and filter data in TpFIBDataset
Copyright (c) 2002 by Konstantin Beliaev
-------------
Add this unit to "uses" clause of any unit of your project to allow TDBGridEh to sort data in
TpFIBDataset automatically after sorting markers
will be changed.
TFIBDatasetFeaturesEh will sort data locally
using DoSort procedure of TpFIBDataset
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.037 c