시비리안님 말씀에 동의하며..
저 같은 경우에는 테이블 컴포넌트를 페이징하면서 조금 개선해 본 적이 있습니다..
unit IBPageCtrl;
interface
uses
SysUtils, Classes, DB, IBHeader, IB, IBDatabase, IBCustomDataSet, IBSQL,
IBQuery;
type
TIBPageCtrl = class(TComponent)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
Constructor Create(AOwner:TComponent); Override;
Destructor Destroy; Override;
private
{ Private declarations }
FActive : Boolean;
FSQL, FSelectField : TStringList;
FRecordCount, FPageSize, FLastPage, FPage : Integer;
FDataSource : TDataSource;
FOnChanged : TNotifyEvent;
Procedure SetActive(Value:Boolean);
Procedure SetSQL(Value:TStringList);
Procedure SetSelectField(Value:TStringList);
Procedure SetPageSize(Value:Integer);
Procedure SetPage(Value:Integer);
published
{ Published declarations }
Property Active : Boolean read FActive write SetActive;
Property SQL : TStringList read FSQL write SetSQL;
Property SelectField : TStringList read FSelectField write SetSelectField;
Property RecordCount : Integer read FRecordCount;
Property PageSize : Integer read FPageSize write SetPageSize;
Property LastPage : Integer read FLastPage;
Property Page : Integer read FPage write SetPage;
Property DataSource : TDataSource read FDataSource write FDataSource;
Property OnChanged : TNotifyEvent read FOnChanged write FOnChanged;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Ryu', [TIBPageCtrl]);
end;
Constructor TIBPageCtrl.Create(AOwner:TComponent);
Begin
Inherited Create(AOwner);
FSQL:= TStringList.Create;
FSelectField:= TStringList.Create;
End;
Destructor TIBPageCtrl.Destroy;
Begin
FSQL.Free;
FSelectField.Free;
Inherited Destroy;
End;
Procedure TIBPageCtrl.SetActive(Value:Boolean);
Var
IBQuery : TIBQuery;
Begin
If (FDataSource = Nil) or (FDataSource.DataSet = Nil) then Exit;
IBQuery:= TIBQuery(FDataSource.DataSet);
IBQuery.Close;
If Value = True then Begin
IBQuery.SQL.Text:= FSQL.Text;
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@First', '1', [rfReplaceAll, rfIgnoreCase]);
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@Skip', '0', [rfReplaceAll, rfIgnoreCase]);
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@SelectField', 'Count(*)', [rfReplaceAll, rfIgnoreCase]);
IBQuery.Open;
// Division by Zero 에러를 피하기 위해
If FPageSize < 1 then FPageSize:= 1;
FRecordCount:= IBQuery.Fields[0].AsInteger;
FLastPage:= ((FRecordCount-1) div FPageSize) + 1;
Page:= 1;
End Else Begin
FPage:= 0;
FLastPage:= 0;
End;
FActive:= Value;
If Assigned(FOnChanged) then FOnChanged(Self);
End;
Procedure TIBPageCtrl.SetSQL(Value:TStringList);
Begin
FSQL.Assign(Value);
End;
Procedure TIBPageCtrl.SetSelectField(Value:TStringList);
Begin
FSelectField.Assign(Value);
End;
Procedure TIBPageCtrl.SetPageSize(Value:Integer);
Begin
FPageSize:= Value;
Active:= False;
Active:= True;
If Assigned(FOnChanged) then FOnChanged(Self);
End;
Procedure TIBPageCtrl.SetPage(Value:Integer);
Var
IBQuery : TIBQuery;
Begin
If (FDataSource = Nil) or (FDataSource.DataSet = Nil) then Exit;
IBQuery:= TIBQuery(FDataSource.DataSet);
// 페이지 크기보다 크면 페이지 크기로 지정한다.
If Value > LastPage then Value:= LastPage;
// 표시할 수 없는 페이지 또는 이전 페이지와 같으면 무시한다.
If (Value < 1) or (Value = FPage) then Exit;
FPage:= Value;
IBQuery.Close;
IBQuery.SQL.Text:= FSQL.Text;
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@First', IntToStr(FPageSize), [rfReplaceAll, rfIgnoreCase]);
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@Skip', IntToStr((FPage-1)*FPageSize), [rfReplaceAll, rfIgnoreCase]);
IBQuery.SQL.Text:= StringReplace(IBQuery.SQL.Text, '@SelectField', FSelectField.Text, [rfReplaceAll, rfIgnoreCase]);
IBQuery.Open;
If Assigned(FOnChanged) then FOnChanged(Self);
End;
end.
|