Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Вниз

DataSet.Locate не дружит с Filter, а надо - как быть   Найти похожие ветки 

 
Silver... ©   (2006-07-15 21:55) [0]

Очень надо чтоб

DataSet.Locate искал только в записях отвечающих условию DataSet.Filter

например если DataSet содержит

ID  Name
---------
1   Name1
2   Name2
3   Name3
4   Name1
5   Name3

после фильтрации остается
ID  Name
---------
4   Name1
5   Name3

DataSet.Locate("Name", "Name1", [loCaseInsensitive, loPartialKey])
находит ID = 1 а надо ID = 4
что делать?


 
Johnmen ©   (2006-07-15 22:54) [1]

Самому проходить по набору данных в поисках нужной записи...
Кстати, скорость по сравнению с Локейт практически не измениться...


 
Reindeer Moss Eater ©   (2006-07-16 12:08) [2]

Используй TTable + Filter тогда все буде так, как ты хочешь.
В этом случае связка будет эквивалентна TQuery + условие фильтра в секции where. (Фильтрация на сервере)

TQuery + Filter = фильтрация всегда на клиенте


 
Silver... ©   (2006-07-20 01:56) [3]

Есть:
 Таблица "A" - например Рабочие(IDRab, Name, Ot, Do)
                    Ot/Do - время его "видимости" (когда доступен)
 Таблица "B" - например Заказы(IDZak, IDRab, Ot, Do)
 Таблица "C" - например ЗакРаб(IDZakRab, IDZak, IDRab, N)

Ситуация такая:
 - Открывается заказ с лимитом по времени выполнения (От - До) в LookupName выбираем имя
    и присваиваем [N] -- вот тут надо чтоб в Lookup были только те Рабочие которые подходят
    Заказу[От - До]. Использую фильтрацию и всё работает на ура

 - WHERE - первое что пробовал - не подходит по одной причине переодически надо смотреть на
    предыдущие записи, в этом случае в AfterScroll делаю фильтрацию (DataSetт.Close/Open
    работает неприятно медленно с Filter работает быстрее - но имеет этот баг)

-> Самому проходить по набору данных в поисках нужной записи...
Кстати, скорость по сравнению с Локейт практически не измениться...

ага все уже сделано в DBGridEh - менять его ... :(


 
Johnmen ©   (2006-07-20 09:04) [4]


> ага все уже сделано в DBGridEh - менять его ... :(


Ну-ну... Вся надежда на дядю, который за тебя всё сделает?
Или уже "всё" сделал в ЕхЛибГрид. Тогда пользуйся, чего спрашиваешь?


 
Silver... ©   (2006-07-23 17:58) [5]


> Вся надежда на дядю

А зачем на дядю - да я пользую сторонние компоненты (не верю что ктонибудь здесь пользует тока Стандартный VCL), иначе бы писал на ASM-е(к сожаленю не знаю, но по такому поводу вючил бы)

 Вообще DataSet.Filter - инструмент удобный, по крайней мере для меня, но имеет кучю "недорозумений" - DataSet.Locate видит и всё остальное, ...

 А вопрос у меня был: Как отфильтровать DataSet на клиенте (делается частенько не бегать на сервер каждый раз за данными) и без DataSet.Close/Open - опять-таки тормоза имеем --- но чтоб отфильтрованные данные небыли видны (по крайней мере DataSet.Locate) потому что DBGridEh - который я сеичас пользую так ищет в списке то что я набираю

PS. Не прошу сделайте/дайте а подскажите


 
Anatoly Podgoretsky ©   (2006-07-23 18:25) [6]

Я так и не понял, а DataSet это кто?


 
sniknik ©   (2006-07-23 18:34) [7]

> не верю что ктонибудь здесь пользует тока Стандартный VCL
это ты зря, многие используют, я например. и исключительно стандартный. (знаю конторы в которых нестандартные(/некупленные, что зачастую одно и тоже) попросту запрещены. у нас такая контора... была... счас на это не очень внимание обращают, но не изза того чтобы нам полегче было, а просто бардака добавилось с ростом конторы)

> иначе бы писал на ASM-е
а это еще зачем/причем? в смысле знать конечно не повредит но какая связь с VCL?

> PS. Не прошу сделайте/дайте а подскажите
легко. совет не ставь знак равенства между всеми наследниками DataSet... люби конкретику (не только с  DataSet). тогда избежиш "кучю "недорозумений"".


 
Anatoly Podgoretsky ©   (2006-07-23 18:44) [8]

Интересно, что за фильтр наложен, что получился такой результат, что то тут не чисто.


 
sniknik ©   (2006-07-23 18:54) [9]

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


 
Anatoly Podgoretsky ©   (2006-07-23 19:19) [10]

Наверно, но он же обычный партизан.


 
Johnmen ©   (2006-07-23 20:42) [11]

Есть предположение, что товарищ юзает TIBDataSet. Если это так, то ничего удивительного - у него вообще не фильтруется! Ибо, как широко известно, в компонентах IBX свойство Filter нереализовано...


 
Silver... ©   (2006-07-25 17:39) [12]

Значит так:
DataSet -> ADODataSet
но так как для фильтрации процедурку рялизовал ... написал
TDataSet(DataSet).Filter := ... //а тут уж любой наследник попадет

Далее...
 имеем MasterDataSet, DetailDataSet в нем поле Lookup1 от SpravDataSet

В MasterDataSet имеется поле Группа (например - упростил для примера)

Задача:
 В Lookup1 поле DetailDataSet-а надо иметь не полный список из SpravDataSet-а а тока ... соответствующие условию (которое меняется при каждом переходе на др. запись в MasterDataSet [MasterDataSet.AfterScroll])

Выход 1:
 WHERE - не подходит SpravDataSet.Close/Open при каждом MasterDataSet.AfterScroll = тормоза

Выход 2:
 в MasterDataSet.AfterScroll
 SpravDataSet.Filter := Условие фильтра
 -> все работает на ура тока наблудается вышеуказаный баг

PS. Начал дебагить и увидел что в DBGridEh когда набираем теxт в Lookup поле, виполняется:
if AColumn.UsedLookupDataSet.Locate(AColumn.Field.LookupResultField, FSearchText,
     [loCaseInsensitive, loPartialKey]) then

вот здесь ошибка вылитает - SpravDataSet: Record not found

Нацарапал Тест:
Table1...
ID   A
1  aaa
2  bbb
3  ccc
4  aaa
5  bbb


procedure TForm1.FormCreate(Sender: TObject);
begin
 ADODataSet1.Open;
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
 if Edit1.Text <> "" then
   ADODataSet1.Filter := "ID > " + Edit1.Text; //тока цифры разумеется :)
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 ADODataSet1.Locate("A", Edit2.Text, [loCaseInsensitive, loPartialKey]);
 ShowMessage("ID = " + VarToStr(ADODataSet1.FieldByName("ID").Value));
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
 ADODataSet1.Filtered := CheckBox1.Checked;
end;


Проба 1 (без фильтрации):
Table1... имеет вид:
ID   A
--------
1  aaa
2  bbb
3  ccc
4  aaa
5  bbb

ADODataSet1.Filtered := False;
ADODataSet1.Locate("A", "bb", [loCaseInsensitive, loPartialKey])
------
 ShowMessage ---> ID=2 ---- ПРАВЕЛЬНО


Проба 1 (с фильтрацией):
Table1... имеет вид:
ID   A
--------
4  aaa
5  bbb

ADODataSet1.Filtered := False;
ADODataSet1.Filter := "ID > 3";
ADODataSet1.Locate("A", "bb", [loCaseInsensitive, loPartialKey]);
------
 ShowMessage ---> ID=4 ---- НЕ ПРАВЕЛЬНО - должно быть ID=5


sniknik ©   (23.07.06 18:54) [9]  --- Дакажи --- используй мой пример -- поясни


 
Виталий Панасенко   (2006-07-25 18:09) [13]

Вообще-то, Locate - функция логическая. Если найдет, то True
if ADODataSet1.Locate("A", "bb", [loCaseInsensitive, loPartialKey])
then
 ShowMessage("Нашел")
else
 ShowMessage("НЕНашел");


 
sniknik ©   (2006-07-25 20:27) [14]

доказывать не буду, пояснить могу, вернее... не зря тебе говорилось о знаке равенства между датасетами, или скорее отсутствии такового. хочеш проверь, повтори тоже самое на клиентском (ClientDataSet) и попробуй получить тот же рузультат.

с ADO-шным еще проще, вся реализация его локейта в исходниках в ADODB.LocateRecord, кто хочет понять почему и как он работает тот поймет, возможность есть.

не согласен с решением от борланда, используй метод Find непосредственно у обьекта (мелкософтский способ), либо как предлагалось в [1].

и кстати, фильтр без Filtered = true (в [12] "Проба 1 (с фильтрацией):") работать не будет.


 
Silver... ©   (2006-07-25 21:12) [15]


> Виталий Панасенко   (25.07.06 18:09) [13]

у меня на строчке if... ошибку выдает до "нашел" / "не нашел" и не доходит
а по ходу наити должен - обязан только наити должен последний а не второй


> и кстати, фильтр без Filtered = true (в [12] "Проба 1 (с
> фильтрацией):") работать не будет

=
Очепятка разумеется ... Filtered := True


 
Johnmen ©   (2006-07-25 21:45) [16]

Ещё соображение, вследствие которого предполагаю, что надо попробовать выставить LookupCache у лукапного поля в DetailDataSet.


 
StriderMan ©   (2006-07-26 00:06) [17]


> Johnmen ©   (23.07.06 20:42) [11]
>  Ибо, как широко известно, в компонентах IBX свойство Filter
> нереализовано...

А вот и неправда! В TIBTable прекрасно работает фильтр!


 
Johnmen ©   (2006-07-26 00:43) [18]


> StriderMan ©   (26.07.06 00:06) [17]
> А вот и неправда! В TIBTable прекрасно работает фильтр!


Ох уж эти сказочники (с)


 
Виталий Панасенко   (2006-07-26 09:06) [19]


> Silver... ©   (25.07.06 21:12) [15]
>
> > Виталий Панасенко   (25.07.06 18:09) [13]
>
> у меня на строчке if... ошибку выдает до "нашел" / "не нашел"
> и не доходит
> а по ходу наити должен - обязан только наити должен последний
> а не второй

Загадочный ты зверь... А сообщить конкретно какую ошибку - табу ?


 
StriderMan ©   (2006-07-26 12:18) [20]


> Johnmen ©   (26.07.06 00:43) [18]

Попробуйте, а потом утверждайте.

у TIBQuery действительно не работает, но TIBTable, повторюсь, прекрасно с фильтрацией справляется! У меня на них проект живет!


 
Johnmen ©   (2006-07-26 13:26) [21]


> StriderMan ©   (26.07.06 12:18) [20]
>Попробуйте, а потом утверждайте.


Мне не надо пробовать. Достаточно в исходники заглянуть...

> но TIBTable, повторюсь, прекрасно с фильтрацией справляется!

Не верю :)
Приводите код.

> У меня на них проект живет!

Вот это чудо. Сочувствую. Искренне...:)


 
StriderMan ©   (2006-07-26 14:14) [22]


> Не верю :)
> Приводите код.


procedure TIBTable.GenerateSQL;

...

 if Filtered and (Filter <> "") then  {do not localize}
 begin
   SQL.Text := SQL.Text + " where " + Filter; {do not localize}
   bWhereClausePresent := True;
 end;


 
Johnmen ©   (2006-07-26 14:18) [23]


> StriderMan ©   (26.07.06 14:14) [22]


Мне не интересен код исходников. Он у меня как бы есть...
Приводите СВОЙ код, говорящий о том, что св-во Filter работает.


 
Silver... ©   (2006-07-26 14:25) [24]


> Загадочный ты зверь... А сообщить конкретно какую ошибку
> - табу ?



...

> Silver... ©   (25.07.06 17:39) [12]


>      [loCaseInsensitive, loPartialKey]) then
> вот здесь ошибка вылитает - SpravDataSet: Record not found


 
StriderMan ©   (2006-07-26 14:26) [25]


> Мне не интересен код исходников. Он у меня как бы есть..
> .

ну так посморите на него внимательно [22], и скажите почему вдруг он не работает


> Приводите СВОЙ код, говорящий о том, что св-во Filter работает

как интересно в коде можно узнать, сработал он или нет??
ну раз уж вам так интересно, привожу

   
dmTable2.Table.Filter := "Table1ID = " + dmTable1.fldID.AsString;
dmTable2.Table.Filtered := true;


(имена объектов изменены)


 
Johnmen ©   (2006-07-26 14:30) [26]

1. Обращаю Ваше внимание на то, где у Вас стоИт Open. Поставьте его перед приведённым кодом и проанализируйте эффект.
2. Так же неплохо бы внимательно прочитать комментарий, указанный в приведенной выдержке исходника.


 
Виталий Панасенко   (2006-07-26 14:31) [27]


> Silver... ©   (26.07.06 14:25) [24]

Это ты под средой такое сообщение получаешь или при выполнении собственно программы ? Ты что-то накрутил в параметрах поиска. Потому у тебя и "не работает Locate по фильтру". Потому как Locate  не находит того, что ты ищешь. потому и ...


 
Johnmen ©   (2006-07-26 14:34) [28]


> Silver... ©   (26.07.06 14:25) [24]


Ошибка возбуждается в процедуре Resync с параметром mrExact
begin
 CursorPosChanged;
  if GetRecord(FBuffers[FRecordCount], gmCurrent, True) <> grOK then
    DatabaseError(SRecordNotFound, Self);

Это значит, что не может быть найдена запись для обновления/идентификации на предмет получения лукапного значения. Ну естественно, ведь стоИт фильтр. Поэтому попробуй [16].


 
StriderMan ©   (2006-07-26 14:38) [29]


> 1. Обращаю Ваше внимание на то, где у Вас стоИт Open. Поставьте
> его перед приведённым кодом и проанализируйте эффект.

Open стоит ЗАДОЛГО до этого кода. И все работает прекрасно.

> 2.

честно говоря смысл комментария не уловил. что он значит?


 
sniknik ©   (2006-07-26 14:53) [30]

Johnmen ©   (26.07.06 14:30) [26]
> 1. Обращаю Ваше внимание на то, где у Вас стоИт Open. ...
неважно, судя по исходникам (D7)

procedure TIBDataSet.SetFiltered(Value: Boolean);
begin
 if (Filtered <> Value) then
 begin
   inherited SetFiltered(value);
   if Active then
   begin
     Close;
     Open;

   end;
 end
 else
   inherited SetFiltered(value);
end;


 
Johnmen ©   (2006-07-26 15:13) [31]

1. Вот именно! Происходит переоткрытие НД с изменением в запросе параметров WHERE. Причём тут ФИЛЬТРАЦИЯ (набора данных)????????
2. Комментарий означает, что данные фичи НЕ ЛОКАЛИЗОВАНЫ, т.е. не имеют локальной реализации для набора данных.

А коли так, то эта якобы фильтрация есть простое изменение текста запроса с повторным выполнением.


 
StriderMan ©   (2006-07-26 15:20) [32]


> НЕ ЛОКАЛИЗОВАНЫ, т.е. не имеют локальной реализации для
> набора данных

