こんにちわん^^w
DELPHI6を使って数値データをExcelファイルに出力しているんですが速度的にかなり遅いんです(;;
どうすれば早くなるでしょうか?
どのような手法で、何件のデータを入れているか解らないので、誰も答えられないと思います。
強いて答えるならば、ハードウェアのスペックをあげましょう。
可能な限りメモリを積み、可能な限り高スペックなCPUを載せて実行しましょう。
ハードディスクの書き込み速度も意外とネックになりますので、ディスクもやい物にするか、RAM上にファイルを置き、そこで書き換えてから戻した方が早くなります。
脱字です。
> ディスクもやい物にするか
正しくは
> ディスクも早い物にするか
エクセル側の再計算処理を一時的に止めてみては?
お役に立てれば幸いです。
どこが遅いのか具体的に書いたほうがレスが付くと思いますよ。
数年前のことなのでコードはよく覚えていませんが、
配列を使用すると早くなったと記憶しています。
たとえば、100個の整数型の値があったとします。
①この100個の値をひとつひとつセルにセットしていては
非常に遅くなります。
②100個の値を配列にまとめ、配列で出力すると劇的に速くなります。
つまり、
Values : array [0..99] of integer;
とし、
①の方法(遅い方法)
for i:=0 to 99 do
begin
Cell(A,i+1) := Values[i]; //Excelの指定のセルへ値をセットする
end;
②の方法(速い方法)
Cell(A1) := Values; //配列ごとまとめて出力
※上記コードでおおまかな意味は伝わると思いますが、
コードはよく覚えていないのであてにしないで下さいね。
あとはソフトの構成ですが、
・配列による出力をうまく利用
・セルへのセット回数をできるだけ少なくなるようにする
これらを考慮すればそれなりの速さは得られるのではないでしょうか。
>どのような手法で、何件のデータを入れているか解らないので、誰も答えられないと思います。
すいませんでした!!
えっと数値と文字列をvExcel.ActiveSheet.Cells[1,1] := '';
というように指定のCellに直接出力しているような感じで作成しています。
30行500列くらいのデータを全てループで回して指定したCellに描画する
ようなソースです。
>エクセル側の再計算処理を一時的に止めてみては?
再計算処理を一時的に止める?ごめんなさい;;わかんないです;;
>②の方法(速い方法)
> Cell(A1) := Values; //配列ごとまとめて出力
配列に設定したデータは指定したCellに出力できますか?
Cell(A1)を基準に出力するような感じですか?
Excelに書き込んでいる時にExcelを見せないようにするとかはどうでしょう?
Excelに書き込みが完了してから、表示することで少しは早くなると思います。
的外れでしたらごめんなさい
以前やったことがあるのですが・・・
計算以外で罫線・書式設定等を設定するときに、
セルをあちこち移動すると時間がかかりました。
同じ動作?をさせるときは
Range(A1:C10).〜 := 〜
のような感じで指定してあげると速度が速くなった覚えがあります。
Excelへの書き込みはExcelVBAで行うがいちばん高速です。
具体的には、
CSVなどの一時ファイルにデータを書く。
Excelを立ち上げ、マクロを起動。
マクロでは新シートにCSVファイルをオープンして、適当なセルにデータを移す。
似たような事をしていますが、うちではクリップボード経由で貼り付けています。
このようなデータをExcel出力したいとすると
A B
1 [1.1][1.2]
2 [2.1][2.2]
3 [3.1][3.2]
4 [4.1][4.2]
var
Values : array of Double;
BeginCell , EndCell : OleVariant ;
ExcelWorksheet : TExcelWorksheet; //Serversのコンポーネント
とし、
SetLength(Values,4,2);
try
//Valuesに値をセット
for r:=Low(Values) to High(Values) do
begin
for c:=Low(Values[r]) to High(Values[r]) do
begin
Values[r,c] := (r+1) + (c+1)/10;
end;
end;
//出力開始セル
// ここではA1のセルとしている
BeginCell := ExcelWorksheet.Cells.Item[1,1];
//出力範囲を考慮して終了セルを決定
EndCell := ExcelWorksheet.Cells.Item[BeginCell.Row + Length(Data)-1
,BeginCell.Column + Length(Data[0])-1];
//Excelに出力
ExcelWorksheet.Range[BeginCell,EndCell].Value := Values;
finally
SetLength(Values,0,0);
end;
DelphiにはExcel出力関連のヘルプがなかったと思います。
ExcelについているVBAのヘルプを参考にして確認しながら
実装しましょうね
※上記コードはデバッグしていません。調整願います。
遅い速いは,主観的なもので,実際にどの程度なのかが不明ですが,
また,私のExcel(Excle200)では500列は扱えませんので,
300行,256列に2回実数値を代入する実験をしてみました.
バリアント配列に,予め数値を代入しておき,Excelのセルの(1,1)から
(300,256)の範囲にバリアント配列をセットしました.
WindowsXP(SP1)+Delphi5(UP1) Pen4 2GHz 1,000MB のメモリの環境で
テストしたところ,約280msでした.
直接セルに数値をセットしているテストはしていませんが,
データベースから取得した値をセットするテストでは,
(109行4列)
セルに直接値代入の場合 3,500ms
バリアント配列使用の場合 100ms
でした.
ツイート | ![]() |