Delphi中DBGrid 应用全书

 

DelphiDBGrid 应用全书()

[ 作者:佚名    转贴自:本站原创    点击数:3340    更新时间: 2004-11-21     文章录入:luokang

 

    Delphi 语言的数据库编程中,DBGrid 是显示数据的主要手段之一。但是 DBGrid 缺省的外观未免显得单调和缺乏创意。其实,我们完全可以在我们的程序中通过编程来达到美化DBGrid 外观的目的。通过编程,我们可以改变 DBGrid 的表头、网格、网格线的前景色和背景色,以及相关的字体的大小和风格。
   
以下的示例程序演示了对 DBGrid 各属性的设置,使 Delphi 显示的表格就像网页中的表格一样漂亮美观。
   
示例程序的运行:
   
Form1 上放置 DBGrid1Query1DataSource1 三个数据库组件,设置相关的属性,使 DBGrid1 能显示表中的数据。然后,在 DBGrid1 onDrawColumnCell 事件中键入以下代码,然后运行程序,就可以看到神奇的结果了。本代码在 Windows98Delphi5.0 环境下调试通过。
procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;State: TGridDrawState);
var i :integer;
begin
  if gdSelected in State then Exit;
//
定义表头的字体和背景颜色:
    for i :=0 to (Sender as TDBGrid).Columns.Count-1 do
    begin
      (Sender as TDBGrid).Columns[i].Title.Font.Name :='
宋体'; //字体
      (Sender as TDBGrid).Columns[i].Title.Font.Size :=9; //
字体大小
      (Sender as TDBGrid).Columns[i].Title.Font.Color :=$000000ff; //
字体颜色(红色)
      (Sender as TDBGrid).Columns[i].Title.Color :=$0000ff00; //
背景色(绿色)
    end;
//
隔行改变网格背景色:
  if Query1.RecNo mod 2 = 0 then
    (Sender as TDBGrid).Canvas.Brush.Color := clInfoBk //
定义背景颜色
  else
    (Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223); //
定义背景颜色
//
定义网格线的颜色:
    DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
  with (Sender as TDBGrid).Canvas do //
cell 的边框
  begin
    Pen.Color := $00ff0000; //
定义画笔颜色(蓝色)
    MoveTo(Rect.Left, Rect.Bottom); //
画笔定位
    LineTo(Rect.Right, Rect.Bottom); //
画蓝色的横线
    Pen.Color := $0000ff00; //
定义画笔颜色(绿色)
    MoveTo(Rect.Right, Rect.Top); //
画笔定位
    LineTo(Rect.Right, Rect.Bottom); //
画绿色的竖线
  end;
end;

2.Delphi5 - 隔行改变DBGrid网格颜色

Form1 上放置 DBGrid1Query1DataSource1 三个数据库组件,设置相关的属性,使 DBGrid1 能显示表中的数据。然后,在 DBGrid1 onDrawColumnCell 事件中键入以下代码,然后运行程序
 procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
 DataCol: Integer; Column: TColumn; State: TGridDrawState);
var i:integer;
begin
  if gdSelected in State then Exit;  //
隔行改变网格背景色:
    if adoQuery1.RecNo mod 2 = 0 then
      (Sender as TDBGrid).Canvas.Brush.Color := clinfobk //
定义背景颜色
  else
    (Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223);  //
定义背景颜色
 //
定义网格线的颜色:
  DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
  with (Sender as TDBGrid).Canvas do //
cell 的边框
  begin
    Pen.Color := $00ff0000; //
定义画笔颜色(蓝色)
    MoveTo(Rect.Left, Rect.Bottom); //
画笔定位
    LineTo(Rect.Right, Rect.Bottom); //
画蓝色的横线
    Pen.Color := clbtnface; //
定义画笔颜色(兰色)
    MoveTo(Rect.Right, Rect.Top); //
画笔定位
    LineTo(Rect.Right, Rect.Bottom); //
画绿色
  end;
end;

3. DBGrid指定列上显示DBComboBox

设置DBGrid1OnDrawDataCell事件如下:
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);
begin
  if (gdFocused in State) then
  begin
    if (Field.FieldName = DBComboBox1.DataField ) then
    begin
      DBComboBox1.Left := Rect.Left + DBGrid1.Left;
      DBComboBox1.Top := Rect.Top + DBGrid1.top;
      DBComboBox1.Width := Rect.Right - Rect.Left;
      DBComboBox1.Height := Rect.Bottom - Rect.Top;
      DBComboBox1.Visible := True;
    end;
  end;
end;
2)
DBGrid指定单元格未获得焦点时不显示DBComboBox,设置DBGrid1OnColExit事件如下:
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then
    begin
      DBComboBox1.Visible := false;
    end;
end;
3)
、当DBGrid指定列获得焦点时DrawDataCell事件只是绘制单元格,并显示DBComboBox,但是DBComboBox并没有获得焦点,数据的输入还是在单元格上进行。在DBGrid1KeyPress事件中调用SendMessage这个 Windows API函数将数据输入传输到DBComboBox上,从而达到在DBComboBox上进行数据输入。因此还要设置KeyPress事件如下:
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if (key < > chr(9)) then
  begin
    if (DBGrid1.SelectedField.FieldName =DBComboBox1.DataField) then
    begin
      DBComboBox1.SetFocus;
      SendMessage(DBComboBox1.Handle
WM_Charword(Key)0);
    end;
  end;
end;

 

打印 TDBGrid内容----方法1
procedure PrintDbGrid(DataSet:TDataSet;DbGrid:TDbGrid;Title:String);
var
PointX,PointY:integer;
 ScreenX:integer;
 i,lx,ly:integer;
 px1,py1,px2,py2:integer;
 RowPerPage,RowPrinted:integer;
 ScaleX:Real;
 THeight:integer;
 TitleWidth:integer;
 SumWidth:integer;
 PageCount:integer;
 SpaceX,SpaceY:integer;
 RowCount:integer;
begin
PointX:=Round(GetDeviceCaps(printer.Handle,LOGPIXELSX)/2.54);
PointY:=Round(GetDeviceCaps(printer.Handle,LOGPIXELSY)/2.54);
 ScreenX:=Round(Screen.PixelsPerInch/2.54);
ScaleX:=PointX/ScreenX;
 RowPrinted:=0;
 SumWidth:=0;
 printer.BeginDoc;
 With Printer.Canvas do
 begin
  DataSet.DisableControls;
   DataSet.First ;
   THeight:=Round(TextHeight('
')*1.5);//设定每行高度为字符高的1.5
   SpaceY:= Round(TextHeight('
')/4);
   SpaceX:=Round(TextWidth('
')/4);
   RowPerpage:=Round((printer.PageHeight-5*PointY)/THeight); //
上下边缘各 2厘米
   ly:=2*PointY;
   PageCount:=0;
  while not DataSet.Eof do
   begin
    if (RowPrinted=RowPerPage) or (RowPrinted=0) then
     begin
      if RowPrinted<>0 then
      Printer.NewPage;
       RowPrinted:=0;
       PageCount:=PageCount+1;
       Font.Name:='
宋体';
       Font.size:=16;
       Font.Style:=Font.Style+[fsBold];
       lx:=Round((Printer.PageWidth-TextWidth(Title))/2);
       ly:=2*PointY;
       TextOut(lx,ly,Title);
       Font.Size:=11;
       Font.Style:=Font.Style-[fsBold];
       lx:=Printer.PageWidth-5*PointX;
       ly:=Round(2*PointY+0.2*PointY);
       if RowPerPage*PageCount>DataSet.RecordCount then
        RowCount:=DataSet.RecordCount
       else
       RowCount:=RowPerPage*PageCount;
       TextOut(lx,ly,'
'+IntToStr(RowPerPage*(PageCount-1)+1)+'-'+IntToStr(RowCount)+'条,共'+IntToStr(DataSet.RecordCount)+'');
       lx:=2*PointX;
       ly:=ly+THeight*2;
       py1:=ly-SpaceY;
       if RowCount=DataSet.RecordCount then
        py2:=py1+THeight*(RowCount-RowPerPage*(PageCount-1)+1)
       else
        py2:=py1+THeight*(RowPerPage+1);
       SumWidth:=lx;
       for i:=0 to DBGrid.Columns.Count-1 do
       begin
       px1:=SumWidth-SpaceX;
         px2:=SumWidth;
         MoveTo(px1,py1);
         LineTo(px2,py2);
         TitleWidth:=TextWidth(DBGrid.Columns[i].Title.Caption);
         lx:=Round(SumWidth+(DBGrid.Columns[i].width*scaleX-titleWidth)/2);
         TextOut(lx,ly,DBGrid.Columns[i].Title.Caption);
         SumWidth:=Round(SumWidth+DBGrid.Columns[i].width*scaleX)+SpaceX*2;
       end;
       px1:=SumWidth;      //
画最后一条竖线
       px2:=SumWidth;
       MoveTo(px1,py1);
       LineTo(px2,py2);
       px1:=2*PointX;            //
画第一条横线
     px2:=SumWidth;
      py1:=ly-SpaceY;
      py2:=ly-SpaceY;
       MoveTo(px1,py1);
       LineTo(px2,py2);
       py1:=py1+THeight;
       py2:=py2+THeight;
       MoveTo(px1,py1);
       LineTo(px2,py2);
     end;
   lx:=2*PointX;
     ly:=ly+THeight;
     px1:=lx;
     px2:=SumWidth;
     py1:=ly-SpaceY+THeight;
     py2:=ly-SpaceY+THeight;
     MoveTo(px1,py1);
     LineTo(px2,py2);
     for i:=0 to DBGrid.Columns.Count-1 do
     begin
       TextOut(lx,ly,DataSet.FieldByname(DBGrid.Columns[i].Fieldname).AsString);
       lx:=Round(lx+DBGrid.Columns[i].width*ScaleX+SpaceX*2);
     end;
     RowPrinted:=RowPrinted+1;
     DataSet.next;
   end;
   DataSet.first;
   DataSet.EnableControls;
 end;
 printer.EndDoc;
end;

 

 

 

DBGrid输出到Excel表格---方法一
(支持多Sheet{
功能描述:把DBGrid输出到Excel表格(支持多Sheet
调用格式:CopyDbDataToExcel([DBGrid1, DBGrid2]);
}

procedure CopyDbDataToExcel(Args: array of const);
var
  iCount, jCount: Integer;
  XLApp: Variant;
  Sheet: Variant;
  I: Integer;
begin
  Screen.Cursor := crHourGlass;
  if not VarIsEmpty(XLApp) then
  begin
    XLApp.DisplayAlerts := False;
    XLApp.Quit;
    VarClear(XLApp);
  end;

  try
    XLApp := CreateOleObject(
Excel.Application);
  except
    Screen.Cursor := crDefault;
    Exit;
  end;

  XLApp.WorkBooks.Add;
  XLApp.SheetsInNewWorkbook := High(Args) + 1;

  for I := Low(Args) to High(Args) do
  begin
    XLApp.WorkBooks[1].WorkSheets[I+1].Name := TDBGrid(Args[I].VObject).Name;
    Sheet := XLApp.Workbooks[1].WorkSheets[TDBGrid(Args[I].VObject).Name];

    if not TDBGrid(Args[I].VObject).DataSource.DataSet.Active then
    begin
      Screen.Cursor := crDefault;
      Exit;
    end;

    TDBGrid(Args[I].VObject).DataSource.DataSet.first;
    for iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do
      Sheet.Cells[1, iCount + 1] :=
    TDBGrid(Args[I].VObject).Columns.Items[iCount].Title.Caption;

    jCount := 1;
    while not TDBGrid(Args[I].VObject).DataSource.DataSet.Eof do
    begin
      for iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do
        Sheet.Cells[jCount + 1, iCount + 1] :=
      TDBGrid(Args[I].VObject).Columns.Items[iCount].Field.AsString;

      Inc(jCount);
      TDBGrid(Args[I].VObject).DataSource.DataSet.Next;
    end;
    XlApp.Visible := True;
  end;
  Screen.Cursor := crDefault;
end;
dbgrid
的數據導入到excel中---方法二

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids, DBGrids, Db, DBTables, Excel97, OleServer, Word97;


type
  TForm1 = class(TForm)
    ExcelApplication1: TExcelApplication;
    ExcelWorkbook1: TExcelWorkbook;
    ExcelWorksheet1: TExcelWorksheet;
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Button1: TButton;
    Button4: TButton;
    WordApplication1: TWordApplication;
    WordDocument1: TWordDocument;
    procedure Button1Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  i, row, column: integer;
begin
  Try
    ExcelApplication1.Connect;
  Except
    MessageDlg('Excel may not be installed',
      mtError, [mbOk], 0);
    Abort;
  End;
  ExcelApplication1.Visible[0] := True;
  ExcelApplication1.Caption := 'Excel Application';
  ExcelApplication1.Workbooks.Add(Null, 0);
  ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[1]);
  ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Worksheets[1] as _Worksheet);
  DBGrid.DataSource.DataSet.Open;
  row := 1;
  While Not (DBGrid.DataSource.DataSet.Eof) do
  begin
    column := 1;
    for i := 1 to DBGrid.DataSource.DataSet.FieldCount do
    begin
      ExcelWorksheet1.Cells.Item[row, column] := DBGrid.DataSource.DataSet.fields[i - 1].AsString;
      column := column + 1;
    end;
    DBGrid.DataSource.DataSet.Next;
    row := row + 1;
  end;
end;

 

procedure TForm1.Button4Click(Sender: TObject);
begin
  ExcelApplication1.Disconnect;
  ExcelApplication1.Quit;
end;

end.
一个将dbgrid导为excel文件的过程,需要引用单元comoby,一个ExcelApplication1控件:

procedure CopyDbDataToExcel(Target: TDbgrid);
var
iCount, jCount: Integer;
XLApp: Variant;
Sheet: Variant;
begin
Screen.Cursor := crHourGlass;
if not VarIsEmpty(XLApp) then
begin
XLApp.DisplayAlerts := False;
XLApp.Quit;
VarClear(XLApp);
end;
//
通过ole创建Excel对象
try
XLApp := CreateOleObject('Excel.Application');
except
Screen.Cursor := crDefault;
Exit;
end;
XLApp.WorkBooks.Add[XLWBatWorksheet];
XLApp.WorkBooks[1].WorkSheets[1].Name := '
测试工作薄
';
Sheet := XLApp.Workbooks[1].WorkSheets['
测试工作薄
'];
if not Target.DataSource.DataSet.Active then
begin
Screen.Cursor := crDefault;
Exit;
end;
Target.DataSource.DataSet.first;

for iCount := 0 to Target.Columns.Count - 1 do
begin
Sheet.cells[1, iCount + 1] := Target.Columns.Items[iCount].Title.Caption;
end;
jCount := 1;
while not Target.DataSource.DataSet.Eof do
begin
for iCount := 0 to Target.Columns.Count - 1 do
begin
Sheet.cells[jCount + 1, iCount + 1] := Target.Columns.Items[iCount].Field.AsString;
end;
Inc(jCount);
Target.DataSource.DataSet.Next;
end;
XlApp.Visible := True;
Screen.Cursor := crDefault;
end;

//调用
procedure TForm2.SpeedButton5Click(Sender: TObject);
begin
copyDbDataToExcel(dbgrid1);
end;
DBGrid导入Excel---方法四
uses DBGrids,ComObj,db;

Function PDBGridExportToExcel(Dbgrid:tdbgrid;title:string):boolean;
const
{ XlSheetType }
  xlChart = -4109;
  xlDialogSheet = -4116;
  xlExcel4IntlMacroSheet = 4;
  xlExcel4MacroSheet = 3;
  xlWorksheet = -4167;
{ XlWBATemplate }
  xlWBATChart = -4109;
  xlWBATExcel4IntlMacroSheet = 4;
  xlWBATExcel4MacroSheet = 3;
  xlWBATWorksheet = -4167;
{ HorizontalAlignment}
  xlLeft=1;
  xlCenter=-4108;
  xlRight=-4152;
const
  MinColumnWidth=8;  //
转入Excel中每栏最小宽度
var
 XL:variant;
 i,j:integer;
begin
  result:=false;
  if not assigned(dbgrid.DataSource) then exit;
  if not assigned(dbgrid.DataSource.DataSet) then exit;
  if not dbgrid.DataSource.DataSet.active then exit;

TRY
  TRY
      XL:=CreateOLEObject('Excel.Application');
      XL.Visible := True;
      XL.Workbooks.Add(xlWBatWorkSheet);
      XL.ActiveWorkbook.ActiveSheet.Name:=title;

      with dbgrid do
      begin
       dbgrid.DataSource.DataSet.DisableControls;
       for i:=0 to Columns.Count-1 do
       begin
        XL.ActiveWorkbook.ActiveSheet.cells[1,i+1].value:=Columns[i].Title.Caption;

        //设定列宽
        if (not Columns[i].Visible)or(Columns[i].Field=nil) then
           XL.ActiveWorkbook.ActiveSheet.Columns[i+1].ColumnWidth:=0
        else if Columns[i].Width<MinColumnWidth then
           XL.ActiveWorkbook.ActiveSheet.Columns[i+1].ColumnWidth:=MinColumnWidth  div 5
        else
           XL.ActiveWorkbook.ActiveSheet.Columns[i+1].ColumnWidth:=Columns[i].Width div 5;

        //设定列格式
        if (Columns[i].Field<>nil) then begin
          if Columns[i].Field.DataType=ftString then
            XL.ActiveWorkbook.ActiveSheet.Columns[i+1].NumberFormatLocal:='@'
          else
            XL.ActiveWorkbook.ActiveSheet.Columns[i+1].NumberFormatLocal:='G/
通用格式';
        end;
       end;//with
       XL.ActiveWorkbook.ActiveSheet.Rows[1].HorizontalAlignment:=xlCenter;

       DataSource.DataSet.First;
       j:=1;
       while not DataSource.DataSet.eof do
       begin
         j:=j+1;
         XL.ActiveWorkbook.ActiveSheet.rows[j].select;
         for i:=0 to Columns.Count-1 do
           if (Columns[i].Field<>nil) then
           XL.ActiveWorkbook.ActiveSheet.cells[j,i+1].Value:=Columns[i].Field.AsString;
         DataSource.DataSet.Next;
       end;//while
      end;//with
      result:=true;
  EXCEPT
      result:=false;
  END;//TRY
FINALLY
  dbgrid.datasource.dataset.EnableControls;
END;//TRY
end;//DBToExcel

DbGrid控件的标题栏弹出菜单
procedure TFrmOrderPost.DbgOrderPostMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  CurPost:TPoint;
begin
  GetCursorPos(CurPost);//
获得鼠标当前坐标
  if (y<=17) and (x<=vCurRect.Right) then
  begin
    if button=mbright then
    begin
      PmTitle.Popup(CurPost.x,CurPost.y);
    end;
  end;
end;
//vCurRect
该变量在DbGridDrawColumnCell事件中获得
{procedure TFrmOrderPost.DbgOrderPostDrawColumnCell(Sender: TObject;const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  vCurRect:=Rect;//vCurRect
在实现部分定义
end;}
如何将几个DBGRID里的内容导入同一个EXCEL表中?
在软件实际制作中,为节省开发成本和开发周期,一些软件人员通常会吧DBGrid中的数据直接导出到Excel表中,而先前能看到的函数仅仅只能在WorkBook的一个Sheet中导入数据,不支持多Sheet!。

单元应用:

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, DBTables, Grids, DBGrids, ActiveX, ComObj,
Excel2000, OleServer;

测试环境:

  OSWin2k ProExcel2kDelphi6.0

源程序:  

{
功能描述:把DBGrid输出到Excel表格(支持多Sheet
设计:CoolSlob
日期: 2002-10-23
支持:
CoolSlob@163.com
调用格式:CopyDbDataToExcel([DBGrid1, DBGrid2]);
}

procedure CopyDbDataToExcel(Args: array of const);
var
  iCount, jCount: Integer;
  XLApp: Variant;
  Sheet: Variant;
  I: Integer;
begin
  Screen.Cursor := crHourGlass;
  if not VarIsEmpty(XLApp) then
  begin
    XLApp.DisplayAlerts := False;
    XLApp.Quit;
    VarClear(XLApp);
  end;

  try
    XLApp := CreateOleObject(
Excel.Application);
  except
    Screen.Cursor := crDefault;
  Exit;
  end;

  XLApp.WorkBooks.Add;
  XLApp.SheetsInNewWorkbook := High(Args) + 1;

  for I := Low(Args) to High(Args) do
  begin
    XLApp.WorkBooks[1].WorkSheets[I+1].Name := TDBGrid(Args[I].VObject).Name;
    Sheet := XLApp.Workbooks[1].WorkSheets[TDBGrid(Args[I].VObject).Name];

    if not TDBGrid(Args[I].VObject).DataSource.DataSet.Active then
    begin
      Screen.Cursor := crDefault;
      Exit;
    end;

    TDBGrid(Args[I].VObject).DataSource.DataSet.first;
    for iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do
      Sheet.Cells[1, iCount + 1] := TDBGrid(Args[I].VObject).Columns.Items[iCount].Title.Caption;

    jCount := 1;
    while not TDBGrid(Args[I].VObject).DataSource.DataSet.Eof do
    begin
      for iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do
        Sheet.Cells[jCount + 1, iCount + 1] := TDBGrid(Args[I].VObject).Columns.Items[iCount].Field.AsString;

      Inc(jCount);
      TDBGrid(Args[I].VObject).DataSource.DataSet.Next;
    end;
  end;

  XlApp.Visible := True;
  Screen.Cursor := crDefault;
end;

 怎样在DbGrid的左边,实现像EXCEL那样的自动编号?这些编号与表无关
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 Grids, DBGrids, StdCtrls, Buttons, Db, DBTables, ExtCtrls, jpeg;
const ROWCNT=20;

type
    tmygrid=class(tdbgrid)
    protected
      procedure Paint;override;
      procedure DrawCell(ACol:Integer;ARow:Integer;ARect:TRect;AState:TGridDrawState);override;
    public
      constructor create(AOwner:TComponent);override;
      destructor  destroy;override;
    end;

 TForm1 = class(TForm)
   BitBtn1: TBitBtn;
   DataSource1: TDataSource;
   Table1: TTable;
   procedure BitBtn1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 mygrid:tmygrid;
implementation

{$R *.DFM}

    {tmygrid}
    constructor tmygrid.create(AOwner:TComponent);
    begin
       inherited create(Owner);
       RowCount:=ROWCNT;
    end;

    destructor tmygrid.destroy;
    begin
      inherited;
    end;

    procedure tmygrid.Paint;
    begin
      RowCount:=ROWCNT;
      if dgIndicator in options then
         ColWidths[0]:=30;
      inherited;
    end;

    procedure tmygrid.DrawCell(ACol:Integer;ARow:Integer;ARect:TRect;AState:TGridDrawState);
    begin
      inherited;
      if (ARow>=1) and (ACol=0) then
         Canvas.TextRect(ARect,ARect.Left,ARect.Top,IntToSTr(ARow));
   end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 mygrid:=tmygrid.create(Self);
 mygrid.parent:=self;
 mygrid.left:=0;
 mygrid.top:=0;
 mygrid.Height:=300;
 mygrid.DataSource:=DataSource1;
end;

end.

DBGrid中,怎样才能让我能点击一个单元格选择整行,又可以编辑单元格的内容呢?
在设计过程中,有时候数据较大量,field 较多的时候,只是点击单元格可能会对某个field的数据误操作(如数据错行),为此才会想到这个问题,解决办法如下:
   
点击单元格就改当前行颜色。这个办法也算是没办法的办法吧!

type
 TMyDBGrid=class(TDBGrid);
//
//DBGrid1.Options->dgEditing=True
//DBGrid1.Options->dgRowSelect=False
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
 DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
 with TMyDBGrid(Sender) do
 begin
   if DataLink.ActiveRecord=Row-1 then
   begin
     Canvas.Font.Color:=clWhite;
     Canvas.Brush.Color:=$00800040;
   end
   else
   begin
     Canvas.Brush.Color:=Color;
     Canvas.Font.Color:=Font.Color;
   end;
   DefaultDrawColumnCell(Rect,DataCol,Column,State);
 end;
end;

测试通过(d7)!

有关双击dbgrid排序的问题(想让用户双击dbgird控件的某一个字段时就升序,再双击就降序....?
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
 temp, title: string;
begin
 temp := Column.FieldName;
 qusp.Close;
 if Column.Index <> lastcolumn then
 begin
   if (Pos('
', DBGrid1.Columns[LastColumn].Title.Caption) > 0) or (Pos('', DBGrid1.Columns[LastColumn].Title.Caption) > 0) then
     DBGrid1.Columns[LastColumn].Title.Caption := Copy(DBGrid1.Columns[LastColumn].Title.Caption, 3, Length(DBGrid1.Columns[LastColumn].Title.Caption) - 2);
   qusp.Sql[icount] := 'order by ' + temp + ' asc';
   DBGrid1.Columns[Column.Index].Title.Caption := '
' + DBGrid1.Columns[Column.Index].Title.Caption;
   lastcolumn := column.Index;
 end
 else
 begin
   LastColumn := Column.Index;
   title := DBGrid1.Columns[LastColumn].Title.Caption;
   if Pos('
', title) > 0 then
   begin
     qusp.Sql[icount] := 'order by ' + temp + ' desc';
     Delete(title, 1, 2);
     DBGrid1.Columns[LastColumn].Title.Caption := '
' + title;
   end
   else if Pos('
', title) > 0 then
   begin
     qusp.Sql[icount] := 'order by ' + temp + ' asc';
     Delete(title, 1, 2);
     DBGrid1.Columns[LastColumn].Title.Caption := '
' + title;
   end
   else
   begin
     qusp.Sql[icount] := 'order by ' + temp + ' asc';
     DBGrid1.Columns[LastColumn].Title.Caption := '
' + title;
   end;
 end;
 qusp.Open;
end;

 

 DbGrid控件隐藏或显示标题栏DbGrid控件隐藏或显示标题栏

1
、 新建一个带两个参数的过程(1个参数是菜单对象,第2 个是DbGrid控件):
    Procedure ViewTitle(Sender:TObject;DbgColumns:TDBGrid);
    //
隐藏或显示DbGrid标题栏

  2、 然后按Ctrl+Shift+C组合键,定义的过程会在实现部分出现。
    Procedure FrmStock.ViewTitle(Sender:TObject;DbgColumns:TDBGrid);
    begin
      With (Sender as TMenuItem) do
      begin
        Checked:=not Checked;
        DbgColumns.Columns[Tag].Visible:=Checked;
      end;
    end;

  3、 把菜单子项的Tag设置成跟DbGridColumns值相对应,比如:
    DbGrid
有一个标题栏是‘日期‘在第0,然后把要触法该列的菜单的Tag设置成0

  4、 把菜单的onClick事件选择ViewTitle该过程。
 
  DBGrid
对非布尔字段的栏中如何出现 CheckBox 选择输入可将dbgrid关联的dataset中需显示特殊内容字段设为显式字段
OnGetText事件中写如下代码:
table举例:
procedure TForm1.Table1Myfield1GetText(Sender: TField;
 var Text: String; DisplayText: Boolean);
var Pd:string;
begin
 inherited;
 pd:=table1.fieldbyname('myfield1').asstring;
 if pd='1' then
     Text:='
'
 else
     if pd='2' then
        text:='
'
     else
        Text:='
';
end;


dbgrid dbgrideh 如何让所显示数据自动滚动?

procedure TForm1.Timer1Timer(Sender: TObject);
var
m:tmessage;
begin
 m.Msg:=WM_VSCROLL;
 m.WParamLo:=SB_LINEDOWN;
 m.WParamHi:=1 ;
 m.LParam:=0;
 postmessage(self.DBGrid1.Handle,m.Msg,m.WParam,m.LParam);

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
self.Timer1.Enabled:=true;
end; 

如果需要让他自动不断地从头到尾滚动,添加如下代码
if table1.Eof then table1.First;  

关于DBGrid中下拉列表的两种设计比较

一、DBGrid 中 的 下 拉 列 表
   
DBGrid 网格中实现下拉列表,设置好 DBGrid 中该字段的 PickList 字符串列表、初始的序号值 DropDownRows 即可。以职工信息库中的籍贯字段(字符串类型)为例,具体设计步骤如下:
    1
、在窗体上放置 Table1DataSource1DBGrid1DBNavigator1 等控件对象,按下表设置各个对象的属性:

---------------------------------------
对象           属性          设定值
---------------------------------------
Table1         DataBase      sy1
               TableName     zgk.dbf //
职工信息库
               DataSource1   DataSet Table1
DbGrid1        DataSource    DataSource1
DBNavigator1   DataSource    Datasource1
-------------------------------------------

    2、双击 Table1,在弹出的 Form1.Table1 窗口中,用右键弹出快捷菜单,单击 Add Fields 菜单项;选择所有的字段后,按 OK 按钮。

    3、修改第 2 步新增字段的 DisplayLabel 属性。以 Table1ZGBH 字段为例, 在 Object Inspector 窗口中选择 Table1ZGBH,修改属性 DisplayLabel= 职工编号,其余字段类似。
 
    4
、双击 DBGrid1,在弹出的 Editing DBGrid1.Columns 窗口中, 单击 Add all Fields 按钮,增加 Table1 的所有字段。

    5、在 Editing DBGrid1.Columns 窗口,选择 jg 这一行,切换到 Object Inspector 窗口,修改它的 PickList.Strings
“湖北枝江市
 
北京市
 
河南平顶山市
 
浙江德清市”

    6、在 Form1.Oncreate 事件中写入语句:

    Table1.Open;

    7F9 运行,用鼠标点击某个记录的籍贯字段,右边即出现一个按钮,点击这个按钮,可出现一个下拉列表,包含第 5 步中输入的四行字符串,可用鼠标进行选择。当然也可以自行输入一个并不属下拉列表中的字符串。


二、DBGrid 中 的 查 找 字 段
   
所谓查找字段(LookUp Field),即 DBGrid中的某个关键字段的数值来源于另外一个数据库的相应字段。运用查找字段技术,不仅可以有效的避免输入错误,而且 DBGrid 的显示方式更为灵活,可以不显示关键字段,而显示源数据库中相对应的另外一个字段的数据。

    例如,我们在 DBGrid 中显示和编辑职工信息,包括职工编号、职工姓名、籍贯、所在单位编号,而单位编号来源于另一个数据库表格——单位库,称“单位编号”为关键字段。如果我们直接显示和编辑单位编号的话,将会面对 123 等非常不直观的数字,编辑时极易出错。但是如果显示和编辑的是单位库中对应的单位名称话,将非常直观。这就是 DBGrid 的所支持的查找字段带来的好处。

    实现 DBGrid 的查找字段同样不需要任何语句,具体设计步骤如下:
    1
、在窗体上放置 Table1Table2DataSource1DBGrid1DBNavigator1 等控件对象,按下表设置各个对象的属性:
---------------------------------------
对象         属性        设定值

---------------------------------------
Table1       DataBase    sy1
             TableName   zgk.dbf //
职工信息库
Table2       DataBase    sy1
             TablenAME   dwk.dbf //
单位信息库
DataSource1  DataSet     Table1
DbGrid1      DataSource  DataSource1
DBNavigator1 DataSource  Datasource1
------------------------------------------

    2、双击Table1,在弹出的 Form1.Table1 窗口中,用右键弹出快捷菜单,单击 Add Fields 菜单项;选择所有的字段后,按 OK 按钮。

    3、修改第 2 步新增字段的 DisplayLabel 属性。以 Table1ZGBH 字段为例,在 Object Inspector 窗口中选择 Table1ZGBH,修改属性 DisplayLabel= 职工编号,其余字段类似。

    4、设置 Table1DWBH.Visible=False

    5、在 Form1.Table1 窗口,用右键弹出快捷菜单,单击 New Field 菜单项,新增一个查找字段 DWMC,在弹出的窗口设置相应的属性,按 OK 按钮确认;在 Object Inspector 窗口,设置 Table1DWMC.DisplayLabel= 单位名称。

     6、在 Form1.Oncreate 事件中写入语句:
     Table1.Open;

     7、按 F9 运行,当光标移至某个记录的单位名称字段时,用鼠标点击该字段,即出现一个下拉列表,点击右边的下箭头,可在下拉列表中进行选择。在这里可以看出,下拉列表的内容来自于单位信息库,并且不能输入其他内容。


    三、DBGrid 中的下拉列表和查找字段的区别
   
虽然 DBGrid 中的下拉列表和查找字段,都是以下拉列表的形式出现的,但两者有很大的差别。

    1、用 PickList 属性设置的下拉列表,它的数据是手工输入的,虽然也可以在程序中修改,但动态特性显然不如直接由另外数据库表格提取数据的查找字段。

    2、用 PickList 属性设置的下拉列表,允许输入不属于下拉列表中的数据,但查找字段中只能输入源数据库中关键字段中的数据,这样更能保证数据的完整性。

    3、用 PickList 属性设置的下拉列表设计较为简单。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值