что значит локальная реализация? IBTable и есть набор данных. Это не абстрактный класс.


> то эта якобы фильтрация есть простое изменение текста запроса
> с повторным выполнением.

а что нужно от нормальной фильтрации? как она должна работать?


 
Johnmen ©   (2006-07-26 15:23) [33]


> sniknik ©   (26.07.06 14:53) [30]


Кстати, надо смотреть SetFilterText, который переопределён для TIBTable а тянется от предпредка - TDataSet.


 
Sergey13 ©   (2006-07-26 15:25) [34]

2 [32] StriderMan ©   (26.07.06 15:20)
> а что нужно от нормальной фильтрации? как она должна работать?

На клиенте наверное. Без обращения к серверу.


 
Johnmen ©   (2006-07-26 15:29) [35]

> что значит локальная реализация?

Это значит для данных, которые уже на клиенте, локально.

> IBTable и есть набор данных.

И что?

>  Это не абстрактный класс.

Про абстрактный класс я ничего не говорил.

> а что нужно от нормальной фильтрации?

Чтобы она работала.

>как она должна работать?

Правильно.


 
Desdechado ©   (2006-07-26 15:40) [36]

> 2. Комментарий означает, что данные фичи НЕ ЛОКАЛИЗОВАНЫ,
>  т.е. не имеют локальной реализации для набора данных.

Выдаешь желаемое за действительное :)
Комментарий означает всего лишь то, что текстовая строка " where " не является ресурсом, требующим перевода на другие языки при попытках локализации (перевода).


 
Johnmen ©   (2006-07-26 15:55) [37]


> Desdechado ©   (26.07.06 15:40) [36]


Пусть так.


 
StriderMan ©   (2006-07-26 16:15) [38]


> Правильно.

как правильно? есть стандарт фильтрации наборов данных?


 
Silver... ©   (2006-07-26 16:19) [39]

[16] - уже пробовал - Не работает

Да я думаю Lookup тут вовсе не причем, из теста видно что Locate ищет во всем DataSet-е -- а не должен. Мне бы какимто образом (локально не WHERE) ограничить его поиск тока на не отфильтрированые записи.
 Как?

PS. я б сказал что это баг в функции: С чего бы вдруг искать в данных вне поля зрения (на крайняк параметр бы сунули типа [loFullDataSet])


 
Johnmen ©   (2006-07-26 16:25) [40]

[39]

> из теста видно что Locate ищет во всем DataSet-е -- а не
> должен.


[15]

> у меня на строчке if... ошибку выдает до "нашел" / "не нашел" и не доходит


Как Вас понимать, сэр?


 
Silver... ©   (2006-07-26 16:40) [41]

интересно чего не понятного

Тест - тот что я сделал отдельно в [12]

вот объясните ...

ADODataSet1...
ID   A
--------
1  aaa
2  bbb
3  ccc
4  aaa
5  bbb


фильтрируем:
ADODataSet1.Filter := "ID > 3";
ADODataSet.Filtered := True;


получаем:
ADODataSet1...
ID   A
--------
4  aaa
5  bbb


ишем:
ADODataSet1.Locate("A", "BB", [loCaseInsensitive, loPartialKey]);
ShowMessage("ID = " + VarToStr(ADODataSet1.FieldByName("ID").Value));


понятное дело не находит и курсор остается на первой записи

как получить ID = 5 --- не даст ведь :( в этом то и вся проблемма


 
Johnmen ©   (2006-07-26 17:35) [42]


> понятное дело не находит и курсор остается на первой записи


Должна находить. Даже в отфильтрованном.
Ошибка закомуфлирована. Она не здесь...


 
sniknik ©   (2006-07-26 18:18) [43]

Johnmen ©   (26.07.06 17:35) [42]
> Должна находить. Даже в отфильтрованном.
> Ошибка закомуфлирована. Она не здесь...
она и находит, даже в отфильтрованном...

интересно долго еще будет рассусоливание одного и тогоже?... когда ктонибудь реализацию ADODB.LocateRecord посмотрит? еще в [14] предлагал... элементарно ведь.
Johnmen тебе то это просто посмотреть надо, сразу понятно...


 
Silver... ©   (2006-07-26 18:36) [44]

смотрю и вижу...

FLookupCursor.Filter := "";

 одно не могу понять кто именно разработчикам VCL сказал убирать фильтр перед поиском или мож проблемы дает?

 Теперь чего генофонд править?


 
sniknik ©   (2006-07-26 20:29) [45]

> но не могу понять кто именно разработчикам VCL сказал убирать фильтр перед поиском
это не убирание, это скорее гарантия, однотипного поведения (чтоб предыдущие поиски не наложились...) а изначально там и так пусто, неважно есть у тебя фильтр или нет.

и поведения вероятно специально запрограммированого... логика скорее всего такая - locate должен показывать есть ли искомая запись в рекордсете, и ведь показывает же! а от установки фильтра физически данные из рекордсета не исчазают... просто фильтруется вывод на показ. и что теперь должен искать locate? толко среди выводимых на показ? но ведь locate это метод рекордсета (который неизменился) а не какогото дополнительного обьекта "отфильтрованные для отображения записи".
т.е. с этой точки зрения все правильно (хотя х.з. что там на самом деле в головах разработчикой присходило...)
есть и другое соображение, если сделать "по Silver-овски" то потеряем возможность поиска вне фильтра (узнать есть ли вообще запись) при установленном, а вот если так как есть то желаемый поик только в отфильтрованном легко осуществить и другими методами... в ADO на locate свет клином не сошолся.

> Теперь чего генофонд править?
ну попробуй. ;)

но вообще, советы, что делать, тоже в [14] были. + упоминавшийся поиск другими методами, да и locate поправить элементарно главное не в генофонде, а к себе модуль скопировать.


 
Anatoly Podgoretsky ©   (2006-07-26 20:37) [46]

StriderMan ©   (26.07.06 14:14) [22]
Это не фильтр, а новый запрос к серверу.


 
Silver... ©   (2006-07-26 21:09) [47]


> в ADO на locate свет клином не сошолся.

согласен тока веди в DBGridEh Locate-ом рялизованно теперь мне либо там либо сям менять надо. а вообше разработчикам совет бы переслать вшить в генофонд [loFullDataSet] - было бы красивше


 
Silver... ©   (2006-07-26 21:14) [48]


> в ADO на locate свет клином не сошолся.

согласен тока веди в DBGridEh Locate-ом рялизованно теперь мне либо там либо сям менять надо. а вообше разработчикам совет бы переслать вшить в генофонд типа [loFullDataSet/loFilteredDataSet] - было бы красивше


 
Johnmen ©   (2006-07-27 10:29) [49]

>sniknik ©   (26.07.06 18:18) [43]
>Johnmen тебе то это просто посмотреть надо, сразу понятно...

Да, мне сразу понятно, что находит даже в отфильтрованном. Что и подтверждается быстро накиданным мною примерчиком...
Так что
> Должна находить. Даже в отфильтрованном.
> Ошибка закомуфлирована. Она не здесь...
По-прежнему актуально.



Страницы: 1 2 вся ветка

Форум: "Базы";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.6 MB
Время: 0.013 c
15-1157900925
новоалексан
2006-09-10 19:08
2006.10.01
Как создать true type шрифт?


2-1157695195
Bwa_JO
2006-09-08 09:59
2006.10.01
Кто-нибудь мне может подсказать что-нибудь про getAttribute?


15-1157898818
Дураг
2006-09-10 18:33
2006.10.01
А есть ли шаблоны проектирования в Delphi?


15-1157814167
ArtemESC
2006-09-09 19:02
2006.10.01
Английский...


2-1158207408
O.O
2006-09-14 08:16
2006.10.01
Погасить message





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский