📄 database.htm
字号:
happens.
> Also when I run the application I get no data on any form/datasource in it.
>
> In the "Database Explorer" from the Delphi menu, I get all the tables and their data
with no problem.
</PRE>
<P>The table needs to be open. Change the Active property of the Ttable to True.</P>
<H1><A NAME="database5">Delphi table scrolling: PeekMessage() tricks</A></H1>
<I><P>From: ComDep@lottery.powernet.co.uk (Matthew)</P>
</I><P>I have had a play with PeekMessage(). The function works, but the catch is as follows.</P>
<P>I am scrolling a linked table. The "seek" in the link slows the scolling down. So I only want to "seek"
and locate the record pointer in the other table when the user has STOPPED scrolling. While the user is scolling,
I don't want seeks. So I thought, if there are Messages pending, with PeekMessage(), then don't seek, else do. Sounds simple, but the trick is this.</P>
<P>I set the seek filter to WM_MOUSEFIRST/LAST. The user presses the mouse down continuously on the scroll bar of a DBGrid.
This results in PeekMessage() returning false, which is not what we want.
Only continous and very fast Mouse up/mouse down/mouse up/mouse down action would return true.</P>
<P>If I use 0 and 0 in the filter to catch ANY message, the result always returns true.
The reason, I think, is that any mouse click in my display has some consequence, i.e. a PAINT message,
so the PeekMessage returns true at all times, so does not help.</P>
<P>What would be great would be if there was a OnMouseUp() handler which works when the user releases the mouse on the DBGrid scroll bar.
Sadly, OnMouseUp() works only inside the DBGrid, not on its scrolls bars. OnMouseUp() with TForm's KeyPreview:=true does not respond at all, I have found.</P>
<P>One more thing I tested was polling with GetKeyState() for the Mouse buttons.
I thought while the mouse is DOWN do not update the "seek", otherwise do.
Unfortunately, by the time the mouse is UP, the scrolling has finished.
This is the way the Windows scroll bars seem to work. So the seek never happens and the table record pointer is not updated. </P>
<P>These issues all concern the scroll bars, everything else can be handled with OnKeyUp() and OnMouseUp() elsewhere.</P>
<H1><A NAME="database6">OnCalcFields Hint</A></H1>
<I><P>From: "Andrew Michael Gibson" <GibsonA@Jedi.nwnet.co.uk></P>
</I><P>The Oncalc event is called VERY often, and can be unnecessary and time consuming</P>
<P>lets say you have a calculated field, and that need calclating according to some field that the user edits (i.e)</P>
<P><HR></P>
<PRE>MyCalcField.AsInteger := Table1Field1.AsInteger + 10;</PRE>
<P><HR></P>
<P>Now, should you decide to go and sequentially go through every record in the table,
that is a lot of on calc events occuring! They are also possibly unnecessary if you are not doing processing involving the MyCalcField.</P>
<P>I would suggest turning this event off before processing, and the turning it back on after processing i.e. :</P>
<P><HR></P>
<PRE>Procedure TForm1.BigProcessingFunction;
begin
Table1.OnCalcFields := nil;
<Do massive processing here!>
Table1.OnCalcFields := Table1OnCalcFields;
end;</PRE>
<P><HR></P>
<P>of course the fields are not calculated during the processing time, which can be a bummer,
but if you need the result of a specific field, you can calculate that during the massive processing!</P>
<P>This method of avoiding unnecessary code can be used all over the place and make a significant difference to the speed of an App.</P>
<P><H1><A NAME="database7">First access to any table is very slow</P></A></H1>
<P><I>From: "Jim O'Flaherty" <jimo@sequel.com></I></P>
This 'problem' may come from the fact that the BDE must query the DB to get
table information before working with the table the first time. Once it
has the information, it is able to cache it and will work quickly
throughout the remainder of the session (while TDatabase.Connection remains
True). To use the cached information between runs, goto the BDE config
program to the particular alias you are using to connect through and set
BDE CACHE = TRUE and BDE CACHE DIR = 'C:\temp' or wherever you want the
files to be stored.<P>
NOTE: Be aware that if you change your table definition, you will need to
delete the file in this Cache dir that represents it. You can find the
filename in the SCache.INI file located in the same directory by viewing it
in your favorite text editor.<P>
<H1><A NAME="database8">db file at run-time</A></H1>
<EM>From: Wayne Ransier <vsense@ime.net></EM>
I got this from Lloyd's help file:
<A HREF="http://www.borland.com/TechInfo/delphi/whatsnew/dwnloads.html">http://www.borland.com/TechInfo/delphi/whatsnew/dwnloads.html</A> <p>
<HR><PRE>uses DB, DBTables, StdCtrls;
procedure TForm1.Button1Click(Sender: TObject);
var
tSource, TDest: TTable;
begin
TSource := TTable.create(self);
with TSource do begin
DatabaseName := 'dbdemos';
TableName := 'customer.db';
open;
end;
TDest := TTable.create(self);
with TDest do begin
DatabaseName := 'dbdemos';
TableName := 'MyNewTbl.db';
FieldDefs.Assign(TSource.FieldDefs);
IndexDefs.Assign(TSource.IndexDefs);
CreateTable;
end;
TSource.close;
end;
</PRE><HR>
<EM>{ This code came from Lloyd's help file! }</EM>
<H1><A NAME="database9"> Quickie DB searcher </A></H1>
<I>[Ryan Peterson, rpetersn@use.usit.net]</I><p>
Here's a quickie DB search utility. It does its work by finding a string
inside the field (it converts everything to an uppercase string, even floats).
This may be the slowest way to search, but it seems to work faster
than the other solutions I've found on the Net. And it'll hit just
about anything. For ex. say you have float field that has the
number 4.509375354, and you search for 7, you'll hit it. Also, It'll
search on more than one field at a time - handy if you have two address fields.
I'm posting this little unit because when I first started in
Delphi, one of my biggest troubles was finding a search utility and I
didn't know enough to write my own (fear struck deep into my bones).
So I hope this will help those of you who need it like I did.
It's fairly easy to understand, but if you need to know exactly
how to use it, just e-mail me personally and I'll be glad to help.
Look at the case statement to find out which field types are
supported (easy to add more). If anyone finds a bug or adds
some functionality to this code, please send it to me, I'd really
appreciate it. Thanks. <P>
<HR><PRE>
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;
{ex. of 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.
</PRE><HR>
<HR SIZE="6" COLOR="#00FF00">
<A HREF="mailto:rdb@ktibv.nl"><FONT SIZE=2>Please email me</FONT></A><FONT SIZE=2> and tell me if you liked this page.<BR>
<SCRIPT LANGUAGE="JavaScript"><!--
document.write("Last modified " + document.lastModified);
// --></SCRIPT></FONT>
<P ALIGN="CENTER"><CENTER><TABLE CELLSPACING=0 BORDER=0>
<TR><TD VALIGN="MIDDLE">
<P><FONT SIZE=2>This page has been created with </FONT></TD>
<TD VALIGN="MIDDLE">
<P><A HREF="http://www.dexnet.com./homesite.html"><IMG SRC="../images/hslogo.gif" BORDER=0 WIDTH=144 HEIGHT=64></A></TD>
</TR>
</TABLE>
</CENTER></P>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -