我感觉要和你讨论一下程序设计的问题了
当Delete,UpDate操作后,如果Select的数据集关闭再打开,就会First,需要从新定位,
这时候屏幕会出现轻微的闪烁,性能也受影响,显得很迟钝。
----用LISTVIEW替换TREEVIEW
把表示层和数据层分开(这几乎成为我的一句口头禅了)
这样就要写更多的CODE了
下面就回答你的第二个问题.
另外那怕很简单的程序
也要写一堆Code,如何是好?
----不管程序有多简单写出优质代码才是最重要的
如果你这个程序的确很简单,但在系统中地位很重要
还是值得你下工夫的.
一个再简单的程序也应该有一个良好的结构和执行效率
以下是我写的一个很简单的软件的持久流化部分
程序里只用到两个表
{*******************************************************}
{ }
{ Resource Classes }
{ }
{ 1999,2000 NARI IS Corporation }
{ }
{*******************************************************}
unit ResClses;
interface
uses
Sysutils, Classes, ComCtrls, Db, ResCallDB, ResDBUtils;
type
TResIUDMode = (rmInsert, rmUpdate, rmDelete);
TResPasteMode = (rpmCut, rpmCopy);
TResSearchFlag = (rsfFind, rsfNotFind);
type
TResVirtualNode = class end;
type
TRes = class;
TResCls = class;
TResInst = class;
TRes = class(TObject)
private
FResID: Integer;
FResName: string;
FResCode: string;
FResNote: string;
FResDispIndex: Integer;
FResCallDB: TResCallDB;
public
constructor Create; overload; virtual;
destructor Destroy; override;
procedure LoadFromDataSet; virtual;
procedure Assign(Source: TRes); virtual;
procedure SelectByID(ID: Integer); virtual;
procedure DbInsert; virtual;
procedure DbUpdate; virtual;
procedure DbDelete; virtual;
procedure UpdateListItem(Item: TListItem); virtual;
function Clone: TRes; virtual;
function Duplicate: TRes; virtual;
property ResID: Integer read FResID write FResID;
property ResName: string read FResName write FResName;
property ResCode: string read FResCode write FResCode;
property ResNote: string read FResNote write FResNote;
property ResDispIndex: Integer read FResDispIndex write FResDispIndex;
property ResCallDB: TResCallDB read FResCallDB write FResCallDB;
end;
TResCls = class(TRes)
private
FResParID: Integer;
FResVRFlag: string;
FResSchema: string;
FResView: string;
public
constructor Create; override;
destructor Destroy; override;
procedure LoadFromDataSet; override;
procedure Assign(Source: TRes); override;
procedure SelectByID(ID: Integer); override;
procedure DbInsert; override;
procedure DbUpdate; override;
procedure DbDelete; override;
procedure UpdateListItem(Item: TListItem); override;
function Clone: TRes; override;
function Duplicate: TRes; override;
procedure CreateView;
procedure DropView;
property ResParID: Integer read FResParID write FResParID;
property ResVRFlag: string read FResVRFlag write FResVRFlag;
property ResSchema: string read FResSchema write FResSchema;
property ResView: string read FResView write FResView;
end;
TResInst = class(TRes)
private
FResClsID: Integer;
FResExtFlag: string;
FResValFlag: string;
public
constructor Create; override;
destructor Destroy; override;
procedure LoadFromDataSet; override;
procedure Assign(Source: TRes); override;
procedure SelectByID(ID: Integer); override;
procedure DbInsert; override;
procedure DbUpdate; override;
procedure DbDelete; override;
procedure UpdateListItem(Item: TListItem); override;
function Clone: TRes; override;
function Duplicate: TRes; override;
property ResClsID: Integer read FResClsID write FResClsID;
property ResExtFlag: string read FResExtFlag write FResExtFlag;
property ResValFlag: string read FResValFlag write FResValFlag;
end;
implementation
uses
ResUtils;
//------------------------------------------------------------------------------
// TRes
//------------------------------------------------------------------------------
constructor TRes.Create;
begin
inherited;
FResCallDB := TResDOACallDB.Create;
end;
destructor TRes.Destroy;
begin
FResCallDB.Free;
inherited;
end;
procedure TRes.LoadFromDataSet;
begin
end;
procedure TRes.Assign(Source: TRes);
begin
if Source is TRes then
begin
ResID := TRes(Source).ResID;
ResName := TRes(Source).ResName;
ResCode := TRes(Source).ResCode;
ResDispIndex := TRes(Source).ResDispIndex;
ResNote := TRes(Source).ResNote;
end;
end;
procedure TRes.SelectByID(ID: Integer);
begin
end;
procedure TRes.DbInsert;
begin
end;
procedure TRes.DbUpdate;
begin
end;
procedure TRes.DbDelete;
begin
end;
procedure TRes.UpdateListItem(Item: TListItem);
begin
with Item do
begin
Caption := ResName;
Data := Self;
SubItems.Clear;
end;
end;
function TRes.Clone: TRes;
begin
Result := nil;
end;
function TRes.Duplicate: TRes;
begin
Result := nil;
end;
//------------------------------------------------------------------------------
// TResCls
//------------------------------------------------------------------------------
constructor TResCls.Create;
begin
inherited;
end;
destructor TResCls.Destroy;
begin
inherited;
end;
procedure TResCls.LoadFromDataSet;
begin
inherited;
Assert(ResCallDB.DataSet.Active);
Assert(not ResCallDB.DataSet.Eof);
with ResCallDB.DataSet do
begin
ResID := FieldByName('RES_CLS_ID').AsInteger;
ResName := FieldByName('RES_CLS_NAME').AsString;
ResCode := FieldByName('RES_CLS_CODE').AsString;
ResNote := FieldByName('RES_CLS_NOTE').AsString;
ResDispIndex := FieldByName('RES_CLS_DISPINDEX').AsInteger;
ResParID := FieldByName('RES_CLS_PARID').AsInteger;
ResVRFlag := FieldByName('RES_CLS_VRFLAG').AsString;
ResSchema := FieldByName('RES_CLS_SCHEMA').AsString;
ResView := FieldByName('RES_CLS_VIEW').AsString;
end;
end;
procedure TResCls.Assign(Source: TRes);
begin
inherited;
if Source is TResCls then
begin
ResParID := TResCls(Source).ResParID;
ResVRFlag := TResCls(Source).ResVRFlag;
ResSchema := TResCls(Source).ResSchema;
ResView := TResCls(Source).ResView;
end;
end;
procedure TResCls.SelectByID(ID: Integer);
const
strSql = 'SELECT * FROM PMIS.COM_RES_CLS WHERE RES_CLS_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlOpen(Format(strSql, [ID]));
LoadFromDataSet;
SqlOpenEnd;
end;
end;
procedure TResCls.DbInsert;
const
strSql = 'INSERT INTO PMIS.COM_RES_CLS '
+ '(RES_CLS_ID,'
+ 'RES_CLS_NAME,'
+ 'RES_CLS_CODE,'
+ 'RES_CLS_NOTE,'
+ 'RES_CLS_DISPINDEX,'
+ 'RES_CLS_PARID,'
+ 'RES_CLS_VRFLAG,'
+ 'RES_CLS_SCHEMA,'
+ 'RES_CLS_VIEW) '
+ 'VALUES (%D, ''%S'', ''%S'', ''%S'', %D, %D, ''%S'', ''%S'', ''%S'')';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResID, ResName, ResCode, ResNote, ResDispIndex,
ResParID, ResVRFlag, ResSchema, ResView]));
SqlExecEnd;
end;
end;
procedure TResCls.DbUpdate;
const
strSql = 'UPDATE PMIS.COM_RES_CLS '
+ 'SET '
+ 'RES_CLS_NAME = ''%S'','
+ 'RES_CLS_CODE = ''%S'','
+ 'RES_CLS_NOTE = ''%S'','
+ 'RES_CLS_DISPINDEX = %D,'
+ 'RES_CLS_PARID = %D,'
+ 'RES_CLS_SCHEMA = ''%S'','
+ 'RES_CLS_VIEW = ''%S'''
+ 'WHERE RES_CLS_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResName, ResCode, ResNote, ResDispIndex, ResParID,
ResSchema, ResView, ResID]));
SqlExecEnd;
end;
end;
procedure TResCls.DbDelete;
const
strSql = 'DELETE FROM PMIS.COM_RES_CLS WHERE RES_CLS_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResID]));
SqlExecEnd;
end;
end;
procedure TResCls.CreateView;
const
strSql = 'CREATE VIEW %S.%S '
+ 'AS '
+ 'SELECT RES_INST_ID AS ID,'
+ ' RES_INST_NAME AS NAME,'
+ ' RES_INST_DISPINDEX AS DISPINDEX '
+ 'FROM PMIS.COM_RES_INST '
+ 'WHERE RES_CLS_ID = '
+ '(SELECT RES_CLS_ID FROM PMIS.COM_RES_CLS '
+ 'WHERE RES_CLS_CODE = ''%S'') '
+ 'AND RES_INST_VALFLAG = ''T''';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResSchema, ResView, ResCode]));
SqlExecEnd;
end;
end;
procedure TResCls.DropView;
const
strSql = 'DROP VIEW %S.%S';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResSchema, ResView]));
SqlExecEnd;
end;
end;
procedure TResCls.UpdateListItem(Item: TListItem);
begin
inherited;
with Item.SubItems do
begin
Add(ResCode);
Add(InterpretResVRFlag(ResVRFlag));
Add(ResSchema);
Add(ResView);
Add(ResNote);
end;
end;
function TResCls.Clone: TRes;
var
rsResCls: TResCls;
begin
rsResCls := TResCls.Create;
with rsResCls do
begin
ResID := TResCls(Self).ResID;
ResName := TResCls(Self).ResName;
ResCode := TResCls(Self).ResCode;
ResDispIndex := TResCls(Self).ResDispIndex;
ResNote := TResCls(Self).ResNote;
ResParID := TResCls(Self).ResParID;
ResVRFlag := TResCls(Self).ResVRFlag;
ResSchema := TResCls(Self).ResSchema;
ResView := TResCls(Self).ResView;
end;
Result := rsResCls;
end;
function TResCls.Duplicate: TRes;
var
rsResCls: TResCls;
begin
rsResCls := TResCls.Create;
with rsResCls do
begin
ResID := GetNextRecID('PMIS.COM_RES_CLS_ID_SEQ');
ResName := TResCls(Self).ResName;
ResCode := TResCls(Self).ResCode;
ResDispIndex := ResID;
ResNote := TResCls(Self).ResNote;
ResParID := TResCls(Self).ResParID;
ResVRFlag := TResCls(Self).ResVRFlag;
ResSchema := TResCls(Self).ResSchema;
ResView := TResCls(Self).ResView;
end;
Result := rsResCls;
end;
//------------------------------------------------------------------------------
// TResInst
//------------------------------------------------------------------------------
constructor TResInst.Create;
begin
inherited;
end;
destructor TResInst.Destroy;
begin
inherited;
end;
procedure TResInst.LoadFromDataSet;
begin
inherited;
Assert(ResCallDB.DataSet.Active);
Assert(not ResCallDB.DataSet.Eof);
with ResCallDB.DataSet do
begin
ResID := FieldByName('RES_INST_ID').AsInteger;
ResName := FieldByName('RES_INST_NAME').AsString;
ResCode := FieldByName('RES_INST_CODE').AsString;
ResDispIndex := FieldByName('RES_INST_DISPINDEX').AsInteger;
ResNote := FieldByName('RES_INST_NOTE').AsString;
ResValFlag := FieldByName('RES_INST_VALFLAG').AsString;
ResExtFlag := FieldByName('RES_INST_EXTFLAG').AsString;
ResClsID := FieldByName('RES_CLS_ID').AsInteger;
end;
end;
procedure TResInst.Assign(Source: TRes);
begin
inherited;
if Source is TResInst then
begin
ResValFlag := TResInst(Source).ResValFlag;
ResExtFlag := TResInst(Source).ResExtFlag;
ResClsID := TResInst(Source).ResClsID;
end;
end;
procedure TResInst.SelectByID(ID: Integer);
const
strSql = 'SELECT * FROM PMIS.COM_RES_INST WHERE RES_INST_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlOpen(Format(strSql, [ID]));
LoadFromDataSet;
SqlOpenEnd;
end;
end;
procedure TResInst.DbInsert;
const
strSql = 'INSERT INTO PMIS.COM_RES_INST '
+ '(RES_INST_ID,'
+ 'RES_INST_NAME,'
+ 'RES_INST_CODE,'
+ 'RES_INST_DISPINDEX,'
+ 'RES_INST_NOTE,'
+ 'RES_INST_VALFLAG,'
+ 'RES_INST_EXTFLAG,'
+ 'RES_CLS_ID)'
+ 'VALUES (%D, ''%S'', ''%S'', %D, ''%S'', ''%S'', ''%S'', %D)';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResID, ResName, ResCode, ResDispIndex, ResNote,
ResValFlag, ResExtFlag, ResClsID]));
SqlExecEnd;
end;
end;
procedure TResInst.DbUpdate;
const
strSql = 'UPDATE PMIS.COM_RES_INST '
+ 'SET '
+ 'RES_INST_NAME = ''%S'','
+ 'RES_INST_CODE = ''%S'','
+ 'RES_INST_DISPINDEX = %D,'
+ 'RES_INST_NOTE = ''%S'','
+ 'RES_INST_VALFLAG = ''%S'','
+ 'RES_INST_EXTFLAG = ''%S'','
+ 'RES_CLS_ID = %D '
+ 'WHERE RES_INST_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResName, ResCode, ResDispIndex, ResNote, ResValFlag,
ResExtFlag, ResClsID, ResID]));
SqlExecEnd;
end;
end;
procedure TResInst.DbDelete;
const
strSql = 'DELETE FROM PMIS.COM_RES_INST WHERE RES_INST_ID = %D';
begin
inherited;
Assert(ResCallDB <> nil);
with ResCallDB do
begin
SqlExec(Format(strSql, [ResID]));
SqlExecEnd;
end;
end;
procedure TResInst.UpdateListItem(Item: TListItem);
begin
inherited;
with Item.SubItems do
begin
Add(ResCode);
Add(InterpretResValFlag(ResValFlag));
Add(InterpretResExtFlag(ResExtFlag));
Add(ResNote);
end;
end;
function TResInst.Clone: TRes;
var
rsResInst: TResInst;
begin
rsResInst := TResInst.Create;
with rsResInst do
begin
ResID := TResInst(Self).ResID;
ResName := TResInst(Self).ResName;
ResCode := TResInst(Self).ResCode;
ResDispIndex := TResInst(Self).ResDispIndex;
ResNote := TResInst(Self).ResNote;
ResValFlag := TResInst(Self).ResValFlag;
ResExtFlag := TResInst(Self).ResExtFlag;
ResClsID := TResInst(Self).ResClsID;
end;
Result := rsResInst;
end;
function TResInst.Duplicate: TRes;
var
rsResInst: TResInst;
begin
rsResInst := TResInst.Create;
with rsResInst do
begin
ResID := GetNextRecID('PMIS.COM_RES_INST_ID_SEQ');
ResName := TResInst(Self).ResName;
ResCode := TResInst(Self).ResCode;
ResDispIndex := ResID;
ResNote := TResInst(Self).ResNote;
ResValFlag := TResInst(Self).ResValFlag;
ResExtFlag := TResInst(Self).ResExtFlag;
ResClsID := TResInst(Self).ResClsID;
end;
Result := rsResInst;
end;
end.
--------------------------------------------
添加时
1.在LISTVIEW上加一条记录
2.在数据库里物理插入一条记录
删除时
1.删掉LISTVIEW里的那条记录
2.删除数据里对应记录
修改时,注意方法
procedure UpdateListItem(Item: TListItem);
傻瓜照相机是好,专业人员不用,
专业人员就是用了,
也要求不高的时候玩玩的.