Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Быстрый поиск в базах данных

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

Я представляю на Ваш суд утилиту быстрого поиска по базе данных. Данная технология производит поиск по полям, преобразуя их значения в строки (все значения преобразуются в верхний регистр, включая действительные числа). Данное решение может быть не самым быстрым, однако на поверку оно оказывается быстрее остальных, обнаруженных мною в Интернете (может вам повезет больше). Более того, представьте, что действительное значение какого-либо поля равно 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.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay