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