Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск записи, Locate 
:(
    Опции темы
MacTep
  Дата 9.2.2005, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Как организовать поиск в базе данных таким образом, чтобы пользовательно по нажатию любой клавиши видел, что активной стала та запись, в которой какое-либо поле начинается с той буквы, которую нажал пользователь? Я пишу так:

Код

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
 Main.Locate('NameFilm',Key,[loPartialKey]);
end;


Работает только при первом нахождении записи. после второго нажатия на эту же клавишу активной остатся старая запись, а следующую запись с такой же первой буквой не становится активной. Как испрвить? Буду рад всем предложениям! smile


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Alex
Дата 9.2.2005, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 17
Всего: 162



А если так:
Код

Main.Locate('NameFilm',Key,[loCaseInsensitive]);



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
MacTep
Дата 10.2.2005, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Alex, так как ты предложил работать тоже не будет, так как ключ поиска loPartialKey предполагает и добавление к нему loCaseInsensitive. Т.е. Дельфи сама приписывает это значение к ключу loPartialKey (прочитал об этом в книге). Так что вопрос по прежнему остается открытым! smile А хотелось бы его как можно быстрее закрыть...


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
z-END
Дата 10.2.2005, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 1
Всего: 102



хочется - закрывай=)
а вообще Locate ищет первую запись не от текущей, а с первой, по этому ничего не выйдет


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Sharl
Дата 10.2.2005, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 16.8.2003

Репутация: нет
Всего: нет



Можно по другому подойти ,использовав все время обновляемую
TTable.Filter


PM MAIL   Вверх
z-END
Дата 10.2.2005, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 1
Всего: 102



Sharl ой незнаю... при нажатии на педаль каждый раз делать:
1. DisableControls//отключаем контролы
2. Filter ( причем я слабо себе представляю как ты опишешь это в фильтре) //выполняем поиск необходимой записи
3. x :=KeyFieldValue; //присваеваем х - данные ключевого поля, (без него вообще дохлый номер)
4. Filtered := False; //отключаем фильтр
5. Loacte (x); // находим по ключевому полю требуемую запись
6. EnableControls //включаем контролы
если в БД куча записей ты представляешь сколько время на это уйдет, а если данные уже отображаются отфильтрованными, че тогда?!
Наверно правильней при нажатии создавать SQL-запрос (вот тока в запросах несилен, незнаю мона так делать или нет), в который поместить все записи содержашие данную букву, при повторном нажатии перемещать указатель скула на сл.запись и передвигать его аналогично в основной БД.


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Alex
Дата 10.2.2005, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 17
Всего: 162



а я бы подглядел как это делает EhLib в своем поиске smile


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Akella
Дата 10.2.2005, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Цитата(Alex @ 10.2.2005, 17:21)
а я бы подглядел как это делает EhLib в своем поиске

Я тоже отключаю такую возможность, в том случае если много записей, т.к. начинает тормозить.
Добавлено @ 17:44
а так работает нормально
Код

tFilterPrep - TTable
idxFName - индекс
edGroupFind - TEdit
 if tFilterPrep.IndexName <> 'idxFName' then tFilterPrep.IndexName:='idxFName';
 tFilterPrep.FindNearest([edGroupFind.Text]);


Это сообщение отредактировал(а) dsergey - 10.2.2005, 17:45
PM MAIL   Вверх
Sharl
Дата 10.2.2005, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 16.8.2003

Репутация: нет
Всего: нет



Цитата

Наверно правильней при нажатии создавать SQL-запрос (вот тока в запросах несилен, незнаю мона так делать или нет), в который поместить все записи содержашие данную букву, при повторном нажатии перемещать указатель скула на сл.запись и передвигать его аналогично в основной БД.

z-END
Да.
Наверно для решения этой задачи лучше использовать SQL

запрос может быть примерно таким
Код

SELECT *(или имена полей таблиц)  FROM имя_таблицы WHERE искомое_поле LIKE 'введенные_символы%'
(% - означает - остальное неважно).


А потом в проге делать
Код

Query1.Next;


Еще один метод
Можно использовать
Query1(или Table1).Database.StartTransaction;
перед переходом

Table1.Delete;
и снова Locate,

В конце работы с поиском
Query1.Database.Rollback;

Но наверно метод второй более дикий по отношению к user-у?



PM MAIL   Вверх
MacTep
Дата 11.2.2005, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Спасибо всем за советы, попробую что-нибудь придумать. Посмотрим, что из этого получится...


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Akella
Дата 11.2.2005, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Нуно использовать принцип пробежки по все полям с использованием фанкции POS


Процедура поиска по всем полям

Код


Procedure FindRec(What,Mes:String;DS:TDataSet;sFields:array of String;
                            foFromBegin,foCaseSansitive,ShowMes:Boolean);
{
What            - строка для поиска (editFind.Text)
DS              - таблица (TTable,TQuery и т.д.)
Fields          - список полей, по которым нужно вести поиск (['Field1','Field3','Field7'])
foFromBegin     - поиск от начала таблицы (true - от начала или False от текущей записи)
foCaseSansitive - поиск с зависимостью от регистра символов (true - зависит от регистра или False не зависит от регистра)
}
  Function FieldInFields(_Field:String;_Fields:array of String):Boolean;//
  Var
   x:byte;
  begin//содержиться ли текущее поле в масива полей, предназначенных для поиска
    Result:=False;
    For x:=Low(_Fields) to High(_Fields) do
      if _Field = _Fields[x] then begin
        result:=true;
        exit;
      end;//if
  end;//func

Var
i,q,f,w:integer;
begin
ds.DisableControls;//для ускорения отключаем таблицу
w:=ds.RecNo;
try
  //если поиск сначала таблицы
    if foFromBegin then q:=0 else q:=ds.RecNo;
  //идем по всем записям
    For i:=q to ds.RecordCount-1 do begin
  //пробег по всем полям
      For f:=0 to ds.FieldCount-1 do begin
  //если текущее поле содержится в массиве полей, предназначенных для поиска
        if FieldInFields(ds.Fields[f].FieldName,sFields) then begin
  //проверка на регистр
          if (foCaseSansitive = True) AND (POS(What,ds.Fields[f].AsString)<>0) then exit;
          if (foCaseSansitive = False) AND (POS(AnsiUpperCase(What),AnsiUpperCase(ds.Fields[f].AsString))<>0) then exit;
        end;//if FieldInFields(ds.Fields[f].FieldName,sField) then begin
      end;//For f:=0 to ds.FieldCount-1 do begin
      ds.Next;
    end;//For i:=q to ds.RecordCount-1 do begin
    ds.RecNo:=w;
    if ShowMes then ShowMessage(mes);
finally
  ds.EnableControls;//даже если произойдет исключение, то таблицу надо включить
end;//try-finally
end;//proc


Пример использования


FindRec(edFindText.Text,'',dm.tSpis,['Dirname','Type','PathName','Prim'],False,cbRegister.Checked,False);


PM MAIL   Вверх
Sharl
Дата 11.2.2005, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 16.8.2003

Репутация: нет
Всего: нет



Bce отлично , но проблематично
Код

ds.RecNo

скажем для Access-a надо ручками пересчитать и каждый раз сканировать с первой записи или поставить TBookmark- и


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0958 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.