お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"TStringGridの使い方例"

この発言に対し以下のコメントが寄せられています
#00523 Satobe さん RE:TStringGridの使い方例

・全体をクリアする場合,動的に行数を変える場合は,RowCountを変化させ るしかないようです.初めに行数を調べて,どばっと確保.Rows.Addとか やってもだめ. ・StringGridから他のGrid等に項目をドラッグするには,dmAutomaticでは 動作がおかしくて使えないので,dmManualにしてBeginDragを自分で する必要がありますが,特別の事情がない限りEndDragを呼んではいけません. 以下に複数行の項目をTreeViewにドラッグする例を示します.  ちなみにWin32コモンコントロールのTListViewは,比較的簡単に体裁良く 表が作れるし,dmAutomaticでいけちゃうし,Clearしてから動的に行を追加 してソートするとかは簡単ですが,何かの拍子にWin95のみ罫線が表示されなく なる(NT4ではOK)バグとか,項目クラスの造りがMS的でダサイ,一行のピッチが 小さい,OnDrawCellイベントがないから行,桁ごとに色,文字を変えられ ない(オーナードロー出来るのか?)等,使い込んでいくと不満が出てきます. var MovingSubject: TAcntSubject; { グリッドの行数を動的に決定しつつ,各行に表示対象のオブジェクトを 割り当てる例.   まずTListにオブジェクトを入れてソートし,順序よく並べて内容を表示 } procedure TSbjExplr.UpdateNotePane; var Compo: TDataComponent; AllotNote: TAllotNote; Slip: TSlip; i, j: integer; S1,S2,S3: string; PrevV,Sum,V,DrV,CrV: Currency; SumDebt,SumCred: Currency; Subject: TAcntSubject; SbjList: TList; begin if SelectedSubject = nil then Exit; SbjList := TList.Create; try Grid1.RowCount := 3; // Clear grid; // 前月末の残高 with Grid1.Rows[1] do begin Objects[0] := nil; Strings[0] := '01/01'; Strings[1] := '期首残高'; Strings[2] := ''; Strings[3] := ''; Strings[4] := ''; Sum := SelectedSubject.InitialCarryover; PrevV := Sum; Strings[5] := FormatCurr('0,', Sum); end; if ShowMonthly1.Checked then begin // 月別集計表示 略 end else begin // データ詳細表示 // タイトル行 with Grid1.Rows[0] do begin Objects[0] := nil; Strings[0] := '日付'; Strings[1] := '摘要'; Strings[2] := '相手科目'; Strings[3] := '借方'; Strings[4] := '貸方'; Strings[5] := '残高'; end; // OnDrawCellの時に参照する非表示ラベルに書式をセット TLabel(LBPanel.Controls[ColNum+1]).Alignment := taLeftJustify; TLabel(LBPanel.Controls[ColNum+2]).Alignment := taLeftJustify; // データを集めてStringListに取り込み for i := 0 to SelectedSubject.DataCount-1 do begin Compo := SelectedSubject.Datas[i]; // 通年データ表示 if Compo is TAllotNote then begin // 仕訳データの取り込み AllotNote := TAllotNote(Compo); Slip := AllotNote.Slip; // 作りかけは表示しない if (Slip = nil)or(Slip.Owner = nil) then Continue; end; SbjList.Add(Compo); end; // 日付順に項目をソート SelectedSubjectTemp := SelectedSubject; SbjList.Sort(ListSort1); // sort by date SumDebt := 0; SumCred := 0; Grid1.RowCount := SbjList.Count + 3; for i := 0 to SbjList.Count-1 do begin Subject := SbjList.Items[i]; with Grid1.Rows[i+2] do begin if Subject <> nil then begin Objects[0] := Subject; V := Subject.Value - Subject.InitialCarryover; DrV := Subject.DrValue; CrV := Subject.CrValue; if Subject is TAllotNote then begin // 仕訳データ Strings[0] := FormatDateTime('mm/dd', Subject.Date); Slip := TAllotNote(Subject).Slip; Strings[1] := Slip.Summary; // 相手科目 S3 := ''; for j := 0 to Slip.NoteCount-1 do begin if (Slip.Notes[j].Subject <> SelectedSubject)and (Slip.Notes[j].DrCr <> TAllotNote(Subject).DrCr) then begin if Length(S3) > 0 then S3 := S3 + ' /'; S3 := S3 + Slip.Notes[j].Subject.SubjectName; end; end; Strings[2] := S3; if Subject.DrCr = dcDebtor then begin S1 := FormatCurr('0,', DrV); S2 := ''; SumDebt := SumDebt + DrV; end else begin S1 := ''; S2 := FormatCurr('0,', CrV ); SumCred := SumCred + CrV; end; end else begin // 子科目 Strings[0] := '子科目'; Strings[1] := Subject.SubjectName; Strings[2] := '残高 : ' + FormatCurr('0,',Subject.Value); S1 := FormatCurr('0,', DrV); SumDebt := SumDebt + DrV; S2 := FormatCurr('0,', CrV ); SumCred := SumCred + CrV; end; Strings[3] := S1; Strings[4] := S2; if Subject.DrCr = SelectedSubject.DrCr then begin Sum := Sum + V; end else begin Sum := Sum - V; end; end; Strings[5] := FormatCurr('0,', Sum ); end; end; with Grid1.Rows[Grid1.RowCount-1] do begin Sum := SelectedSubject.Value; Objects[0] := nil; Strings[0] := '12/31'; Strings[1] := '年間合計'; Strings[2] := '残高欄は増減を示す'; Strings[3] := FormatCurr('0,',SumDebt); Strings[4] := FormatCurr('0,',SumCred); V := Sum - SelectedSubject.InitialCarryover; if V > 0 then S1 := '+' else S1 := ''; Strings[5] := S1 + FormatCurr('0,', V); end; end; finally SbjList.Free; end; end; // Gridからドラッグ開始 procedure TSbjExplr.Grid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then Grid1.BeginDrag(False); end; procedure TSbjExplr.Grid1StartDrag(Sender: TObject; var DragObject: TDragObject); begin MovingSubject := TAcntSubject(Grid1.Rows[Grid1.Selection.Top].Objects[0]); end; // 以下ドロップを受ける側 procedure TSbjExplr.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := False; if (Source = Grid1)or(Source = Sender) then begin if (MovingSubject <> nil) then begin Accept := True; end; end; end; procedure TSbjExplr.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer); var TargetSubject: TAcntSubject; SrcSub: TAcntSubject; i: integer; begin if Source = Grid1 then begin TargetSubject := TAcntSubject(TreeView1.DropTarget.Data); if (MovingSubject <> nil) then begin if (TargetSubject = MovingSubject) then begin raise Exception.Create('受け側と送り側の科目が同じです'); end else if TargetSubject.IsOwnedBy(MovingSubject) then begin raise Exception.Create('科目の親子関係は逆転できません'); end else begin for i := Grid1.Selection.Top to Grid1.Selection.Bottom do begin SrcSub := TAcntSubject(Grid1.Rows[i].Objects[0]); if SrcSub <> nil then begin SrcSub.Owner.RemoveComponent(SrcSub); // 親の差し替え TargetSubject.InsertComponent(SrcSub); end; end; UpdateSubjectPane; // TreeView,Gridの再描画 end; end; end else if Source = Sender then begin // 以下略 end; MovingSubject := nil; end; // Gridへの自力描画,書式設定はチューニング用の非表示コンポから拾ってくる procedure TSbjExplr.Grid1DrawCell(Sender: TObject; Col, Row: Integer; Rect: TRect; State: TGridDrawState); var GrC: TCanvas; Grid: TStringGrid; Algn: TAlignment; S: string; begin Grid := TStringGrid(Sender); GrC := Grid.Canvas; if Row = 0 then begin S := Grid.Cells[Col, Row]; Algn := TLabel(LBPanel.Controls[Col]).Alignment; end else if Row = 1 then begin if Grid.Row <> Row then begin Grc.Brush.Assign(Shape1.Brush); //非表示Shapeから色を取ってくる Grc.FillRect(Rect); end; S := Grid.Cells[Col, Row]; // ↓非表示Labelから書式を取ってくる Algn := TLabel(LBPanel.Controls[Col + ColNum]).Alignment; end else if Row = Grid.RowCount-1 then begin if Grid.Row <> Row then begin Grc.Brush.Assign(Shape2.Brush); Grc.FillRect(Rect); end; S := Grid.Cells[Col, Row]; Algn := TLabel(LBPanel.Controls[Col + ColNum]).Alignment; end else begin // 中間行 S := Grid.Cells[Col, Row]; Algn := TLabel(LBPanel.Controls[Col + ColNum]).Alignment; end; DrawString( S, GrC, Rect, Algn); end; // 右寄せ,センタリング表示も可能.CanvasのClipRectを事前に設定しておく procedure DrawString( const S: string; Canvas: TCanvas; Rect: TRect; Alignment:TAlignment); var FontHeight: integer; DrRect: TRect; const Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER); begin FontHeight := Canvas.TextHeight('W'); with DrRect do begin Left := Rect.Left+2; Right := Rect.Right-2; Top := ((Rect.Bottom + Rect.Top) - FontHeight) div 2; Bottom := Top + FontHeight; end; Canvas.FillRect(Rect); DrawText(Canvas.Handle, PChar(S), -1, DrRect, (DT_EXPANDTABS or DT_VCENTER) or Alignments[Alignment]); end; TN(CQJ01721) Original document by TN 氏 ID:(CQJ01721)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum