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