Форум: "Базы";
Текущий архив: 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 Name3DataSet.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 bbbprocedure 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 bbbADODataSet1.Filtered := False;
ADODataSet1.Locate("A", "bb", [loCaseInsensitive, loPartialKey])
------
ShowMessage ---> ID=2 ---- ПРАВЕЛЬНО
Проба 1 (с фильтрацией):
Table1... имеет вид:
ID A
--------
4 aaa
5 bbbADODataSet1.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 с параметром mrExactbegin
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