Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.01;
Скачать: CL | DM;

Вниз

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... ошибку выдает до "нашел" / "не нашел" и не доходит


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



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

Текущий архив: 2006.10.01;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.047 c
2-1157984741
SamProf
2006-09-11 18:25
2006.10.01
TForm.onShow или как там


15-1157985150
Ломброзо
2006-09-11 18:32
2006.10.01
Ищу tool для Oracle


15-1157912513
Tar[OFF]
2006-09-10 22:21
2006.10.01
Помогите сделать принтер


6-1139698111
msdn11
2006-02-12 01:48
2006.10.01
AT+CMGS sms не уходит


2-1157920671
Ivanov
2006-09-11 00:37
2006.10.01
Проблема с dll