powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / filter+lookup вместе живут?
23 сообщений из 23, страница 1 из 1
filter+lookup вместе живут?
    #35629488
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможна ли обычная фильтрация (через filter) по lookup-полям?
TTable, похоже, отрицает такую возможность:
авторProject Project1.exe raised exception class EDatabaseError with message 'Field 'cex' cannot be used in a filter expression'. Process stopped. Use Step or Run to continue.TOracleDataset/DOA гавкать не гавкает, но положительного результата не выдает - выдаёт пустой набор данных.

Фильтровать по совету автор"How can I filter on a lookup field in a dataset?
Answer : You cannot use the lookup field's name in the filter string, but you can use an OnFilterRecord" можно, но как-то муторно - весьма затруднительно в сопровождении, нет универсальности.

Потестировал в очередной раз свой любимый ДОА, сделал "на коленке" такой пилотный вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
 function  TOracleDataSet.ApplyFilterTo(Data: PRecordData): Boolean;
 var  OldFFilterBuffer: Pointer;
    SaveState: TDataSetState;
 begin 
  OldFFilterBuffer := FFilterBuffer;
  SaveState := SetTempState(dsFilter);
   try 
    Result := True;
    FFilterBuffer := Data;
    GetCalcFields(PChar(FFilterBuffer));    // добавленная строка  - вызов механизма вычисления Calc и lookup полей 
     if  Assigned(OnFilterRecord)  then  OnFilterRecord(Self, Result);
     if  Result  then  Result := ApplyFilter;
   finally 
    RestoreState(SaveState);
    FFilterBuffer := OldFFilterBuffer;
   end ;
 end ;
- работает, причем так же, как и с обычными полями - операции = <> и т.д., включая частичное совпадение и проч.
Конечно, для GetCalcFields(PChar(FFilterBuffer)) еще желательно проверять, есть ли необходимость в вызове этого метода (наличие "lookup field in списке полей в фильтре").
Ясно, что фильтрация будет медленнее, чем по обычным полям.
Но вряд ли медленне, чем с использованием OnFilterRecord.
----------------------------------------------------
Хочется услышать мнение заинтересованных коллег. Стоит ли ковырять в эту сторону?
Писать письма в AllRound уже надоело, всё бестолку - похоже, этот продукт им перестал приносить реальные деньги уже давненько.
----------------------------------------------------
Главная цель разработки: универсальный механизма локальной фильтрации без разделения полей на обычные, калькулируемый и lookup - т.к. юзеру в конце концов пофиг, какие они на самом деле.
----------------------------------------------------
Прошу в данном топике не предлагать осуществление фильтрации средствами БД - как это делается, я знаю вполне прилично - все граничные условия на сервере задаём.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35629505
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx> Но вряд ли медленне, чем с использованием OnFilterRecord.

Когда-то давно когда у меня тоже всплыла подобная мысль,
я ответил себе, что все это мелочи, не стоящие внимания,
поскольку фильтруются в абсолютном большинстве случаев
достаточно небольшое количество данных и разница между
обработчиком OnFilterRecord и стандартной фильтрацией
будет минимальна. И небольшой тест это подтвердил.

andreymx> Хочется услышать мнение заинтересованных коллег.
andreymx> Стоит ли ковырять в эту сторону?

На мой взгляд - скорее нет, если это разовая задача.
Если же это задача достаточно часто встречающаяся (и иные надстройки
Вы уже делали) и хочется какой-то универсальности - то стоит.

andreymx> универсальный механизма локальной фильтрации без разделения полей на обычные,
andreymx> калькулируемый и lookup - т.к. юзеру в конце концов пофиг, какие они на самом деле.

На мой взгляд, проще и правильнее реализовать в механизме/компоненте фильтрации
(GUI или где-то рядом) - т.е. когда пользователь выбрал лукап-значение, добавлять в
выражение фильтра условие строку поле_кода_лукапа + операция + значение_кода_лукапа.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35629689
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустамandreymxуниверсальный механизма локальной фильтрации без разделения полей на обычные, калькулируемый и lookup - т.к. юзеру в конце концов пофиг, какие они на самом деле.
На мой взгляд, проще и правильнее реализовать в механизме/компоненте фильтрации
(GUI или где-то рядом) - т.е. когда пользователь выбрал лукап-значение, добавлять в
выражение фильтра условие строку поле_кода_лукапа + операция + значение_кода_лукапа.
Это реализовано и уже давно, но наши пользователи хотят полной поддержки - скажем, фильтр по подстроке.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35630975
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxскажем, фильтр по подстроке.
Ясно. В таком случае делать из лукапов "настоящие"
поля - например, их выборкой join-ом со справочником.
Впрочем, это, конечно, скорее воркэраунд.

P.S. Да, как известно, я не поклонник лукап-полей.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35631092
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxХочется услышать мнение заинтересованных коллег. Стоит ли ковырять в эту сторону?Это тебе виднее - надо не надо. Но скорее всего будет работать.
andreymxПисать письма в AllRound уже надоело, всё бестолку - похоже, этот продукт им перестал приносить реальные деньги уже давненько.
Я об этом говорил еще 2 года назад. Обороты от PSD в десятки раз выше, чем от DOA.
andreymxГлавная цель разработки: универсальный механизма локальной фильтрации без разделения полей на обычные
У тебя все получится :)
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35631380
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry ArefievДмиорий, а как в ANYDAC уживаются filter+lookup?
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35631632
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxа как в ANYDAC уживаются filter+lookup?
Явно - так же как и в DOA, т.е. никак.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35631744
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefievandreymxа как в ANYDAC уживаются filter+lookup?
Явно - так же как и в DOA, т.е. никак.А на будущее?
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35631993
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx
Ну что бы и нет ... Только сначала подумаю на введением альтернативы lookup полю.
Они ограниченные и не самые эффективные.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633058
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefievandreymxсначала подумаю на введением альтернативы lookup полю.
Они ограниченные и не самые эффективные.Ну да... сильно зависит от количества строк lookup-dataset-а. Если он не проиндексирован по ключевым полям в мемори
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633075
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxНу да... сильно зависит от количества строк lookup-dataset-а. Если он не проиндексирован по ключевым полям в мемори
Ну там больше аспектов над которыми стоит подумать ...
1) Если lookup2 поля сделать fkInternalCalc, то их можно будет вычислять только раз - при
первом чтении значения lookup2 поля. Далее вычисленное значение сохраняется в буфере
записи вместе с остальными полями. Существенно ускорит навигацию (гуляние вверх, вниз,
влево, вправо по датасету с кучей lookup полей).
2) Если lookup2 поле уметь привязывать к полю c.Name в следующем запросе:
Код: plaintext
1.
select o.*, c.Name
from Orders o left join Customers c on o.CustomerId = c.Id
то проблем с загрузкой клиента вычислением lookup2 полей вообще нет. Но за счет сервера.
Это может ускорить lookup2 поля, где lookup датасет имеет мноооого записей.
3) LookupResultField - одно поле ? Не густо ... Неплохо было бы ввести форматную строку,
например:
Код: plaintext
[ {code} ]  {Name} ,  {Address} 
4) Lookup датасет можно разобрать на части - SQLFrom, SQLWhere, и т.д. и описывать это все
в Lookup source или типа того. Это позволит динамически строить необходимые запросы к
справочнику. Что в свою очередь позволит:
- иметь режим вычисления Lookup2 поля прямым SELECT ... FROM ... WHERE <PK> = :Val;
- приделать развитой LOV к Lookup Source;
- реализовать QBF, который сможет строить результирующий запрос и по Lookup2 полям

ну и т.д.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633129
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Главное, чего не хватает нам в lookup/picklist - это возможность создания зависимых выпадающих списков.
Т.е. главная рашифровка, предположим, по pred+cex; а в строке грида при уже введенном pred чтобы выпадали только строки с таким pred.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633138
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxГлавное, чего не хватает нам в lookup/picklist - это возможность создания зависимых выпадающих списков.
Это делается MasterSource в (4) случае. Собственно то, о чем я тут говорю, было реализовано
лет 10 назад для БДЕ - теперь думаю затащить в AnyDAC ...
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633246
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, это очень неоднозначная проблема - стоит ли для каждой строчки дёргать БД.
В общем случае - я против.
Аргументы всё те же: нагрузка сети, БД, +возможно, DbLink, + возможность получения несогласованных данных...
Хотя в некоторых случаях вполне ускорит работу.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #35633324
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxДа, это очень неоднозначная проблема - стоит ли для каждой строчки дёргать БД.
Да, неоднозначная - это точно. Например, есть справочник материалов (что-то в районе
200,000 записей). Есть строки заказа (штук 5-10 записей).

0) При стандартном lookup поле - все 200,000 засосутся в память. Что будет задержкой в несколько
секунд, съеденными 50-70Мб памяти и хорошей нагрузкой на сеть, когда 100 чел. с утра дружно
начинают работать.

Варианты оптимизации:
1) каждая станция дернет свои 10 SELECT WHERE PK=:Val. Вобщем-то копейки ... Но будет
кошмар, если надо выбрать X * 100,000 записей.
2) грузится не весь справочник материалов, а его подмножество / раздел. Предположу, что
работает плохо, так как могут быть в одном заказе и плоскогубцы и валенки ...
3) выборка основного набора данных идет rowset'ами по X записей (в AnyDAC - 50 по умолчанию).
Можно после выборки очередного rowset собрать все RefID и выполнить SELECT WHERE PK in (id1,
..., idN).
4) выбирать основной набор данных уже сдойженный со справочниками. Сервер достаточно
быстро отработает такой запрос. Но будет ужастик для программиста, если 50 справочных полей.

Кстати, а как там Forms реализует LOV ??
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
filter+lookup вместе живут?
    #37830984
NeoDBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Direct Oracle Access 4.1.1

я сделал так

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function TOracleDataSet.ApplyFilterTo(Data: PRecordData): Boolean;
var OldFFilterBuffer: Pointer;
    SaveState: TDataSetState;
begin
  OldFFilterBuffer := FFilterBuffer;
  SaveState := SetTempState(dsFilter);
  try
    Result := True;
    FFilterBuffer := Data;
    GetCalcFields(TRecordBuffer(FFilterBuffer)); // 8.06.2012 поиск по lookup
    if Assigned(OnFilterRecord) then OnFilterRecord(Self, Result);
    if Result then Result := ApplyFilter;
  finally
    RestoreState(SaveState);
    FFilterBuffer := OldFFilterBuffer;
  end;
end;
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
filter+lookup вместе живут?
    #39534300
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxпредположим, по pred+cex; а в строке грида при уже введенном pred чтобы выпадали только строки с таким pred.Прошу прощения за некрофилию. Данная задача была решена?
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39534487
LSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустамandreymxскажем, фильтр по подстроке.
Ясно. В таком случае делать из лукапов "настоящие"
поля - например, их выборкой join-ом со справочником.
Впрочем, это, конечно, скорее воркэраунд.

P.S. Да, как известно, я не поклонник лукап-полей.+500. Я делаю обычные поля. А для полноценной имитации лукап-поведения в гриде, возвращаю из лукап-формы в датасет два значения: ключ и текст (благо, что файрДАК умеет "редактировать" нередактируемые поля). Если запись запостить, то текст обновится уже с сервера. Если edit отменить, то вернется старое значение текста.
И лукап-форма при этом полноценная. Есть поиск, фильтрация, создание новой записи и многое другое, чего заведома нет в лукап-комбобоксе.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39534639
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LSV+500. Я делаю обычные поляЗадача: в ячейку грида воткнуть комбобокс с предопределенным выпадающим списком. Раньше это было сделано через позиционирование лукапкомбобокса на ячейку грида. Думал убрать комбобокс и сделать лукап поле. Наткнулся на невозможность отфильтровать запись
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39534837
LSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_LSV+500. Я делаю обычные поляЗадача: в ячейку грида воткнуть комбобокс с предопределенным выпадающим списком. Раньше это было сделано через позиционирование лукапкомбобокса на ячейку грида. Думал убрать комбобокс и сделать лукап поле. Наткнулся на невозможность отфильтровать записьИменно поэтому я сделал у себя обычное поле.
Потому-то решить проблему фильтрации лукапа практически невозможно.
У обычного поля к конце кнопочка вызова лукап-формы. Чуть менее удобно, чем комбо, но зато имеет много преимуществ.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39534865
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Задача: в ячейку грида воткнуть комбобокс с предопределенным выпадающим списком.

Для этого не нужно lookup поле, просто забей свой предопределённый список значений Grid-y
в TColumn.PickList.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39534912
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_LSV+500. Я делаю обычные поляЗадача: в ячейку грида воткнуть комбобокс с предопределенным выпадающим списком. Раньше это было сделано через позиционирование лукапкомбобокса на ячейку грида. Думал убрать комбобокс и сделать лукап поле. Наткнулся на невозможность отфильтровать запись
Я когда-то возился с сей "проблемой", решил заменой отказом лукап-полей в режиме отображения на лукап поля в режиме редактирования.

Каждый датасет готовлю специально (я использовал комбинацию из особого фрейма с гридом и датасетом, несущественно).

Предположим, отображаю список товаров Goods, показываю наименование товара и наименование типа товара из таблики KindOfGoods:
Код: sql
1.
2.
select g.id g_id, g.name g_name, kg.name kg_name from Goods g
   join KindOfGoods kg on g.id = kg.goods_id


Все отлично "фильтруется и сортируется". Нужно как-то редактировать поле kg_name.

К описанию добавляю список (в данном случае из одного элемента)
псевдо-лукап полей:

Код: pascal
1.
  lkp := DataSetStruct.AddLookupField('kg_name', 'goods_id'); // Имя отображаемого и редактируемого полей.


И для этого поля указываю все необходимые данные для реализации его "редактирования":
Код: pascal
1.
2.
3.
4.
  lkp.SelectSQL := 'Select kg.id kg_id, name kg_name, full_name kg_full_name kg_full_name from KindOfGoods'; // Откуда брать лукап -
 данные
  lkp.AddViewField('kg_name'); // Поля для отображения в списке
  lkp.AddViewField('kg_full_name');


Все, все необходимые данные для создания лукап-комбобокса есть. В момент редактирования в ячейке грида создается контрол (использовал из набора EhKib), инициализируется и отображается. После завершения редактирования выполняется апдейт поля kg_id текущей записи таблички Goods, контрол редактирования уничтожается, выполняется Refresh текущей записи грида. Всё.

Я уже не помню подробностей, но идея, надеюсь, ясна. Реальной работы ничуть не больше, чем при возне с настоящими лукап-полями, зато и преимущества налицо.
...
Рейтинг: 0 / 0
filter+lookup вместе живут?
    #39535437
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, для потомков. dblcbBuilds - TDBLookupComboBox, dbgAssemblyList - TDBGrid

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
type
  THackDBGrid = class(TDBGrid);

procedure TfrmAssembly.FormCreate(Sender: TObject);
begin
  dblcbBuilds.Parent := dbgAssemblyList;
end;

procedure TfrmAssembly.dbgAssemblyListCellClick(Column: TColumn);
var
  LGrid: THackDBGrid;
  LCurCell: TPoint;
begin
  if Column.Field.FieldName = CfnVersion then begin
    LGrid := THackDBGrid(dbgAssemblyList);
    LCurCell.X := LGrid.Col;
    LCurCell.Y := LGrid.Row;
    if (LCurCell.X = FCurCell.X) and (LCurCell.Y = FCurCell.Y) then
      ShowBuildList
    else begin
      HideBuildList;
      FCurCell := LCurCell;
    end;
  end else
    HideBuildList;
end;

procedure TfrmAssembly.ShowBuildList;
var
  LRect: TRect;
  LGridDS: TDataSet;
  LLookupDS: TIBDataSet;
begin
  LRect := THackDBGrid(dbgAssemblyList).CellRect(FCurCell.X, FCurCell.Y);
  dblcbBuilds.BoundsRect := LRect;

  LGridDS := dbgAssemblyList.DataSource.DataSet;
  LLookupDS := dblcbBuilds.ListSource.DataSet as TIBDataSet;

  LLookupDS.Close;
  LLookupDS.ParamByName(CfnModID).AsVariant := LGridDS.FieldByName(CfnModID).AsVariant;
  LLookupDS.Open;
  LLookupDS.FetchAll;

  dblcbBuilds.Visible := True;
  dblcbBuilds.KeyValue := LGridDS.FieldByName(CfnModBldID).AsVariant;
end;

procedure TfrmAssembly.HideBuildList;
begin
  dblcbBuilds.ListSource.DataSet.Active := False;
  dblcbBuilds.Visible := False;
  FCurCell.X := -1;
  FCurCell.Y := -1;
end;

...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / filter+lookup вместе живут?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]