none
Excel VBAでExcelファイルを大量に複製するとメモリが解放されずに増大してしまう回避方法について RRS feed

  • 質問

  • お世話になります。

    VBAを組み込んだExcelファイル(以降File A)から複数のExcelファイルを複製していくとメモリが解放されず増大していきます。
    (1ファイル作成するごとに、大体50~100Mbytes増大していきます)
    最終的にはPCがフリーズします。(何ファイル目かは不明ですが、PCのメモリが枯渇したタイミングだと思われます)

    この事象ですが、VBAの修正(改善)等で回避する方法があるのか否かご教示頂くたく問い合わせをさせて頂きました。


    ※以下に処理内容を記載致しますが、その中に登場するファイル等の説明になります。
     ・File A  ⇒ コントロールファイル(実際にファイルを作成するVBAが組み込まれたファイルになります)
     ・File B  ⇒ 帳票ファイル(実際に作成されるファイルになります)
     ・製品A  ⇒ データベース
     
    実際にはVBS(VBScript)からFile A内のVBAのファンクションをコールしてExcelファイルを作成していきます。

    VBS及びVBAの具体的な処理の手順及び内容は以下の通りです。

    【VBS側】
     1.VBSからFile A内のVBA(Excelマクロ)を起動します。

      ・以下、VBSで使用している構文になります。
       ========================================================================
       Set XL = CreateObject( "Excel.Application" )
       XL.Workbooks.Open "File A"
       XL.Run "'" & XL.ActiveWorkbook.Name & "'" & "!" & "File A内のファンクション名", "配列名[5000,7]"
       XL.ActiveWorkbook.Close False
       XL.Quit
       Set XL = Nothing
       ========================================================================

    【Excel側】

     ・File A内のVBAで、VBSから受け取った配列の要素数分、2~6の処理を繰り返し実行します。

     2.VBSから受け取ったパラメータ(配列の中身)をFile Aの任意のシートに貼り付けます。
      ・以下、実際に使用している構文になります。
       ========================================================================
       range(セルアドレス) = 設定値
       Cells(行番号, 列番号).Value = 設定値
       ========================================================================

     3.データベースに接続し、データ取得をします。

      ・製品AのAPI関数を使用して自分自身のブックのシートにデータを取得します。

     4.File Aから任意のシートをコピーした新規ブックを作成します。(以降 File B)

      ・以下、実際に使用している構文になります。
       ========================================================================
       Workbooks(自ブック名).Sheets(自ブックで保持しているシート名の配列).Copy
       ========================================================================

     5.(4.)にて新規作成したブックのシートの情報をシートを選択してコピーした後、値貼り付けします。
      (※理由は参照式等が入っているためです)

      ・以下、実際に使用している構文になります。
       ========================================================================
       Cells.Select
       selection.Copy
       Worksheets(シート名).range(セルアドレス).PasteSpecial Paste:=xlValues, _
       Operation:=xlNone, SkipBlanks:=True, Transpose:=False
       ========================================================================

     6.File Bに名前を付けて任意のディレクトリに保存します。

      ・以下、実際に使用している構文になります。
       ========================================================================
       ActiveWorkbook.SaveAs フルパス
       ActiveWorkbook.Close
       ========================================================================

    ※その他の当該の事象の追加の情報としましては以下の通りとなっております。

     ・Excel のバージョンは、Office 2007 になります。

     ・対象のFile A のファイルサイズは、約300 KBytesです。
      File Bのファイルサイズは、100 KBytes以下となっております。

     ・Excel VBA内では変数使用後の明示的な解放は行っていませんが
      明示的な開放(変数の初期化)をしても増大しております。

     ・製品Aの処理部分をコメントアウトしても増大する為、製品AのAPI関数を使用することが
      原因ではないと思われます。

     ・試しに「DoEvents」の追加や、「Sleep」を1秒追加しても増大しております。

    以上が当該事象の説明になります。

    宜しくお願い致します。


    2015年9月15日 8:51

すべての返信

  • PasteSpecialメソッドの後、
    Application.CutCopyMode = False
    を入れても変わりませんか?
    2015年10月6日 1:42
  • minmin312様

    お世話になっております。

    ご回答誠にありがとうございます。

    さっそくご指示の通りに改修し、テストを実施致しました。

    その結果、残念ながら効果はありませんでした。

    以上取り急ぎご報告させて頂きます。

    2015年10月6日 5:57
  • 原因はわかりませんが、とりあえずの策として、新規ブックの作成を繰り返すのではなく一つのブックBを作成して、シートのコピー・削除を繰り返し、名前を付け替えて保存する仕様にするとか。


    • 編集済み minmin312 2015年10月6日 8:43
    2015年10月6日 8:30
  • minmin312様

    お世話になっております。

    たびたびのご回答誠にありがとうございます。

    ご指示の内容を実施するかどうか検討をしたのですが、改修に時間が相当かかりそうなため

    少し迷っているところです。

    御礼が遅くなり大変申し訳ありませんでした。

    以上です。

    2015年10月8日 6:57