はじめに
個人的には DBGrid をあまり使わないので気付かなかったのですが、DBGrid には長い間バグが存在したようです。この問題は 『Delphi 10.1 Berlin』 以前のバージョンで発生します。
DBGrid のバグ
バグの再現方法と回避方法です。
再現方法
まず、何でもいいので DBGrid にデータを表示させます。
テストとして ADO で接続するようにしてみました。データは %ProgramFiles%\Common Files\Borland Shared\Data
の dbdemos.mdb
を使いました。
Button1 と Button2 をクリックした時のイベントハンドラにこんな感じで記述します。
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'select * from country';
ADOQuery1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'select * from country where Population < 0';
ADOQuery1.Open;
end;
Button1 を押すと全件表示され、
Button2 を押すと 0 件になります。
もう一度 Button1 を押すと再度全件表示されます。
では次に、横スクロールバーが出ないようにフィールドを絞ってみます。Button1 と Button2 をクリックした時のイベントハンドラはこんな感じになります。
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'select Name, Population from country';
ADOQuery1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'select Name, Population from country where Population < 0';
ADOQuery1.Open;
end;
先程と同様に実行してみます。Button1 を押すと全件表示され、
Button2 を押すと 0 件になります。
もう一度 Button1 を押すと再度全件表示されますが、ここでバグが発生します。
縦スクロールバーが表示されていませんよね?
回避方法
この問題を回避するには、横スクロールバーを表示させるようにするか、強制的に縦スクロールバーを表示させます。
強制的に縦スクロールバーを表示させるのには ShowScrollBar()
API を使います。
ShowScrollBar(DBGrid1.Handle, SB_VERT, True);
See also:
インターポーザークラスを使った回避方法
インターポーザークラスを使って回避するのが簡単でしょう。以下のユニットを問題の出るプロジェクトに追加してください。
unit uDBGridFix;
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion >= 32.0}
{$MESSAGE ERROR 'uDBGridFix.pas: This unit is only required for Delphi 10.1 Berlin or earlier.'}
{$IFEND}
{$IF CompilerVersion >= 23.0}
{$DEFINE XE2_OR_LATER}
{$IFEND}
{$ENDIF}
interface
uses
{$IFDEF XE2_OR_LATER}
System.SysUtils, Vcl.DBGrids, Winapi.Windows;
{$ELSE}
SysUtils, DBGrids, Windows;
{$ENDIF}
type
TDBGrid = class({$IFDEF XE2_OR_LATER}Vcl.{$ENDIF}DBGrids.TDBGrid)
protected
procedure UpdateScrollBar; override;
end;
implementation
{ TDBGrid }
procedure TDBGrid.UpdateScrollBar;
begin
inherited;
ShowScrollBar(Self.Handle, SB_VERT, True);
end;
end.
フォームに DBGrid を貼り付けている (or 使用している) ユニットの uses の最後に uDBGridFix
を追記します (Vcl.DBGrid よりも後に記述してください)。
uses
..., uDBGridFix;
実行してみます。Button1 を押して、
Button2 を押して、
再び Button1 を押します。ちゃんと縦スクロールバーが表示されました。
0 件の時も縦スクロールバーが表示されるようになってしまいましたが実害はないと思います。
See also:
横スクロールバーの表示される DBGrid と 横スクロールバーの表示されない DBGrid が同じフォームに貼ってあるんだが?
混在しても大丈夫ですよ。縦スクロールバーしか表示されないなんて事はありません。
おわりに
この問題の解決方法は、今はなき Embarcadero Quality Central に投稿されていました。
- QC#7527: TDBGrid vertical scrollbar dissappears (Quality Central)
- QC#7527: TDBGrid vertical scrollbar dissappears (Internmet Archive)
バグ自体は一つ前の Quality Portal にも報告されていたようです。
See also: