Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

Курс видеоуроков программирования и крэкерства 6.0
(актуальность: февраль 2017)
Свежие инструменты, новые видеоуроки!

  • 300+ видеоуроков
  • 800 инструментов
  • 80 свежих книг и статей

УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Быстрый поиск в базах данных

Кинул как-то уркаган маляву по Яндексу...

Я представляю на Ваш суд утилиту быстрого поиска по базе данных. Данная технология производит поиск по полям, преобразуя их значения в строки (все значения преобразуются в верхний регистр, включая действительные числа). Данное решение может быть не самым быстрым, однако на поверку оно оказывается быстрее остальных, обнаруженных мною в Интернете (может вам повезет больше). Более того, представьте, что действительное значение какого-либо поля равно 4.509375354, а значение поиска равно 7, в этом случае утилита засчитает "попадание". Утилита удобна также тем, что она за один проход производит поиск более, чем в одном поле. Это удобно, если у Вас имеются, к примеру, два поля с адресами. Это моя первая "серьезная" разработка, так как первое, с чем я столкнулся, изучая Delphi, стала необходимость включения процедуры поиска в любое приложение, работающее с базой данных. А так как поиск - вещь тоже сугубо специфическая, как и любое приложение, то мне пришлось побороть свой страх перед "крутым программированием" и попробовать написать свой поисковый механизм, удовлетворивший меня (и, надеюсь, других) своей скоростью и возможностью "мульти"-поиска по нескольким полям. Я надеюсь, что он поможет тем программистам, кто часто сталкивается с подобными задачами. Технология довольно легка для понимания, но если у Вас возникли какие-либо вопросы, пошлите мне письмо электронной почтой, я буду рад Вам помочь. Посмотрев код, можно легко узнать поддерживаемые типы полей (добавить новые не составит проблем). Если кто-либо обнаружит ошибочный код или расширит функциональность утилиты, пожалуйста, пошлите это мне, я буду весьма благодарен. Спасибо.


 unit Finder;
 
 interface
 
 uses DB, DBTables, SysUtils;
 
 function GrabMemoFieldAsPChar(TheField: TMemoField): PChar;
 function DoFindIn(TheField: TField; SFor: string): Boolean;
 function FindIt(TheTable: TDataSet; TheFields: array of integer;
 
   SearchBackward: Boolean; FromBeginning: Boolean; SFor: string): Boolean;
 {применение функции FindIt -
 
 if FindIt(NotesSearchT,
 [NotesSearchT.FieldByName('Leadman').Index],
 False, True, SearchText.Text) then DoSomething; }
 
 implementation
 
 function GrabMemoFieldAsPChar(TheField: TMemoField): PChar;
 begin
   with TBlobStream.Create(TheField, bmRead) do
 
   begin
     GetMem(Result, Size + 1);
     FillChar(Result^, Size + 1, #0);
     Read(Result^, Size);
     Free;
   end;
 end;
 
 function DoFindIn(TheField: TField; SFor: string): Boolean;
 var
 
   PChForMemo: PChar;
 begin
   Result := False;
   case TheField.DataType of
 
     ftString:
       begin
         if (Pos(SFor, UpperCase(TheField.AsString)) > 0) then
           Result := True;
       end;
     ftInteger:
       begin
         if (Pos(SFor, TheField.AsString) > 0) then
           Result := True;
       end;
     ftBoolean:
       begin
         if SFor = UpperCase(TheField.AsString) then
           Result := True;
       end;
     ftFloat:
       begin
         if (Pos(SFor, TheField.AsString) > 0) then
           Result := True;
       end;
     ftCurrency:
       begin
         if (Pos(SFor, TheField.AsString) > 0) then
           Result := True;
       end;
     ftDate..ftDateTime:
       begin
         if (Pos(SFor, TheField.AsString) > 0) then
           Result := True;
       end;
     ftMemo:
       begin
         SFor[Ord(SFor[0]) + 1] := #0;
         PChForMemo := GrabMemoFieldAsPChar(TMemoField(TheField));
         StrUpper(PChForMemo);
         if not (StrPos(PChForMemo, @SFor[1]) = nil) then
           Result :=
             True;
         FreeMem(PChForMemo, StrLen(PChForMemo + 1));
       end;
   end;
 end;
 
 function FindIt(TheTable: TDataSet; TheFields: array of integer;
 
   SearchBackward: Boolean; FromBeginning: Boolean; SFor: string): Boolean;
 var
 
   i, HighTheFields, LowTheFields: integer;
   BM: TBookmark;
 begin
   TheTable.DisableControls;
   BM := TheTable.GetBookmark;
   try
     LowTheFields := Low(TheFields);
     HighTheFields := High(TheFields);
     SFor := UpperCase(SFor);
     Result := False;
     if FromBeginning then
       TheTable.First;
     if SearchBackward then
 
     begin
       TheTable.Prior;
       while not TheTable.BOF do
       begin
         for i := LowTheFields to HighTheFields do
         begin
           if DoFindIn(TheTable.Fields[TheFields[i]], SFor) then
           begin
             Result := True;
             Break;
           end;
         end;
         if Result then
           Break
         else
           TheTable.Prior;
       end;
     end
     else
     begin
       TheTable.Next;
       while not TheTable.EOF do
       begin
         for i := LowTheFields to HighTheFields do
         begin
           if DoFindIn(TheTable.Fields[TheFields[i]], SFor) then
           begin
             Result := True;
             Break;
           end;
         end;
         if Result then
           Break
         else
           TheTable.Next;
       end;
     end;
   finally
     TheTable.EnableControls;
     if not Result then
 
       TheTable.GotoBookmark(BM);
     TheTable.FreeBookmark(BM);
   end;
 
 end;
 
 end.
 




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS