エクセルファイル帳票の改善について

解決


Fine  2005-07-25 23:53:14  No: 91078

現在、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


いな  2005-07-26 00:58:41  No: 91079

XL側でどんなマクロを書いているか?にもよりますが

・Active〜系の宣言はやめる。
・Copyの仕方をCtrl + C & Crrl + Vのやり方ではなく、
  Drag and Dropのやり方に変更(マクロの記録で確かめてください。)


Fine  2005-07-26 01:16:50  No: 91080

いなさん、返信ありがとう御座います。
説明不足で申し訳ありません。
作成したエクセルは帳票の形になっており、セルなどに名称を定義してVBからデータセットをしています。
これにより、エクセルの見た目を変更するのがユーザで簡単に行えるという利点があるため、この方式で行っています。
その為、エクセルにはマクロは組み込んでいません。
VBAも使用しておらず、全てVBからデータをセットしています。
それなのにバックグラウンドでの起動時に時間やメモリの消費が激しいため、質問させていただいております。
実際のデータセットなどもまだ見直しが必要かもしれませんが、制御でのレスポンスは現在は問題ありません。
以上、よろしくお願いします。


特攻隊長まるるう  2005-07-26 03:58:10  No: 91081

具体的な数字が書いてないから雲を掴む様な話だなぁ…。
実行環境のPCのスペックはどのくらいで、
処理してる Excel ファイルの大きさは何 KB で、
5回ほど手動でそのファイルを開いた時とプログラム
から開いた時の時間をストップウォッチで計った平均の
差はプログラムの方が何秒遅くて、
その時にメモリ消費量の推移は手動が何 KB 消費されて
プログラムからだと何 KB 消費されるの?
>制御でのレスポンスは現在は問題ありません。
開いた後にデータを書き換える部分では問題ないという事?
ファイルを開く時限定で考えていいんだよね?


いな  2005-07-26 04:29:03  No: 91082

>バックグラウンドでの起動時に時間やメモリの消費が激しい
とは、通常オペレーション(手動でExcelを開いた)のときと比較して、
メモリの消費が激しいのでしょうか?

ん〜、経験ないなぁ〜。


Fine  2005-07-26 05:00:33  No: 91083

委託ソフトではないため環境はユーザ任意となりますが、ちょいと横にあるサーバでの数値を記載します。

・Windows2003 Srv
・Office 2003
・Pentium4 3GHz
・Memory 512M
ファイルサイズとしては80Kです。
そのエクセルをそのまま開くと、3秒でVBから開くと4秒前後(少し波があります)
メモリ消費はOpenまでは通常で開くと12k  1秒弱
VBからでは15〜17k  2秒弱
本来のユーザPCはもっと低スペックなのでこの差が大きくなっていきます。

>開いた後にデータを書き換える部分では問題ないという事?
>ファイルを開く時限定で考えていいんだよね?
はい。そうです。早く開く時の何かコツなどがあればご教授願いたいです。

>とは、通常オペレーション(手動でExcelを開いた)のときと比較して、
>メモリの消費が激しいのでしょうか?
ある程度は致し方ないと思うのですが、これを改善できたらと思いまして

>ん〜、経験ないなぁ〜。
そうですか。Office2000の頃は結構サクサク動いていたのですがXP移行なぜか遅くなってしまいました。


Dental  2005-07-26 08:03:46  No: 91084

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を何度も開いたり閉じたりするのではなく、一回だけ生成して、
それを再利用するな形にすれば、少しはマシになる……かも。


Dental  2005-07-26 20:08:26  No: 91085

あー。コメントが逆になってるし、変数名もおかしいや。訂正。

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だと、参照設定せずに組んだ方が実行効率がよいのかな。


Dental  2005-07-26 20:25:01  No: 91086

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秒。

なお、いずれも実験を繰り返すたびに処理速度が向上。
キャッシュされるのかな。


Fine  2005-07-26 22:16:08  No: 91087

Dentalさん、大変参考になりました。
指摘内容にて改善を行ってみます。
ひとまず解決にしておきますが、自分なりに回答が見つかればまた報告させていただきます。
ありがとう御座いました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加