谁知道DbiPackTable、DbiSetProp的详细用法?(200分)

  • 主题发起人 主题发起人 wjshh
  • 开始时间 开始时间
W

wjshh

Unregistered / Unconfirmed
GUEST, unregistred user!
最好给个例子。
 
没高手了吗?
 
DbiPackTable 用法如下。 DbiSetProp 没用过,应该差不多
procedure PackTable(Dir, TableName: string);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
tbl, Err: Array[0..255] of Char;
SrcTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := Dir;
SrcTbl.TableName := TableName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiPackTable(DBHandle,
nil,
StrPCopy(Tbl, Dir+'/'+TableName),
szDBASE,
true
);
if (ResultCode <> DBIERR_NONE) then
begin
DbiGetErrorString(ResultCode,Err);
raise EDatabaseError.Create('While Packing ' +
Dir + '/' + TableName + ', the database ' +
'engine generated the error '''
+ StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
end;
end;
 
在Delphi6的帮助里,有一个例子,拷贝如下:详细情况可查看帮助。
procedure PackTable(Table: TTable);
var
Props: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
begin
// Make sure the table is open exclusively so we can get the db handle...
if not Table.Active then
raise EDatabaseError.Create('Table must be opened to pack');
if not Table.Exclusive then

raise EDatabaseError.Create('Table must be opened exclusively to pack');

// Get the table properties to determine table type...
Check(DbiGetCursorProps(Table.Handle, Props));

// If the table is a Paradox table, you must call DbiDoRestructure...
if Props.szTableType = szPARADOX then begin
// Blank out the structure...
FillChar(TableDesc, sizeof(TableDesc), 0);
// Get the database handle from the table's cursor handle...

Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
// Put the table name in the table descriptor...
StrPCopy(TableDesc.szTblName, Table.TableName);
// Put the table type in the table descriptor...
StrPCopy(TableDesc.szTblType, Props.szTableType);
// Set the Pack option in the table descriptor to TRUE...
TableDesc.bPack := True;
// Close the table so the restructure can complete...
Table.Close;
// Call DbiDoRestructure...

Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, False));
end
else
// If the table is a dBASE table, simply call DbiPackTable...
if (Props.szTableType = szDBASE) then
Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))
else
// Pack only works on PAradox or dBASE; nothing else...
raise EDatabaseError.Create('Table must be either of Paradox or dBASE ' +

'type to pack');

Table.Open;
end;
 
这是bde的api函数问题,请看delphi中的bde说明手册。
 
能给一个中文解释吗?
 

若用Ttable元件的Delete 方法删除一条记录,则Delphi 在该条记录的物理位置的首部用“*”打上
标记(正如用Foxpro或Dbase的Del命令一样),TTable中删除记录后,没有真正删除.
用DbiPackTable 进行彻底地物理删除,
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, DBGrids, Db, DBTables,dbitypes;
//首先应在USES语句中加上DBITYPES
type
TForm1 = class(TForm)
Table1: TTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
table1.tablename:='c:2/8/sbk2.dbf';
table1.open;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
dbipacktable(table1.dbhandle,table1.handle,nil,nil,true);
//在OBJECT INSPECTOR中EXCLUSIVE属性为TRUE
end;

end.
注意: 若在DELPHI IDE中, TABLE1的ACTIVE应为FALSE;
在程序中执行table1.open,来打开数据库, 否则在执行程序是会提示TABLE IS BUSY.
原因是在IDE中已经打开的TABLE, 无法的独占地打开TABLE.

 
我这里有一个在delphi开发人员手册上的代码,是用来限制query回送记录的,参考一下吧。
先生成一个tquery的控件。代码如下:

unit restrictedquery;

interface

uses
Windows, Messages, SysUtils, Classes, DB, DBTables,bde;//加上bde

type
Trestrictedquery = class(TQuery)
private
fmaxrowcount:longint;
{ Private declarations }
protected
procedure preparecursor;override;
{ Protected declarations }
public
property maxrowcount:longint read fmaxrowcount write fmaxrowcount;
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Trestrictedquery.preparecursor;
begin
inherited preparecursor;
if fmaxrowcount>0 then
check(dbisetprop(hdbiobj(handle),curmaxrows,fmaxrowcount));
end;
procedure Register;
begin
RegisterComponents('Samples', [Trestrictedquery]);
end;

end.

注册后在sample页,书上说要在query的preparecursor重调用maxrowcount属性最好。但我
总是不能出来结果,请大家看看。
 
《D5开发人员指南》第1048页
 
多人接受答案了。
 
后退
顶部