現在、VB6.0からエクセルで作ったファイルにデータをセットして出力するプログラムを作成しています。
この動作自身は問題ないのですが、エクセル起動時のメモリ消費と起動時間がちょっとかかりすぎていて困っています。
メモリ消費で場合のよると意図しない動作を行うこともあります。
VBの質問とは違うのですが、同様の悩みで改善された方がいらっしゃれば案をお教え願えないでしょうか?
Office XP/2003
(参考)
If PobjComDllLid.kfnc_FileNmae(strPath, strFileName) <> True Then
Exit Sub
End If
'//オブジェクト生成
Set lobjExAppl = PobjComDllLid.kfnc_ExcelOpen
If lobjExAppl Is Nothing Then
Set lobjExAppl = Nothing
Exit Sub
End If
'//帳票ファイルOPEN(読み取り専用)
Set lexWbappl = lobjExAppl.Workbooks.Open(strPath & strFileName, , ReadOnly:=True)
'2005/07/13 KUDO Me.MousePointer = vbArrowHourglass '砂時計表示
objMyForm.MousePointer = vbArrowHourglass '砂時計表示
lobjExAppl.Screenupdating = False
XL側でどんなマクロを書いているか?にもよりますが
・Active〜系の宣言はやめる。
・Copyの仕方をCtrl + C & Crrl + Vのやり方ではなく、
Drag and Dropのやり方に変更(マクロの記録で確かめてください。)
いなさん、返信ありがとう御座います。
説明不足で申し訳ありません。
作成したエクセルは帳票の形になっており、セルなどに名称を定義してVBからデータセットをしています。
これにより、エクセルの見た目を変更するのがユーザで簡単に行えるという利点があるため、この方式で行っています。
その為、エクセルにはマクロは組み込んでいません。
VBAも使用しておらず、全てVBからデータをセットしています。
それなのにバックグラウンドでの起動時に時間やメモリの消費が激しいため、質問させていただいております。
実際のデータセットなどもまだ見直しが必要かもしれませんが、制御でのレスポンスは現在は問題ありません。
以上、よろしくお願いします。
具体的な数字が書いてないから雲を掴む様な話だなぁ…。
実行環境のPCのスペックはどのくらいで、
処理してる Excel ファイルの大きさは何 KB で、
5回ほど手動でそのファイルを開いた時とプログラム
から開いた時の時間をストップウォッチで計った平均の
差はプログラムの方が何秒遅くて、
その時にメモリ消費量の推移は手動が何 KB 消費されて
プログラムからだと何 KB 消費されるの?
>制御でのレスポンスは現在は問題ありません。
開いた後にデータを書き換える部分では問題ないという事?
ファイルを開く時限定で考えていいんだよね?
>バックグラウンドでの起動時に時間やメモリの消費が激しい
とは、通常オペレーション(手動でExcelを開いた)のときと比較して、
メモリの消費が激しいのでしょうか?
ん〜、経験ないなぁ〜。
委託ソフトではないため環境はユーザ任意となりますが、ちょいと横にあるサーバでの数値を記載します。
・Windows2003 Srv
・Office 2003
・Pentium4 3GHz
・Memory 512M
ファイルサイズとしては80Kです。
そのエクセルをそのまま開くと、3秒でVBから開くと4秒前後(少し波があります)
メモリ消費はOpenまでは通常で開くと12k 1秒弱
VBからでは15〜17k 2秒弱
本来のユーザPCはもっと低スペックなのでこの差が大きくなっていきます。
>開いた後にデータを書き換える部分では問題ないという事?
>ファイルを開く時限定で考えていいんだよね?
はい。そうです。早く開く時の何かコツなどがあればご教授願いたいです。
>とは、通常オペレーション(手動でExcelを開いた)のときと比較して、
>メモリの消費が激しいのでしょうか?
ある程度は致し方ないと思うのですが、これを改善できたらと思いまして
>ん〜、経験ないなぁ〜。
そうですか。Office2000の頃は結構サクサク動いていたのですがXP移行なぜか遅くなってしまいました。
Excelは、参照設定して使ってます? それとも参照設定なし?
別スレッドのオブジェクトを利用するときは、むしろレイトバインドの
方が、マーシャリングのコストがかからないという話を聞いた事が
あるような気が……自信なし。
ためしに、ActiveX EXE作って、
For L = 1 To LIMIT 'アーリー
Set O = CreateObject("Project1.Class1")
O.Test
Set O = Nothing
Next
と、
For L = 1 To LIMIT 'レイト
Set C = New Class1
C.Test
Set O = Nothing
Next
の速度差を見たら、なぜか後者の方が遅かったという。。。うちだけ?
(前者の処理時間を 1.0 とすると、後者は 1.6 ほどの時間がかかった)
だけど、
Set X = 〜
For N = 1 To LIMIT2
X.Test
Next
Set X = Nothing
のように、生成部ではなく、メソッド呼び出し部だけ繰り返した場合は、
ほとんど速度差が無かったです。(1.00 対 1.01ぐらい)
で、どうもメソッドの呼び出しよりも、インスタンスの生成の方が
コストがかかるらしいので(たまたまかも?)、改善案としては、
Excelを何度も開いたり閉じたりするのではなく、一回だけ生成して、
それを再利用するな形にすれば、少しはマシになる……かも。
あー。コメントが逆になってるし、変数名もおかしいや。訂正。
Dim O As Object
For L = 1 To LIMIT 'レイト
Set O = CreateObject("Project1.Class1")
O.Test
Set O = Nothing
Next
Dim C As Class1
For L = 1 To LIMIT 'アーリー
Set C = New Class1
C.Test
Set C = Nothing
Next
うちの環境だと、LIMIT=1000ぐらいにした時に、上記のコードで、
レイトが3.8秒、アーリーが7.4秒という結果に。
VB6製ActiveX EXEだと、参照設定せずに組んだ方が実行効率がよいのかな。
Excelで実験。やはり、参照設定無しの方が早いようで。
◎起動と破棄の繰り返し
Dim O As Object
For L = 1 To LIMIT
Set O = CreateObject("Excel.Application")
O.Quit
Set O = Nothing
Next
→ 50回繰り返しで、5.5秒。
Dim C As Excel.Application
For L = 1 To LIMIT
Set C = New Excel.Application
C.Quit
Set C = Nothing
Next
→ 50回繰り返しで、5.9秒。これなら誤差範囲かな。
◎プロパティ呼び出しの繰り返し
Dim O As Object
Set O = CreateObject("Excel.Application")
For L = 1 To LIMIT
X = O.Workbooks.Count
Next
O.Quit
Set O = Nothing
→ 1000回繰り返しで、1.9秒。
Dim C As Excel.Application
Set C = New Excel.Application
For L = 1 To LIMIT
X = C.Workbooks.Count
Next
C.Quit
Set C = Nothing
→ 1000回繰り返しで、3.1秒。
なお、いずれも実験を繰り返すたびに処理速度が向上。
キャッシュされるのかな。
Dentalさん、大変参考になりました。
指摘内容にて改善を行ってみます。
ひとまず解決にしておきますが、自分なりに回答が見つかればまた報告させていただきます。
ありがとう御座いました。
ツイート | ![]() |