dl6pro,xppro,Pentium Ⅳ2.6GHz です。データベースは、IBです。
画面に、panelを5個、DBNavigator、DBMemoを4個、DBTextを14個貼り付けてあります。
DBMemo1の項目(数値を文字列として格納してある)を1行毎に取得し、この項目の総数だけ、動的にLabelを作成、各LabelのCaptionに各行に対応するDBMemo2項目(文字列)を割り当てるようにするために、いかのコードを作成し、DBNavigatorOnClickイベントへ割り付けました。動作は間違いなく行なうのですが、描写に時間がかかるよう、各Labelの作成過程が目に見てわかります。どなたか、良い方法を教えてください。現在のコードは、以下の通りです。
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBCtrls, StdCtrls, ExtCtrls, Mask;
type
KaisuArr = Array of Integer ;
ItemAr = Array of TLabel ;
DayAr = Array of TMaskEdit ;
TFrmSagyoDay = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
private
{ Private 宣言 }
SumKaiTen : Integer ; //それぞれの回数取得のため
TenkenKai,SumKai : KaisuArr ;
ItemLbl : ItemAr ;
DayMaskEd : DayAr ;
Procedure SonotaDisplay ;
public
{ Public 宣言 }
end;
var
FrmSagyoDay: TFrmSagyoDay;
implementation
uses Types, DMKanri;
{$R *.dfm}
procedure TFrmSagyoDay.DBNavigator1Click(Sender: TObject;
Button: TNavigateBtn);
begin
SonotaDisplay;
end;
procedure TFrmSagyoDay.SonotaDisplay; //点検項目の日付とラベルの表示
var I,s,j : Integer ;
begin
S := DBMemo1.Lines.Count ;
SetLength(TenkenKai,s);//配列の要素数を確定
SetLength(SumKai,s);//配列の要素数を確定
SumKaiTen := 0 ;
for I := 0 to S -1 do //配列へ格納
begin
TenkenKai[I] := StrToInt(DBMemo1.Lines[I]);
SumKaiTen := TenkenKai[I] + SumKaiTen; //点検時項目実施回数の合計を計算
SumKai[I] := SumKaiTen;
end;
//****以上、表示用の数を算出するため****
//以下、項目表示用のラベルの動的作成
SetLength(ItemLbl,SumKaiTen);//配列の要素数を確定
for I := 0 to SumKaiTen-1 do
begin
ItemLbl[I] :=TLabel.Create(self);
with ItemLbl[I] do
begin
Parent := Panel5;//Panel5に表示するため
Visible := True ;
Top := (15*I) +30 ;
Left := 15;
Tag := I;
end;
end;
//*******ラベルのキャプションを項目値に変換開始*****
I := 0 ;
j := 0 ;
while J <= S-1 do
begin
while I <= SumKaiTen-1 do
begin
with ItemLbl[I] do
begin
Caption := DBMemo2.Lines[j];
end;
inc(I);
end;
inc(J) ;
I :=SumKai[J-1];
end;
//*******ラベルのキャプションを項目値に変換終了*****
//以下、日付入力用のMaskEditの動的作成
SetLength(DayMaskEd,SumKaiTen);//配列の要素数を確定
for I := 0 to SumKaiTen-1 do
begin
DayMaskEd[I] :=TMaskEdit.Create(self);
with DayMaskEd[I] do
begin
Parent := Panel5;
Visible := True ;
Top := (15*I) +30 ;
Left := 150;
EditMask := '!9999/99/00;1;_';
end;
end;
SetLength(TenkenKai,0);
SetLength(ItemLbl,0);
SetLength(DayMaskED,0) ;
end;
Labelの位置が固定なら、最初からコントロールを配置しておいて、
不要なものは Visible = False なのはだめ?
Panel5.DoubleBuffered := True;
これは・・・あまり効果なさそう。。。
他には...
Panel5の下にLabelを置いて、Caption = '準備中...'; とかにする。
1) Panel5 を非表示
2) 項目表示用のラベルの動的作成
3) Panel5 を表示
Application.ProcessMessages を適当に挟んで。
いまいちやね。
ん?さん早々のレス有難うございます。
>Labelの位置が固定なら、最初からコントロールを配置しておいて、
>不要なものは Visible = False なのはだめ?
動的に作成するLabelとMaskEditの数が固定されていないので、無理だと思います。
>Panel5.DoubleBuffered := True;
>これは・・・あまり効果なさそう。。。
>他には...
>Panel5の下にLabelを置いて、Caption = '準備中...'; とかにする。
>1) Panel5 を非表示
>2) 項目表示用のラベルの動的作成
>3) Panel5 を表示
これも、試したのですが、Labelの表示、非表示時に少しストレスを感じます。
>Application.ProcessMessages を適当に挟んで。
いまいちやね。
ごめんなさい。
Labelの表示、非表示時にストレスではなく、Panelの表示、非表示時にストレスを少し感じます。です
> 動的に作成するLabelとMaskEditの数が固定されていないので、無理だと思います。
現レコードでは10個だけど、次のレコードに移動したら5個で済んだ。
じゃ、6〜10は、非表示にしよう。
その次は、20個(も)必要だ。
でも10個しかないから、残り10個追加しよう。
・・・ということで、表示・非表示を切り換えるのは?
現在のコントロール数を管理しておく必要はあるが、生成・破棄を無駄に繰り返さないと思うのですが。
こんな意味で書いたのだけど、通じなかったかしら?
最初の質問では、レコード移動毎に、全部のコントロールを破棄・生成を行っているように感じたから。
難しい書き方でごめんね。
以下のようにしても駄目ですか?
procedure TFrmSagyoDay.SonotaDisplay; //点検項目の日付とラベルの表示
var I,s,j : Integer ;
begin
LockWindowUpdate(Handle);
try
既存処理記述部
↓
finally
LockWindowUpdate(0);
end;
end;
ん?さん、Basserさんありがとうございました。
Basserさんの方法で期待通りの結果が得られました。