`
阿尔萨斯
  • 浏览: 4168755 次
社区版块
存档分类
最新评论

StringGrid操作大全

 
阅读更多

(1)正确地设置StringGrid列宽而不截断任何一个文字方法是在对StringGrid填充完文本串后调用SetOptimalGridCellWidth过程
-----------程序片断-------------------------------------------------
(*
$Header$
Module Name : General/BSGrids.pas
Main Program : Several.
Description : StringGrid support functions.
03/21/2000 enhanced by William Sorensen
*)

unit BSGrids;

interface

uses
Grids;

type
TExcludeColumns = set of 0..255;
procedure SetOptimalGridCellWidth(sg: TStringGrid;
ExcludeColumns: TExcludeColumns);
// Sets column widths of a StringGrid to avoid truncation of text.
// Fill grid with desired text strings first.
// If a column contains no text, DefaultColWidth will be used.
// Pass [] for ExcludeColumns to process all columns, including Fixed.
// Columns whose numbers (0-based) are specified in ExcludeColumns will not
// have their widths adjusted.

implementation

uses
Math; // we need the Max function
procedure SetOptimalGridCellWidth(sg: TStringGrid;
ExcludeColumns: TExcludeColumns);

var
i : Integer;
j : Integer;
max_width : Integer;
begin
with sg do
begin
// If the grid's Paint method hasn't been called yet,
// the grid's canvas won't use the right font for TextWidth.
// (TCustomGrid.Paint normally sets this, under DrawCells.)
Canvas.Font.Assign(Font);
for i := 0 to (ColCount - 1) do
begin
if i in ExcludeColumns then
Continue;
max_width := 0;
// Search for the maximal Text width of the current column.
for j := 0 to (RowCount - 1) do
max_width := Math.Max(max_width,Canvas.TextWidth(Cells[i,j]));
// The hardcode of 4 is based on twice the offset from the left
// margin in TStringGrid.DrawCell. GridLineWidth is not relevant.
if max_width > 0 then
ColWidths[i] := max_width + 4
else
ColWidths[i] := DefaultColWidth;
end; { for }
end;
end;

end.
(2)实现StringGrid的删除,插入,排序行操作(基本操作啦)//实现删除操作
Procedure GridRemoveColumn(StrGrid: TStringGrid; DelColumn: Integer);
Var Column: Integer;
begin
If DelColumn <= StrGrid.ColCount then
Begin
For Column := DelColumn To StrGrid.ColCount-1 do
StrGrid.Cols[Column-1].Assign(StrGrid.Cols[Column]);
StrGrid.ColCount := StrGrid.ColCount-1;
End;
end;

//实现添加插入操作
Procedure GridAddColumn(StrGrid: TStringGrid; NewColumn: Integer);
Var Column: Integer;
begin
StrGrid.ColCount := StrGrid.ColCount+1;
For Column := StrGrid.ColCount-1 downto NewColumn do
StrGrid.Cols[Column].Assign(StrGrid.Cols[Column-1]);
StrGrid.Cols[NewColumn-1].Text := '';
end;

//实现排序操作
Procedure GridSort(StrGrid: TStringGrid; NoColumn: Integer);
Var Line, PosActual: Integer;
Row: TStrings;
begin
Renglon := TStringList.Create;
For Line := 1 to StrGrid.RowCount-1 do
Begin
PosActual := Line;
Row.Assign(TStringlist(StrGrid.Rows[PosActual]));
While True do
Begin
If (PosActual = 0) Or (StrToInt(Row.Strings[NoColumn-1]) >= StrToInt(StrGrid.Cells[NoColumn-1,PosActual-1])) then
Break;
StrGrid.Rows[PosActual] := StrGrid.Rows[PosActual-1];
Dec(PosActual);
End;
If StrToInt(Row.Strings[NoColumn-1]) < StrToInt(StrGrid.Cells[NoColumn-1,PosActual]) then
StrGrid.Rows[PosActual] := Row;
End;
Renglon.Free;
end;
(3) TstringGrid 的行列合并研究
unit Unit1;

//建立一工程,
//粘贴本单元代码即可看 STringGrid 行列合并效果
//但发现非固定行非固定列的合并效果不好
interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, ADODB, DBTables, Grids;//注意这里要引用

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure SGDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure SGTopLeftChanged(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

// 以下 StringGrid 为固定行,固定列的合并所必须进行的处理
// 非固定行,非固定列的合并效果不好
var
sg:TStringGrid;
procedure TForm1.FormCreate(Sender: TObject);
var
i,j:integer ;
begin
Sg:=TStringGrid.Create(self);

with SG do
begin
parent:=self;
align:=alclient;
DefaultDrawing:=false;
FixedColor:=clYellow;
RowCount:=30;
ColCount:=20;
FixedCols:=1;
FixedRows:=1;
GridLineWidth:=0;
Options:=Options+[goEditing]-[goVertLine,goHorzLine,goRangeSelect];
OnDrawCell:=SGDrawCell;
OnTopLeftChanged:=SGTopLeftChanged;
Canvas.Font.name:='宋体';
Canvas.Font.Size:=10;

for i:=0 to colCount-1 do
for j:=0 to RowCount-1 do
cells[i,j]:=Format('%d行%d列',[j,i]);

for i:=0 to colCount-1 do
cells[i,0]:=Format('第%d列',[i]);
for i:=0 to RowCount-1 do
cells[0,i]:=Format('第%d行',[i]);

Cells[0,0]:=' 左上角';
Cells[1,0]:='AA这是列合并BB';
Cells[0,1]:='A这是行'#10'合并BB';
Cells[1,1]:='1111111';
Cells[1,2]:='1111222';
Cells[2,1]:='2222111';
Cells[2,2]:='2222222';
end;
end;

//重载 OnDrawCell 事件
procedure TForm1.SGDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
r:TRect;
d:TStringGrid;
s:string;
ts:TStrings;
i,n:integer;
fixed:Boolean;
begin
d:=TStringGrid(sender);
if (Acol=2) and (ARow=0) then
begin
r.left:=Rect.left-1-d.colwidths[ACol-1];
r.top:=rect.top-1;
r.right:=rect.right;
r.bottom:=rect.bottom;
s:=d.cells[ACol-1,ARow];
end else
if (Acol=1) and (ARow=0) then
begin
r.left:=Rect.left-1;
r.top:=rect.top-1;
r.right:=rect.right+d.colwidths[ACol+1];
r.bottom:=rect.bottom;
s:=d.cells[ACol,ARow];
end //////////以上列合并
else
if (Acol=0) and (ARow=2) then
begin
r.left:=Rect.left-1;
r.top:=rect.top-1-d.RowHeights[ARow-1];
r.right:=rect.right;
r.bottom:=rect.bottom;
s:=d.cells[ACol,ARow-1];
end else
if (Acol=1) and (ARow=0) then
begin
r.left:=Rect.left-1;
r.top:=rect.top-1;
r.right:=rect.right;
r.bottom:=rect.bottom+d.RowHeights[ARow+1];
s:=d.cells[ACol,ARow];
end ////////以上为行合并
else
begin
r.left:=Rect.left-1;
r.top:=rect.top-1;
r.right:=rect.right;
r.bottom:=rect.bottom;
s:=d.cells[ACol,ARow];
end;

d.Canvas.brush.color:=d.color;
d.canvas.Font.color:=$ff0000;

Fixed:=false;
if (Arow<d.FixedRows) or (ACol<d.Fixedcols) then
begin
d.Canvas.brush.color:=d.FixedColor;
d.Canvas.Font.color:=$ff00ff;
Fixed:=True;
//d.Canvas.Font.style:=d.Canvas.Font.style+[fsBold];
end;
if gdfocused in state then
begin
d.canvas.Brush.color:=$00ff00;
end;
if fixed then
begin
d.Canvas.Pen.color:=$0;
d.canvas.Rectangle(r);

d.Canvas.Pen.color:=$f0f0f0;
d.Canvas.Pen.Width:=2;
d.canvas.Moveto(r.left+1,r.top+2);
d.canvas.Lineto(r.left+r.right,r.top+2);

d.Canvas.Pen.color:=$808080;
d.Canvas.Pen.Width:=1;
d.canvas.Moveto(r.Left+1,r.bottom-1);
d.canvas.Lineto(r.left+r.right,r.bottom-1);

end else
begin
d.Canvas.Pen.color:=$0;
d.Canvas.Pen.Width:=1;
d.canvas.Rectangle(r);
end;
n:=r.top+4;
ts:=TStringList.Create;
ts.CommaText:=s;
for i:=0 to ts.Count-1 do
begin
d.canvas.Textout(r.left+4,n,ts[i]);
inc(n,d.RowHeights[ARow]);
end;
end;

//重载 OnTopLeftChange事件,特别是行的合并
procedure TForm1.SGTopLeftChanged(Sender: TObject);
var
d:TStringGrid;
begin
d:=TStringGrid(Sender);
d.Cells[0,1]:=d.Cells[0,1];
d.Cells[0,2]:=d.Cells[0,2];
end;

end.
(4)让stringgrid点列头进行排序procedure GridQuickSort(Grid: TStringGrid; ACol: Integer; Order: Boolean ; NumOrStr: Boolean);
(******************************************************************************)
(* 函数名称:GridQuickSort *)
(* 函数功能:给 StringGrid 的 ACol 列快速法排序 _/_/ _/_/ _/_/_/_/_/ *)
(* 参数说明: _/ _/ _/ *)
(* Order: True 从小到大 _/ _/ *)
(* : False 从大到小 _/ _/ *)
(* NumOrStr : true 值的类型是Integer _/_/ _/_/ *)
(* : False 值的类型是String *)
(* 函数说明:对于日期,时间等类型数据均可按字符方式排序, *)
(* *)
(* *)(******************************************************************************)
procedure MoveStringGridData(Grid: TStringGrid; Sou,Des :Integer );
var
TmpStrList: TStringList ;
K : Integer ;
begin
try
TmpStrList :=TStringList.Create() ;
TmpStrList.Clear ;
for K := Grid.FixedCols to Grid.ColCount -1 do
TmpStrList.Add(Grid.Cells[K,Sou]) ;
Grid.Rows [Sou] := Grid.Rows [Des] ;
for K := Grid.FixedCols to Grid.ColCount -1 do
Grid.Cells [K,Des]:= TmpStrList.Strings[K] ;
finally
TmpStrList.Free ;
end;
end;

procedure QuickSort(Grid: TStringGrid; iLo, iHi: Integer);
var
Lo, Hi : Integer;
Mid: String ;
begin
Lo := iLo ;
Hi := iHi ;
Mid := Grid.Cells[ACol,(Lo + Hi) div 2];
repeat
if Order and not NumOrStr then //按正序、字符排
begin
while Grid.Cells[ACol,Lo] < Mid do Inc(Lo);
while Grid.Cells[ACol,Hi] > Mid do Dec(Hi);
end ;
if not Order and not NumOrStr then //按反序、字符排
begin
while Grid.Cells[ACol,Lo] > Mid do Inc(Lo);
while Grid.Cells[ACol,Hi] < Mid do Dec(Hi);
end;

if NumOrStr then
begin
if Grid.Cells[ACol,Lo] = '' then Grid.Cells[ACol,Lo] := '0' ;
if Grid.Cells[ACol,Hi] = '' then Grid.Cells[ACol,Hi] := '0' ;
if Mid = '' then Mid := '0' ;
if Order then
begin //按正序、数字排
while StrToFloat(Grid.Cells[ACol,Lo]) < StrToFloat(Mid) do Inc(Lo);
while StrToFloat(Grid.Cells[ACol,Hi]) > StrToFloat(Mid) do Dec(Hi);
end else
begin //按反序、数字排
while StrToFloat(Grid.Cells[ACol,Lo]) > StrToFloat(Mid) do Inc(Lo);
while StrToFloat(Grid.Cells[ACol,Hi]) < StrToFloat(Mid) do Dec(Hi);
end;
end ;
if Lo <= Hi then
begin
MoveStringGridData(Grid, Lo, Hi) ;
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then QuickSort(Grid, iLo, Hi);
if Lo < iHi then QuickSort(Grid, Lo, iHi);
end;

begin
try
QuickSort(Grid, Grid.FixedRows, Grid.RowCount - 1 ) ;
except
on E: Exception do
Application.MessageBox(Pchar('系统在排序数据的时候遇到异常:'#13+E.message+#13'请重试,如果该问题依然存在请与程序供应商联系!'),'系统错误',MB_OK+MB_ICONERROR) ;
end;
end;

procedure StringGridTitleDown(Sender: TObject;
Button: TMouseButton; X, Y: Integer);
(******************************************************************************)
(* 函数名称:StringGridTitleDown *)
(* 函数功能:取鼠标点StringGrid 的列 _/_/ _/_/ _/_/_/_/_/ *)
(* 参数说明: _/ _/ _/ *)
(* Sender _/ _/ *)
(*(*
(******************************************************************************)
var
I: Integer ;
begin
if (Y > 0 ) and (y < TStringGrid(Sender).DefaultRowHeight * TStringGrid(Sender).FixedRows ) then
begin
if Button = mbLeft then
begin
I := X div TStringGrid(Sender).DefaultColWidth ;
//这个i 就是要排序得行了
// 下面调用上面的排序函数就可以了,
GridQuickSort(TStringGrid(Sender), I, False, True) ;
end;
end;
end;

用上面的两个函数就能解决你的问题了。在TStringGrid 的MouseDown事件中调用StringGridTitleDown 函数就可以。你可能要修改一下StringGridTitleDown函数来修改排序得方式及其字符类型。
提醒你一下对于日期、时间、布尔等类型数据均可按字符方式排序。
例如:

procedure TForm_Main.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
StringGridTitleDown(Sender,Button,X,Y);
end;

分享到:
评论

相关推荐

    StringGrid使用全书

    StringGrid使用全书,详细介绍如何操作stringgrid表格。

    关于stringgrid

    写的一个小程序,操作stringgrid的.

    Dephi操作Excel类

    把一个表或Query或StringGrid中的数据保存到一个Execl文件中 Function List : 创建接口 procedure CreateExcelInstance; 把表内容放到Excel文件中 procedure TableToExcel( const Table: TTable ); 把Query...

    Delphi开发技巧之-文件操作

    Windows中的通用应用程序的类名 ...读 table-textfile 到 StringGrid 读取二进制文件使用ASCII显示 转换OEM到ANSI 转换短文件名为长文件名 运行一个程序或打开一个关联文件 返回UNC路径 通过CRC-32验证文件

    Delphi开发技巧之-VCL

    检查TMemo能否取消操作 检查TreeView是否完全展开或折叠 检查TStringGrid是否有滚动条 添加接口对象到list 清空StringGrid的所有单元 移动listbox项目 移动TListView项目 移动TRichEdit内光标到指定位置 聚焦TDBGrid...

    Delphi 使用表达式进行数据库查询操作范例.rar

    Delphi 使用表达式进行数据库查询操作范例,通过TADO为查询初始查询字段结构并将结构保存在StringGrid2中.测试用数据库在database目录中,是SQLSERVER2003格式的数据库文件。下面是摘录的一些代码片段:  ...

    Delphi工资定额计算系统.rar

    Delphi工资定额计算系统,用于劳动管理部门的工资定额计算,通过源码可以掌握以下相关的Delphi编程技术技术:数据库操作、stringgrid的大量操作应用(edit、combox计算等 )、数据报表的使用、注册表的相关操作。

    报表票据打印/建立SQL查询条件/数据功能扩张

    该套控件操作极其简单,使用极其灵活,功能极其强大,可极大的提高软件开发速度。1、打印控件: 针对票据(无),表格(TDataSet,StringGrid),文件(TStrings)而设计,可自由设置打印样式。2、报表设计器:wydReport....

    Delphi操作Excel类

    procedure GetStringGridBody(const StringGrid: TStringGrid; var Cell: Variant); protected procedure SetCellFont(NewFont: TFont); procedure SetTitleFont(NewFont: TFont); procedure SetVisible...

    劳动定额管理

    1.数据库技术 2.stringgrid的大量操作应用 加入edit、combox计算等 3.报表 4.注册表的应用 .

    一些 VCL 控件的Delphi用法示例参考.rar

     动态创建主菜单和菜单项,加速TListBox控件的填充和清空,加速TTreeView控件的填充和清空,实现.dfm文件和.txt文件的互相转换,使程序能在循环中响应界面操作,消除在TEdit控件中按下回车键时的声音,用剪贴板复制...

    Delphi 记录文件的读写.rar

    Delphi 记录文件的读写,这个程序非...在子窗口中输入数据,确定后,会将数据添加到主窗口的StringGrid中,然后通过修改命令,从StringGrid中再读取出数据,进行修改保存,演示了文件内容的读取和写入的操作过程 。

    磁盘编辑器

    在Dephi新建一个项目,在窗体上放置一个stringgrid控件,用来显示和修改磁盘扇区的内容.两个按钮,分别用来读写相应扇区.两个spinedit控件,用来设置起始扇区和读写扇区的数目.一个DriveComboBox控件,用来选择磁盘....

    C++Builder精彩编程实例集锦的源代码(4,5,6部分).rar

    实例185 如何获取操作系统的产品序列号和产品名称 实例186 如何获取和设置鼠标双击响应速度 实例187 如何弹出和关闭光驱 实例188 如何检测网络连接 实例189 如何创建拨号网络 第六部分 数据库应用 实例190 ...

    StringAlignGrid

    相當不錯的StringGrid第三方控件,可以實現對單個Row,Column,Cell的字體及其相關屬性,背景色,對齊等相關屬性的快速簡便操作。可以對控件進行可視化設置。免費控件。支持D6D7。

    C++Builder精彩编程实例集锦的源代码前3部分.rar

    实例240 如何获取StringGrid组件鼠标指定单元格的值 实例241 如何使用StringGrid组件显示数据库查询结果 实例242 如何禁止数据控制组件与数据集组件同步刷新 实例243 如何把数据库表转换成文本文件 实例244 如何...

    C++Builder精彩编程实例集锦的源代码后3部分.rar

    实例240 如何获取StringGrid组件鼠标指定单元格的值 实例241 如何使用StringGrid组件显示数据库查询结果 实例242 如何禁止数据控制组件与数据集组件同步刷新 实例243 如何把数据库表转换成文本文件 实例244 如何...

    第一部分 界面设计

    实例240 如何获取StringGrid组件鼠标指定单元格的值 实例241 如何使用StringGrid组件显示数据库查询结果 实例242 如何禁止数据控制组件与数据集组件同步刷新 实例243 如何把数据库表转换成文本文件 实例244 如何...

    delphi 开发经验技巧宝典源码

    0108 使用Odd函数改变StringGrid组件的奇偶行颜色 72 0109 使用Pred函数获取顺序类型表达式的前驱 72 0110 使用Succ函数获取顺序类型表达式的后继 73 4.4 进制转换相关函数 73 0111 如何将二进制转换为八...

Global site tag (gtag.js) - Google Analytics