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


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



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

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

Наверх




Память: 0.57 MB
Время: 0.012 c
2-1157909809
p314
2006-09-10 21:36
2006.10.01
Типы данных со словом type


15-1158086887
1519
2006-09-12 22:48
2006.10.01
Меню пуск


1-1155711055
QuickFinder
2006-08-16 10:50
2006.10.01
Дату в 4 байта


1-1155736066
bvn123
2006-08-16 17:47
2006.10.01
Событие/сообщение в DLL, автоматически обрабатываемое в main


4-1148418602
GanibalLector
2006-05-24 01:10
2006.10.01
KeyboardLayout





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