2013-10-31 19 views
5

私がコントロールを無効にするのは、ユーザーがそれをクリックするのが無意味なときです。IsFirstRecordとIsLastRecordの実装方法は?

特別なケースの1つは、標準TDBNavigatorの最初、前、次、および最後のボタンをエミュレートするカスタムメニューボタンのセットです。

ユーザーが最初のボタンをクリックすると、最初と前のボタンが両方とも無効になります。

ユーザーが次のおよび前のボタンをクリックすると、下にあるTDataSetが前と同じレコードに配置されますが、最初と前のボタンは両方とも有効です。

現在の実装では、次のようになります。私は、現在のレコードが最初/最後のレコードであることを行っている場合は、事前に知っておく必要があるため

NavigationFirstButton.Enabled := not DataSet.IsEmpty and not DataSet.Bof; 
NavigationPriorButton.Enabled := not DataSet.IsEmpty and not DataSet.Bof; 
NavigationNextButton.Enabled := not DataSet.IsEmpty and not DataSet.Eof; 
NavigationLastButton.Enabled := not DataSet.IsEmpty and not DataSet.Eof; 

BofEofは、ボタンを無効にする正しい方法ではありません。

だから私はIsFirstRecordIsLastRecord方法を使用して、これを書き換えると考える:

function IsFirstRecord(ADataSet: TDataSet): Boolean; 
begin 
    Result := ADataSet.RecNo = 0; 
end; 

function IsLastRecord(ADataSet: TDataSet): Boolean; 
begin 
    Result := ADataSet.RecNo = ADataSet.RecordCount - 1; 
end; 

私は私が最初のレコードRecNo = 0のためではない例を見てきたので、これは、良いアイデアだと思いません本当。 (すなわち、フィルタリングされたTADSクエリ)

IsFirstRecordIsLastRecordの信頼できる実装は何ですか?現在のTDataSetアーキテクチャを使用しても可能ですか?

+0

は 'RecNo'はオプションです(非実装されてもよい)SQLデータセットのために。 'RecordCount'はすべてのデータを取得する必要があるため、SQLデータセットには悪いです。 10GBの情報を生成するSQL SELECT要求を想像してください。通常、ユーザーはデータの最初の画面(または3つの画面または10の画面)のみを分析してからフォームを閉じるだけで、あまり関係のないデータは無視します。 .RecordCountを呼び出すと、1:SQL Serverはディスクから10GBをすべて順番に読み込みます。2:ネットワークはこれらの10GBのデータをすべて転送します。3:クライアントは10GBのすべてのデータをRAMにキャッシュします。 –

+0

したがって、サーバーとネットワーク(他のすべての作業を遅くする)とクライアントのメモリ不足によるクラッシュのストレステストになります。おそらく決して必要とされないだろうという情報のためのすべてのもの。したがって、RecNoアプローチはISAMデータベース(DBF、Paradoxなど)にとって適切なものです。 SQLデータベースの場合、適切な方法は 'TDataSet.EOF'と' TDataSet.BOF'ファンクション –

+1

PSを使用することです。定義ではDataSet.Empty == DataSet.EOFとDataSet.BOFのように、チェックは冗長です。私はあなたが何かを意味したと思うDataSet.Active DataSet.Bof; –

答えて

5

あなたはこのような何かを試みることができる:

function IsFirstRecord(ADataSet: TDataSet): Boolean; 
var 
    BmStr: TBookmarkStr; 
begin 
    Result := not ADataSet.IsEmpty; 
    if not Result then Exit; 
    Result := ADataSet.Bof; 
    // if ADataSet is already at BOF there is no point to continue 
    if not Result then 
    begin 
    ADataSet.DisableControls; 
    try 
     BmStr := ADataSet.Bookmark; 
     try 
     ADataSet.Prior; 
     Result := ADataSet.Bof; 
     finally 
     ADataSet.Bookmark := BmStr; 
     end; 
    finally 
     ADataSet.EnableControls; 
    end; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if IsFirstRecord(ADODataSet1) then 
    ShowMessage('First') 
    else 
    ShowMessage('Not First'); 
end; 

IsLastRecordの実装は、単純に置き換える:

ADataSet.Prior -> ADataSet.Next 
ADataSet.Bof -> ADataSet.Eof 
関連する問題