优化你的Delphi程序

Author: 曾晓萌 Date: 2001年 10期

#1    1.窗口控制
      文本框Edit对回车键的响应:有时操作人员在输入数据之后(特别是用小键盘输入数值数据时),通常会习惯地打入回车键以表示确认,但是在Delphi中的Edit控件并没有专门针对回车键响应的事件。例如在一个窗口中同时有多个文本输入框Edit控件,要求逐个输入数据;一般情况下,当我们输入完第一个文本框的内容之后,必须按下Tab键或直接用鼠标点击第二个文本框才能将光标跳到第二个文本框,这样不便于快速录入数据。现在我们运用文本框对输入字符的响应事件OnKeyPress,通过SetFocus命令来实现:在第一个文本框中输入数据后,按下回车键光标将自动跳到第二个文本框。
      在Edit1的OnKeyPress事件中写入:
      procedure TForm1.Edit1KeyPress(Sender:TObject;var Key: Char);  ??
      Begin
      if Key=chr(13) then Edit2.SetFocus;//*ASCII码中的13表示回车键
      //*在Edit1中输入回车键后,激活Edit2.SetFocus,光标自动跳到Edit2
      End;??
      //*同例对Edit2、Edit3……等都采用如上方法就可以实现对回车键的响应
  #1    2.自动显示PageControl中的指定页
      当我们在一个窗口中定义一个PageControl,并在其下加入多个TabSheet页用于显示不同的信息。此时Delphi在编译程序时会自动记录下编译前所显示的是哪一页,以后当你再运行这个编译过的程序并打开此窗口时,PageContro就会自动跳到那一页上,而我们所要求的是在打开窗口的时候可以显示指定的TabSheet页。
      在窗口显示事件FormShow中加入:
      procedure TForm1.FormShow(Sender: TObject);  ??
      begin
      PageControl1.ActivePage:=TabSheet1;//*激活第一页
      end;??
  #1    3.数据库优化
      Table记录的快速查找定位:在窗口中定义了一个Table、一个DataSource和一个DBgrid用于显示并查询Table所指向数据库,一个用于编辑输入欲查找记录的关键字。一般情况下我们用do...while语句逐条对记录进行判断直到找到符合条件的记录或指针走到了数据库底部为止,但是如果被查找的数据库很大时(超过一万条记录),那么在DBGrid中每检索一条记录,DBGrid就会从头到尾不断滚屏显示直到找到后将指针定位在该记录上,这样查找的速度很慢。现在我们可以利用一个Query来对DBGrid中的数据记录指针进行快速定位。首先要对数据库中的被检索关键值进行排序,然后新建一个Query也指向该数据库,用新建的Query检索所有小于该条件的记录,这样Query所检索的结果就是符合该条件记录前的所有记录,而Query数据库的总记录个数就是查找的记录的位置,这样只要用MoveBy到Query的数据记录总数就可以使TABLE快速移到所要查找的记录上。
      在窗口中定义了Table1、DataSource1、DBGrid1分别用于指向并显示数据库A.DB,数据库A.DB中包含字段“编号”,首先对A.DB中的字段“编号”进行排序,现在我们在Edit1中输入一个编号后,要求记录指针快速地定位在指定编号的记录上。
      未使用Query用法(执行次数为符合条件记录的位置,若没找到,则是数据库的总长度):
      Table1.Open;??
      Table1.First;??
      //*逐条比较直到找到或指针走到数据库底部
      While ((not Table1.Eof) and (Table1['编号']<>Edit1.Text)) do
      Table1.Next;??
      使用Query用法:(执行次数为8)
      Query1.Close;??
      Query1.SQL.Clear;??
      //*查找所有条件小于Edit1.text内容的所有记录,记录总数就是所符合条件记录的位置
      Query1.SQL.Add('select *from trans.db where 编号<'''+edit1.text+'''' ); ??
      Query1.Open;??
      Table1.Open;??
      Table1.First;??
      Table1.Moveby(Query1.RecordCount);  ??
  #1    4.提取xxxx-xx-xx格式的日期字符串
      在数据库中有时需要将一个日期类型数据转化为一个字符串类型数据才能对日期进行排序。但是由于将日期类型直接转化为字符型时,程序会自动省略掉日期中的月、日小于10的0,例如将日期“2000-09-04”转化为字符串后会是“200094”而不是“20000904”,如果对字符串进行比较排序所得出的结果是200094<2000131,从而被认为2000-09-04小于2000-01-31而排在前面,导致排序结果错误。我们必须要想办法将2000-09-04转化为字符20000904,方法如下:
      建立一个DateTimePicker、一个Calendar(在SAMPLE页中的日历),将DateTimePicker.Date(输入日期)赋值给Calendar.CalendarDate(日历日期 ),这样就可以直接从Calendar中读取类型为整型的Year年、Month月、Day日,然后再对月、日的数值进行比较,当数值小于10时则在其前面补上0,最后将数据再转化为字符型,这样就可以把一个日期类型数据转化为标准结构的字符型数据。下例中将所需输入的日期传送给DateTimePicker,再由DateTimePicker传送给CalendarDate,然后从CalendarDate.Yeah、CalendarDate.Month、CalendarDate.Day将年、月、日转化为字符型并赋值给Label1以待使用。此例还可以应用于时间类型的转化。
      DateTimePicker.Date:=now;??
      Calendar1.CalendarDate:=DateTimePicker1.Date;??
      Dabel1.Caption:=IntToStr(Calendar1.Year);  ??
      if Calendar1.Month<10
      Then Label1.Caption:=Label1.Caption+'0'+IntToStr(Calendar1.Month)
      Else Label1.Caption:=Label1.Caption+IntToStr(Calendar1.Month); ??
      If Calendar1.Day<10
      Then Label1.Caption:=Label1.Caption+'0'+IntToStr(Calendar1.Day)
      Else Label1.Caption:=Label1.Caption+IntToStr(Calendar1.Day)
  #1    5.用不同颜色的字体显示不同条件记录
      在一个DBGrid内需要对所显示的记录根据不同的条件采用不同的字体颜色进行区分。例如在数据库中有一个记录字段“分数”,现在需要对于分数小于60的记录用红色表示,分数大于60小于90的记录用绿色表示,分数大于90小于100的记录用蓝色表示。
      在DBGrid的DBGrid1DrawColumnCell事件中加入如下语句:
      Procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;??
      DataCol: Integer; Column: TColumn; State: TGridDrawState ); ??
      Begin
      If Query1['分数']<60 Then
      DBGrid1.Canvas.Font.Color:= clred;??
      If((Query1['分数']>60) And (Query1['数量']<90 )) Then
      DBGrid1.Canvas.Font.Color:= clgreen;??
      If((Query1['分数']>90) And (Query1['数量']<100 ))Then
      DBGrid1.Canvas.Font.Color:= clblue;??
      DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State); ??
      end;??