Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Организация поиска "Далее" [D7]


Den1111 ©   (2009-05-20 12:23:00) 

Помогите пожалуйста оптимизировать функцию поиска. Вообщем реализую поиск по БД. Необходимо найти первое совпадение, после нажимая кнопку "найти далее" ищем следующее совпадение и т.д.
Есть такой код:
procedure TForm1.Button1Click(Sender: TObject);
var FoundRec:boolean;
begin
 FoundRec:=False;
 ButSearchNext.Enabled:=False;
 ADOTable1.First;
 while not ADOTable1.Eof do begin
   if AnsiLowerCase(ADOTable1.FieldValues['pr']) = AnsiLowerCase(Edit1.Text) then
     begin
       FoundRec:=True;
       ButSearchNext.Enabled:=True;
       break;
     end;
   ADOTable1.Next;
 end;
 if not FoundRec then begin
   ADOTable1.First;
   ShowMessage(Edit1.Text+'не найден');
 end;
end;

procedure TForm1.butSearchNextClick(Sender: TObject);
begin
 ADOTable1.Next;
 while not ADOTable1.Eof do begin
   if AnsiLowerCase(ADOTable1.FieldValues['pr']) = AnsiLowerCase(Edit1.Text) then
     break;
   ADOTable1.Next;
   if ADOTable1.Eof then ADOTable1.First;
 end;
end;


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


Ega23   (2009-05-21 11:38:00) [1]


> Я использую TADODataSet


Одобряю.  :)


Den1111   (2009-05-21 11:31:00) [2]


> Ega23 ©   (21.05.09 10:20) [14]

По поводу правил знаю, исправлюсь :)

Ладно придираться то :) Я использую TADODataSet


Ega23   (2009-05-21 10:20:00) [3]


> PS пишу из под другого ника


Вообще-то это запрещено правилами форума. Запрещается, пункт 5.


> Еще раз спасибо. Ttable не использую, только DataSet (в
> основной проге)


А что, TTable это не TDataSet?   :)))


Den1111   (2009-05-21 08:09:00) [4]


> sniknik ©   (20.05.09 18:14) [12]

Мне было важно понять сам принцип работы такого поиска, в основной программе уже сделал как положено. Еще раз спасибо. Ttable не использую, только DataSet (в основной проге)


sniknik   (2009-05-20 18:14:00) [5]

> Да нет, советам я как раз внял!
почему тогда код не выкинул а продолжаешь отлаживать и компонент стремный оставил?


Tornado   (2009-05-20 18:02:00) [6]

PS пишу из под другого ника


Tornado   (2009-05-20 18:01:00) [7]


> Ega23 ©   (20.05.09 16:36) [8]

Да нет, советам я как раз внял! Этот код я привожу из тестовой программки, для отладки поиска, а потом уже перенесу в основную! И там конечно же сделаю все как надо. СПАСИБО огромное мастера!


sniknik   (2009-05-20 16:50:00) [8]

> А зря.
а пофигу. только плохо, что после И.Ш. будет такого защищать, что его увольнять нельзя... :(


Ega23   (2009-05-20 16:36:00) [9]


> Как можно ее обойти?


var
 fld : TStringField;
begin
 .....
 while not ADOTable1.Eof do
 begin
   fld := ADOTable1.FieldByName('name');
   if fld.IsNull then Continue;
   if Pos(s, AnsiLowerCase(fld.AsString)) > 0 then  
  ......    
 


Ну и советам ты не внял, как я вижу. А зря.


Anatoly Podgoretsky   (2009-05-20 16:33:00) [10]

TField.IsNull


Den1111   (2009-05-20 15:28:00) [11]

Вообщем все получилось, почти :) Дело в том что при поиске если попадается пустая строка (а такое бывает, это справочник телефонов, у некоторых пользователей телефона нет, но допустим есть факс, а факс в другом столбце) то я тут же получаю ошибку "Could not convert variant of type (Null) into type (String)". Как можно ее обойти?

Код такой:

procedure TForm1.Button1Click(Sender: TObject);

begin

 FoundRec:=False;
 ButSearchNext.Enabled:=False;
 ADOTable1.First;

 while not ADOTable1.Eof do begin

if Pos(AnsiLowerCase(Edit1.Text), AnsiLowerCase(ADOTable1.FieldValues['name'])) > 0 then
     begin
       FoundRec:=True;
       Button1.Caption := 'найти далее';
       break;
     end;

   ADOTable1.Next;
 end;
 if not FoundRec then begin
   ADOTable1.First;
   ShowMessage(Edit1.Text+'не найдено');
 end;

end;

procedure TForm1.butSearchNextClick(Sender: TObject);
begin
 ADOTable1.Next;
 while not ADOTable1.Eof do begin

if Pos(AnsiLowerCase(Edit1.Text), AnsiLowerCase(ADOTable1.FieldValues['name'])) > 0 then
     break;
   ADOTable1.Next;
  if ADOTable1.Eof then begin
  ADOTable1.First;
  ShowMessage(Edit1.Text+' не найдено');
  end;
 end;
end;


Отдельное спасибо >> Юрий Зотов ©   (20.05.09 12:33) [3]  :))


Den1111   (2009-05-20 12:57:00) [12]

Спасибо всем!


sniknik   (2009-05-20 12:47:00) [13]

по теме
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1241152560&n=18
и для общего развития про ADOTable
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1240985406&n=18


Юрий Зотов   (2009-05-20 12:33:00) [14]

Вместо

if AnsiLowerCase(ADOTable1.FieldValues['pr']) = AnsiLowerCase(Edit1.Text) then

используем

if Pos(AnsiLowerCase(Edit1.Text), AnsiLowerCase(ADOTable1.FieldValues['pr'])) then


Ega23   (2009-05-20 12:30:00) [15]

Недели 2-3 назад обсуждалось, поищи либо в "Начинающим" либо в "Базы", про Locate.

Теперь общие замечания по коду.

1. Не пренебрегай такой штукой, как
DataSet.DisableControls;
try
 ... Работаем с НД
finally
 DataSet.EnableControls;
end;


Данная конструкция ускоряет обход НД на порядок (а то и больше). Даже если к нему никакий DataSource не привязано.

2.
while not ADOTable1.Eof do begin
  if AnsiLowerCase(ADOTable1.FieldValues['pr']) = AnsiLowerCase(Edit1.Text) then
    begin
Зачем каждый такт цикла вычисляешь AnsiLowerCase(Edit1.Text)? Он же не меняется. Объяви
var
 s : string;
begin
 s := AnsiLowerCase(Edit1.Text);
 while not ADOTable1.Eof do begin
   if AnsiLowerCase(ADOTable1.FieldValues['pr'])=ss then
    ....


3. Что-то мне подсказывает, что если не будет найдено ни одного вхождения, то данный код

while not ADOTable1.Eof do begin
  if AnsiLowerCase(ADOTable1.FieldValues['pr']) = AnsiLowerCase(Edit1.Text) then
    break;
  ADOTable1.Next;
  if ADOTable1.Eof then ADOTable1.First;
end;

уйдёт в бесконечный цикл.


Den1111   (2009-05-20 12:24:00) [16]

По клику на Button1 ищем первую запись удовлетворяющую условию, по кнопке butSearchNext - Далее


Наверх

Титульная страница Поиск, карта сайта Написать письмо