Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
14-1098755050
Думкин
2004-10-26 05:44
2004.11.14
С днем рождения! 26 октября.


6-1091738810
MeMO
2004-08-06 00:46
2004.11.14
Вопрос по статье "Мониторинг сетей в Delphi"


14-1098879796
Шишкин Илья
2004-10-27 16:23
2004.11.14
Аналог IntToStr в Turbo Pascal


3-1097979108
Andrew Tsib
2004-10-17 06:11
2004.11.14
Как обр. ошибку ввода пол-ем двух один-х значен индексного поля


6-1094133088
Евгений30048
2004-09-02 17:51
2004.11.14
Как закачать на сервер БИНАРНЫЙ файл по http?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский