Подскажите, перешел с ADO+Gemini на IBX,а как выполнить sort

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Antoxa
Сообщения: 169
Зарегистрирован: 06 июл 2006, 10:53

Подскажите, перешел с ADO+Gemini на IBX,а как выполнить sort

Сообщение Antoxa » 01 май 2008, 16:11

У TIBDataSet, нет процедуры sort!!? Хочется кликнуть на заголовок колонки DBGrid-а и записи в DBGrid-е упорядочиваются в по значению выбранного поля!?? :shock:

dragon_art
Сообщения: 18
Зарегистрирован: 20 сен 2006, 09:18

Сообщение dragon_art » 01 май 2008, 19:25

Обычно для таких целей не используют TDBGrid. Есть хорошая альтернатива TEhGrid из библиотеки EhLIB.
А вместо TIBDataSet советую взять TFIBDataset (FIBPlus).

Antoxa
Сообщения: 169
Зарегистрирован: 06 июл 2006, 10:53

Сообщение Antoxa » 02 май 2008, 07:16

dragon_art писал(а):Обычно для таких целей не используют TDBGrid. Есть хорошая альтернатива TEhGrid из библиотеки EhLIB.
А вместо TIBDataSet советую взять TFIBDataset (FIBPlus).
TEhGrid из библиотеки EhLIB - есть, FIBPlus - пока на планирую... А как с помощью TEhGrid из библиотеки EhLIB ???

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 04 май 2008, 12:46

Вообще-то для таких целей обычно используют SQL. В смысле Order By.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 04 май 2008, 13:25

Деда, ты уже от жизни отстал, или не отошёл ещё от праздников :)
EhLib по тычкам в заголовки мало того, что сам красиво рисует стрелки направления, и даже для мультистолбцовой сортировки, дык ещё и сам формирует этот самый ORDER BY для прицепленного запроса.

Кстати, в бесплатной EhLib (не знаю, может, для новой уже не надо), для FIB нужно было потомка класса TSQLDatasetFeaturesEh переопределить, функции ApplySorting и ApplyFilter конкретно, чтобы EhLib правильно этот самый ORDER BY в правильное место втыкал.
Если нужно, могу поделиться.

zz 5
Сообщения: 32
Зарегистрирован: 02 мар 2006, 10:52

Сообщение zz 5 » 05 май 2008, 17:05

2WildSery Можно ли скрестить FIBPlus и EHLib ? У меня автоматическая сортировка средствами EHGrid с обычным датасетом работает, а FIBDataset похоже не видит :(

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 май 2008, 17:40

WildSery писал(а):Деда, ты уже от жизни отстал, или не отошёл ещё от праздников :)
EhLib по тычкам в заголовки мало того, что сам красиво рисует стрелки направления, и даже для мультистолбцовой сортировки, дык ещё и сам формирует этот самый ORDER BY для прицепленного запроса.
Аааа... При надлежащей ловкости дёргания молнии брюки превращаются, превращаются брюки... (С) И правда отстал. Мне проще и понятней самому :)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 май 2008, 17:40

Вроде я ясно выразился - да, можно. Получайте.

Модуль для использования функции фильтрации в DBGridEh + FIB
USAGE:
- подключить модуль в проект
- выставить свойство STFilter.Visible = True в компонетнте DBGridEh
- в свойстве SelectSQL компонента FIBDataSet добавить строку /*FILTER*/

Код: Выделить всё

unit uEhLibFIB;

{$I EhLib.Inc}

interface

uses DBGridEh, DbUtilsEh, pFIBDataSet, DB, SysUtils, TypInfo, Classes;

type
  TFIBDatasetFeaturesEh = class(TSQLDatasetFeaturesEh)
  public
    constructor Create; override;
    procedure ApplySorting(Sender: TObject; DataSet: TDataSet; IsReopen: Boolean); override;
    procedure ApplyFilter(Sender: TObject; DataSet: TDataSet; IsReopen: Boolean); override;
  end;

implementation

function DateValueToFIBSQLStringProc(DataSet: TDataSet; Value: Variant): String;
begin
  Result := '''' + FormatDateTime('MM"/"DD"/"YYYY', Value) + '''';
end;

constructor TFIBDatasetFeaturesEh.Create;
begin
  DateValueToSQLString := DateValueToFIBSQLStringProc;
  SQLPropName := 'SelectSQL';
end;

procedure TFIBDatasetFeaturesEh.ApplySorting(Sender: TObject; DataSet: TDataSet; IsReopen: Boolean);
var FLD  : array of TVarRec ;
    sort : array of boolean;
    I,J  : integer;
    Grid : TCustomDBGridEh;
begin
  if Sender is TCustomDBGridEh then begin
    Grid:=TCustomDBGridEh(Sender);
    J:=Grid.SortMarkedColumns.Count;
    setlength(fld,J);setlength(sort,J);
    for i:=0 to pred(j) do
      begin
       fld[i].VType:=vtAnsiString;
       string(fld[i].VString):=Grid.SortMarkedColumns[i].fieldname;
       sort[i]:=Grid.SortMarkedColumns[i].Title.SortMarker=smDownEh;
      end;
      TpFibDataset(Dataset).DoSort(fld,sort);
    end;
end;

function GetOneExpressionAsFIBWhereString(O: TSTFilterOperatorEh; v: Variant;
  FieldName: String; DataSet: TDataSet;
  DateValueToSQLStringProc: TDateValueToSQLStringProcEh; SupportsLike: Boolean): String;

  function VarValueAsFilterStr(v: Variant): String;
  var
    OldDecimalSeparator: Char;
  begin
    if VarType(v) = varDouble then
    begin
      OldDecimalSeparator := DecimalSeparator;
      DecimalSeparator := '.';
      try
        Result := FloatToStr(v);
      finally
        DecimalSeparator := OldDecimalSeparator;
      end;
    end
    else if VarType(v) = varDate then
      if @DateValueToSQLStringProc <> nil then
        Result := DateValueToSQLStringProc(DataSet, v)
      else
        Result := '''' + VarToStr(v) + ''''
    else
    if(O = foLike) then
      Result := 'rupper(''%' + VarToStr(v) + '%'')'
    else
      Result := '''' + VarToStr(v) + '''';
  end;

var
  i: Integer;
  theNOT: String;
begin
  if O in [foIn, foNotIn] then
  begin
    if O = foNotIn then
      theNOT := ' NOT'
    else
      theNOT := '';
    Result := Result + FieldName + theNOT + ' IN (';
    if VarIsArray(v) then
      for i := VarArrayLowBound(v, 1) to VarArrayHighBound(v, 1) do
        Result := Result + VarValueAsFilterStr(v[i]) + ','
    else
      Result := Result + VarValueAsFilterStr(v) + ',';
    Delete(Result, Length(Result), 1);
    Result := Result + ')';
  end else
  begin
    if(O = foLike) then
      Result := Result + ' rupper(' + FieldName + ') ' + STFilterOperatorsSQLStrMapEh[O]
    else
      Result := Result + ' ' + FieldName + ' ' + STFilterOperatorsSQLStrMapEh[O];
    if not (O in [foNull, foNotNull]) then
        Result := Result + ' ' + VarValueAsFilterStr(v);
  end;
end;

procedure SetDataSetFIBLikeProp(DataSet: TDataSet; SQLPropName: String; SQLPropValue: WideString);
var
  FPropInfo: PPropInfo;
begin
  FPropInfo := GetPropInfo(DataSet.ClassInfo, SQLPropName);
  if FPropInfo = nil then Exit;
  if FPropInfo^.PropType^.Kind = tkString then
    SetStrProp(DataSet, FPropInfo, SQLPropValue)
{$IFDEF EH_LIB_6}
  else if FPropInfo^.PropType^.Kind = tkWString then
    SetWideStrProp(DataSet, FPropInfo, SQLPropValue)
{$ELSE}
  else if FPropInfo^.PropType^.Kind = tkWString then
    SetStrProp(DataSet, FPropInfo, SQLPropValue)
{$ENDIF}
  else if FPropInfo^.PropType^.Kind = tkClass then
    if (TObject(GetOrdProp(DataSet, FPropInfo)) as TStrings) <> nil then
      (TObject(GetOrdProp(DataSet, FPropInfo)) as TStrings).Text := SQLPropValue;
end;


procedure TFIBDatasetFeaturesEh.ApplyFilter(Sender: TObject; DataSet: TDataSet; IsReopen: Boolean);
var
  s: String;
  OrderLine: Integer;
  SQL: TStrings;
  SQLPropValue: WideString;
  Grid: TDBGridEh;
  i: Integer;
begin
  Grid := TDBGridEh(Sender);
  if not IsDataSetHaveSQLLikeProp(Grid.DataSource.DataSet, SQLPropName, SQLPropValue) then
    raise Exception.Create(Grid.DataSource.DataSet.ClassName + ' is not SQL based dataset');
  SQL := TStringList.Create;
  SQL.Text := SQLPropValue;
  try
    OrderLine := -1;
    for i := 0 to SQL.Count - 1 do
      if UpperCase(Copy(SQL[i], 1, Length(SQLFilterMarker))) = UpperCase(SQLFilterMarker) then
      begin
        OrderLine := i;
        Break;
      end;
    s := GetExpressionAsFilterString(TDBGridEh(Sender), GetOneExpressionAsFIBWhereString, DateValueToFIBSQLStringProc, False, True);
    if s = '' then
      s := '1=1';
    if OrderLine = -1 then
      Exit;
    Grid.DataSource.DataSet.DisableControls;
    try
      if Grid.DataSource.DataSet.Active then
        Grid.DataSource.DataSet.Close;
      SQL.Strings[OrderLine] := SQLFilterMarker + ' AND (' + s + ')';
      SetDataSetFIBLikeProp(Grid.DataSource.DataSet, SQLPropName, SQL.Text);
      if IsReopen then
        Grid.DataSource.DataSet.Open;
    finally
      Grid.DataSource.DataSet.EnableControls;
    end;
  finally
    SQL.Free;
  end;
end;

initialization
  RegisterDatasetFeaturesEh(TFIBDatasetFeaturesEh, TpFIBDataSet);

end.
Последний раз редактировалось WildSery 06 май 2008, 11:35, всего редактировалось 1 раз.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 05 май 2008, 17:45

Merlin писал(а):Мне проще и понятней самому :)
Там кстати, специально для тебя, можно чтобы только стрелки красиво рисовал, а остальное "сделай сам" ;)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 май 2008, 18:30

WildSery писал(а):
Merlin писал(а):Мне проще и понятней самому :)
Там кстати, специально для тебя, можно чтобы только стрелки красиво рисовал, а остальное "сделай сам" ;)
Мы на InfoPower работаем, уже лет 10 на всех честно покупаемых версиях. Он тоже что хош рисует. Через TImageList и события OnTitleButtonClick и OnCalcTitleImage.

Esperito
Сообщения: 10
Зарегистрирован: 09 авг 2007, 19:23

Сообщение Esperito » 05 май 2008, 20:32

WildSery, я извиняюсь, но после unit нужно добавить {$I EhLib.Inc}, чтобы сработал {$IFDEF EH_LIB_6}.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 06 май 2008, 09:23

WildSery писал(а): , а остальное "сделай сам" ;)
Взял я версию EhLib 4.1, но при локальной фильтрации по полю Integer при задании в фильтре отрицательных значений фильтр работает некорректно, пока не разобрался почему :(
С подобной проблемой не сталкивался?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 06 май 2008, 11:39

Esperito писал(а):WildSery, я извиняюсь, но после unit нужно добавить {$I EhLib.Inc}, чтобы сработал {$IFDEF EH_LIB_6}.
Извиняться не нужно, наоборот, спасибо за поправку.
Я кусок вырезал, потому такую деталь просто упустил из виду.
Поправил.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 06 май 2008, 14:41

stix-s писал(а):
WildSery писал(а): , а остальное "сделай сам" ;)
Взял я версию EhLib 4.1, но при локальной фильтрации по полю Integer при задании в фильтре отрицательных значений фильтр работает некорректно, пока не разобрался почему :(
С подобной проблемой не сталкивался?
Хм, странно, с EhLib все в норме, глюк где-то в глубинах FIB+

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 06 май 2008, 14:49

Поди фильтр задал типа от -50 до -70.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 06 май 2008, 15:31

Merlin писал(а):Поди фильтр задал типа от -50 до -70.
нет, проще - "<-1"

dragon_art
Сообщения: 18
Зарегистрирован: 20 сен 2006, 09:18

Сообщение dragon_art » 06 май 2008, 16:37

WildSery писал(а):...

Код: Выделить всё

unit uEhLibFIB;

{$I EhLib.Inc}
...
.
:) Знакомый код :)
Помница я его когда-то выкладывал[/b]

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 06 май 2008, 17:02

dragon_art писал(а):Помница я его когда-то выкладывал
Источник мне неизвестен, к сожалению, а то бы дал просто ссылку.
Пользоваться - пользуемся.

dragon_art
Сообщения: 18
Зарегистрирован: 20 сен 2006, 09:18

Сообщение dragon_art » 07 май 2008, 07:09

тема:
DBgridEh and Server filtering
от 08.06.2006 http://forum.ibase.ru/phpBB2/viewtopic. ... highlight=

тогда я не обращал внимания на строки:

Код: Выделить всё

{      Copyright (c) 2005 by Roman V. Babenko           }
{ e-mail: romb@interbase-world.com                      } 
просто пользовался готовым продуктом :oops:

Antoxa
Сообщения: 169
Зарегистрирован: 06 июл 2006, 10:53

Сообщение Antoxa » 09 май 2008, 13:10

WildSery писал(а):Деда, ты уже от жизни отстал, или не отошёл ещё от праздников :)
EhLib по тычкам в заголовки мало того, что сам красиво рисует стрелки направления, и даже для мультистолбцовой сортировки, дык ещё и сам формирует этот самый ORDER BY для прицепленного запроса.
А как же его заставить сформировать этот самый ORDER BY ???

Ответить