2

このテーブルがあるとしましょう:

name        varchar(255),
quantity    integer,
value       float

このコードを使用したとき:

select left(name, 99), quantity, value from table;

dbgridしかし、スクロールバーを使用してスクロールバーを作成することが目的でない限り、最初の列と他の2つのフィールドに255個のスペースすべてがあります(スペースとは、実際のスペースの文字ではなく、幅の長さを意味します)必要はありません。

この目標を正しく達成するにはどうすればよいですか? Firebird と MySQL を使用しています。

これはレポート ジェネレーターであり、最初のフィールドが常に同じであるとは限らず、レポートごとに異なる SQL コード。

ここに画像の説明を入力

回答する前に、全員がすべての質問を読んでください。最後の段落に書かれていることを考慮していないため、間違っている最初の3つの答え!

4

4 に答える 4

4

TFieldレベルまたは Delphi コードでは実行できないと述べたので、使用しているデータベースに応じて、列でTrim()またはLeft()を使用して、表示したくない空白を削除できます。

たとえば、多くの SQL ダイアレクトでは、次のようなものを使用できます。

SELECT Col1, Col2, Trim(Col3) as Col3 FROM yourtable 
WHERE somecondition

代わりにこれを許可するものもあります:

SELECT Col1, Col2, Left(Col3, MaxCharWidthAllowed) as Col3 FROM yourtable 
WHERE somecondition

また

SELECT Col1, Col2, Substring(Col3, 1, MaxCharWidth) as Col3 FROM yourtable

簡単なテストとして (私は FB を持っていませんが、SQL Server 2008 を持っているので使用しました)、SQL Server Management Studio で次のテスト データを作成しました。

SSMS のテスト データ

次に、新しい D2007 VCL フォーム アプリケーションを作成し、次の手順を実行しました。

  • TADOConnectionフォーム ( ) に をドロップし、ADOConnection1上記のテスト データへの接続文字列を設定します。
  • TADOQueryフォームに 2 つのコンポーネント (ADOQuery1および) をドロップしADOQuery2、それらのConnectionプロパティをADOConnection1
  • TDataSourceフォームに 2 つのコンポーネント (DataSource1およびDataSource2) をドロップし、それらのDataSetプロパティを対応するADOQuery1およびに接続しました。ADOQuery2
  • TDBGrid2 つのコンポーネント (DBGrid1DBGrid2) をドロップし、それらのDataSourceプロパティを対応するDataSource1とに設定しましたDataSource2
  • SELECT * FROM testの SQL に追加ADOQuery1
  • のとして追加SELECT Substring(itemname, 1, 30) as itemname, quantity, value FROM testされました。の長さは、かなり小さい列幅を示すのに十分小さい値として任意に選択されました。SQLADOQuery230
  • に設定ADOConnection1.ConnectedTrue、両方のTADOQuery.Activeプロパティを に設定しますTrue

上記は、この出力を (設計時に、アプリケーションをコンパイルまたは実行することなく) 生成し、上部のグリッドは次のDBGrid1とおりです。

上記の手順の設計時出力

ご覧のとおり、SQL の にDBGrid2接続されADOQuery2Substringいる では、最初の列のサイズが 30 文字幅に正しく設定されています。

于 2013-01-24T12:16:33.923 に答える
3

列の型が本当にそうvarchar(255)でないchar(255)場合は、スペースを自分で保存しない限り、値の末尾にスペースがあってはなりません。IOWvarchar(255)値は、テーブルに保存したとおりに返されます。char(255)値が常に 255 文字の文字列を取得できるように、値がスペースで埋められます。

したがって、タイプを使用し、値をDBに保存するときに値をスペースで埋めない場合、問題は実際にはグリッドにあり、SQLでsimgまたは同等のものを使用しvarcharて解決できないと言えます。trim()ほとんどの場合、グリッドはフィールドの定義を読み取り、値の最大長が 255 文字であることを確認し、それに応じて列幅を設定します。したがって、解決策は、列幅を手動で設定するか、列のApplyBestFitメソッドを使用することです(ある場合)。

于 2013-01-24T13:44:24.180 に答える
1

アップデート:

Delphiは、デフォルトDisplaylengthのvarcharフィールドの長さを取ります。varchar(255)= Displaylength=255。

「SQL」でこの動作を変更できますか?いいえ 結果の長さが99文字しかない場合、長さvarchar(255)=255およびDisplaylength=255です。

比較してください!
許可された:

select left(name,99), quantity, value from table;
  • SQLは、データセットをすばやく配信する必要があります(レポートのデザインではありません)。
  • 各varcharフィールドのテーブルごとに、追加のSQLステートメントを設定する必要があります(xname,99)
  • 切り捨てられた(おそらく重要な)情報を表示できますか?一度もない。

許可されていない:

Columns[index].Width = 99;
  • レポートのデザインが簡単になります。
  • より簡単なSQLステートメントの選択:select name, quantity, value from table
  • マウスで列を展開するだけで、非表示の情報が表示されます。
  • 適切な設計:DBGridの列サイズは、一度に少なくとも2つの列を表示できるサイズにする必要があります。

プログラムが設計を引き継ぐ必要があります。

これはレポートジェネレータであるため、このコードは多くのテーブルから取得されるため、パスカルコードでこれを行うことも、テーブルコンポーネントのFieldsオブジェクトで定義することもできません。

レポートごとに異なるSQLコードを使用する必要があります。

この「異なるSQLコード」を生成するのは誰ですか?
コード(パスカルコード)の生成にも同様の行が使われていると思います。

許可:パスカルコード

   Query1.Close;
   Query1.SQL.Clear;
   Query1.SQL.Add ('select name, quantity, value from table');
   Query1.Active: = true;

許可されない理由:パスカルコード

   Columns[index].Width := 99;

あなたは列の自動調整でそれを行うことができます。特定のサイズより幅の広いすべての列は、実際の幅に合わせて調整されます。これは、固定サイズ=99よりも優れています。

次のプログラムは、RadStudio2007およびZeosコンポーネントでテストされています。
Windows2000コンピュータ上のFirebird2.5。

  • A)Zeosコンポーネント。
  • B)DBGrid1アクティブなデータ接続がありません。
  • C)Firebirdはvarchar(255)のサイズを自動的に割り当てました。
  • D)実行中のプログラム。「useMe」は、列のサイズを自動的に設定するために使用されます。

時間の不足のため、2つのデータフィールドのみを作成しました。

ここに画像の説明を入力してください

ダウンロードにソースコード全体が必要な場合は、お知らせください。

unit FBAuto;
{
~Zarko Gajic
About Delphi Programing
http://delphi.about.com
customized 2013
moskito-x software
}

interface

uses
  Math,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, Grids, DBGrids, ExtCtrls, StdCtrls, ZAbstractRODataset,
  ZAbstractDataset, ZDataset, ZConnection;

type
  TAutoColumnWidth = record
    Index : integer;
    Width : integer;
  end;

  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    DataSource1: TDataSource;
    CBuseMe: TCheckBox;
    DBGrid2: TDBGrid;
    ZQuery2: TZQuery;
    DataSource2: TDataSource;
    IntegerField1: TIntegerField;
    StringField1: TStringField;
    procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure CBuseMeClick(Sender: TObject);
  private
    { Private declarations }
    procedure SetFit;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  AutoColumnWidth : TAutoColumnWidth;
  useMe :Boolean;

procedure TForm1.SetFit;
var
  i:integer;
begin
  if NOT CBuseMe.Checked then begin
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
     if DBGrid1.Columns[i].Field.Size > 300 then
        DBGrid1.Columns[i].Width := DBGrid1.Columns[i].Field.Size;
  end;
  end else begin
  useMe:=true;
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
  AutoColumnWidth.Index:=-1;
  if DBGrid1.Columns[i].Field.DisplayWidth > 200 then  AutoColumnWidth.Index:=i;
     if AutoColumnWidth.Index > -1 then begin
        AutoColumnWidth.Width := -1;
        DBGrid1.Repaint;
        DBGrid1.Columns[AutoColumnWidth.Index].Width := AutoColumnWidth.Width+ 5;
     end;
  end;
  useMe:=false;
  end;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
ZQuery1.Active:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AutoColumnWidth.Index := -1;
  AutoColumnWidth.Width := -1;
  useMe:=false;
end;

procedure TForm1.CBuseMeClick(Sender: TObject);
begin
  setFit;
end;

procedure TForm1.DBGrid1DrawColumnCell(
  Sender: TObject;
  const Rect: TRect;
  DataCol: Integer;
  Column: TColumn;
  State: TGridDrawState);
begin
  if useMe then begin
   if DataCol = AutoColumnWidth.Index then
   begin
    if Assigned(Column.Field) then
    begin
      AutoColumnWidth.Width := Max(AutoColumnWidth.Width, DBGrid1.Canvas.TextWidth(Column.Field.DisplayText));
    end;
   end;
  end;
end;

end.

ニーズに合わせて200以上を設定できます。

if DBGrid1.Columns[i].Field.DisplayWidth > 200 then  AutoColumnWidth.Index:=i;

これが少し役立つか、正しい方向につながることを願っています。

于 2013-01-29T05:16:08.243 に答える
1

データベースからのデータを変更せずに DBGrid に表示されるフィールドの長さを制限するには、2 つの方法があります。1 つはフィールドの DisplayWidth を設定する方法で、もう 1 つはグリッド列の幅を設定する方法です。

クエリの After open イベントで DisplayWidth を設定できます。この例は ZeosLib 用であり、最初のフィールドが制限されるものであると想定しています。これは、各クエリに追加する必要があります。

procedure TForm1.ZQuery1AfterOpen(DataSet: TDataSet);
begin
  DataSet.Fields[0].DisplayWidth := 99;
end;

または、クエリを開いた後に DBGrid 列幅を設定する手順を使用します。この例では、列と幅を指定できます。

procedure TForm1.SetColWidth(c,w: integer);
begin
  if DBGrid1.Columns.Count > c then
    DBGrid1.Columns[c].Width := w;
end;
于 2013-01-25T07:00:30.357 に答える