500万件程のデータが入っているテキストファイルのデータをDBにインポート
する時に、進行状況を表示する為ゲージを使用したいのですが、データが
大量にあるせいかゲージが進みません。というかアプリ自体がフリーズ(応答なし)の様な状態になってしまいます。数万件程度なら問題なくできました。
何か対策はありますでしょうか?
Delphiのバージョンは何でしょうか?
使ったコンポーネントは、何でしょうか?
標準でゲージというのが有るのでしょうか?
フリーズして、全くインポートできないのでしょうか?
数万件の場合は、表示も変化して処理できるのでしょうか?
こんなんでどうでしょう。
var
i: Integer;
SL: TStringList;
begin
SL := TStringList.Create;
try
SL.LoadFromFile('ほにゃらら');
ProgressBar1.Min := 0;
ProgressBar1.Max := 100;
ProgressBar1.Position := 0;
for i:=0 to SL.Count-1 do
begin
if (i mod 100) = 0 then
begin
ProgressBar1.Position := (i * 100) div (SL.Count-1);
Application.ProcessMessages;
end;
// 処理
end;
ProgressBar1.Position := ProgressBar1.Max;
Application.ProcessMessages;
finally
SL.Free;
end;
end;
大量にデータがある場合、Application.ProcessMessagesを挟まないと
ゲージの描画が更新されずにフリーズ状態のように見えます。
だからと言って普通にループにApplication.ProcessMessagesを挟むと
今度はApplication.ProcessMessagesに時間を取られて処理完了に
時間が掛かるようになります。
上記サンプルでは100ループに一回、画面の更新が行われるようになっています。
> 標準でゲージというのが有るのでしょうか?
[Samples]にあるTGaugeの事かと。
上記サンプルソースではTGaugeではなく
[Common Controls]にあるTProgressBarを利用していますが。
# TGaugeへの改変は難しくないと思います。
古いDelphiでは、TGaugeのMinValue/MaxValue/Progressの型が小さく
(16bit Integerだったかな?)
あまり大きな値をMaxValue/Progressにセットすると
ゲージが正常に進まなくなるという問題があった気がします。
# そのため、私は今でもゲージ(プログレスバー)の範囲を
# 0-100固定にし、位置を100分率計算しています。
説明不足で申し訳ありません
Delphiのバージョンは何でしょうか?→Delphi7です
使ったコンポーネントは、何でしょうか?→[Samples]にあるTGaugeです
標準でゲージというのが有るのでしょうか?
フリーズして、全くインポートできないのでしょうか?
→処理自体は出来ています。
数万件の場合は、表示も変化して処理できるのでしょうか?
→全く問題ありません。
DEKOさん
この様な現象があるとは知りませんでした。
勉強になりました。
このゲージは実行ボタンを押した時に別のフォームを表示して(ダイアログの様な感じ)そこに貼り付けているのですが、そのフォームのゲージに下に
「更新中・・・」というラベルも貼り付けているのですが、文字が表示されません。やはり同じ原因なのでしょうか?
>やはり同じ原因なのでしょうか?
ソースを見た訳ではないので何とも言えませんが、
一般的にはApplication.ProcessMessagesを挟まなければそうなりますね。
D7のHelpにはこう書いてあると思います。
メッセージ処理を無視すると,ProcessMessages メソッドを呼び出すアプリケーションだけに影響し,そうでないアプリケーションには影響しません。時間のかかる処理を行うときに ProcessMessages を定期的に呼び出すようにすれば,アプリケーションが描画や他のメッセージに応答することが可能になります。
Application.ProcessMessagesを挟むことで、ゲージ、ラベル共に
問題を解決できました。
大量のデータを扱ったことがなかった為、初めての現象でしたが、
勉強になりました。
ありがとうございます。
.
解決
チェック忘れだね
ツイート | ![]() |