![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Организация поиска "Далее" [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 - Далее