大きなスプレッドシートでVBAコードを実行しています。「メモリ不足」の問題が発生しないように、プロシージャ/呼び出しの間にメモリをクリアするにはどうすればよいですか?
ありがとう
回避策を見つけました。最初はもっと時間がかかるように見えましたが、スワップが少なくなり、使用可能なメモリが増えるため、実際にはすべてがスムーズかつ高速に動作します. これは科学的なアプローチではなく、機能する前にいくつかのテストが必要です。
コードでは、Excel で時々ブックを保存するようにします。360,000 行のシートをループする必要があり、ひどく詰まってしまいました。10,000 回ごとにワークブックを保存するコードを作成しましたが、今では 32 ビット Excel でも魅力的に動作します。
同時にタスク マネージャーを起動すると、保存するたびにメモリ使用率が大幅に低下することがわかります。
メモリを解放する最善の方法は、大きなオブジェクトを無効にすることです。
Sub Whatever()
Dim someLargeObject as SomeObject
'expensive computation
Set someLargeObject = Nothing
End Sub
また、グローバル変数はある呼び出しから別の呼び出しに割り当てられたままであることに注意してください。そのため、永続化が必要ない場合は、グローバル変数を使用しないか、不要になったときにそれらを無効にする必要があります。
ただし、次の場合は役に立ちません。
もう 1 つの可能性は、クラッシュする前により多くの RAM を使用できる 64 ビット バージョンの Excel に切り替えることです (32 ビット バージョンは通常、約 1.3 GB に制限されています)。
答えは、明示的にはできませんが、ルーチンでメモリを解放する必要があります。
記憶を助けるためのいくつかのヒント
ルーチンを何度も実行した後、メモリリークが発生している可能性があるため、メモリ使用量を確認することをお勧めします。
私は自分自身で解決した同様の問題を抱えていました....「大きなもの」が多すぎて、部分的に私のコードがメモリを大量に消費していたと思います
私のアプリケーションでは、ワークブックが出て、別の部門の「日次レポート」を取得し、チームが必要とするすべての情報を抽出します (間違いやデータ入力を最小限に抑えるため)。
私は彼らのシートを直接引き込みます...しかし、彼らが結合セルを使用しているという事実は嫌いです...私はそれを取り除きます(つまり、結合を解除し、結果の空白セルを見つけ、上から値を入力します)
私は自分の問題を解決しました
a)単に列全体を実行しようとするのではなく、「使用されたセル」のみをマージ解除します...つまり、列で最後に使用された行を見つけ、この範囲のみをマージ解除します(取得した各シートには文字通り1000行あります) )
b) 元に戻すは、最後の ~16 個のイベントのみを監視することを知っています...各「マージ解除」の間に、保持されるメモリの量を最小限に抑えるために、「元に戻す」に格納されているものをクリアする 15 個のイベントを配置します (つまり、に移動しますデータを含むセル..およびコピー//特別な値を貼り付けます...それぞれ3列分のデータを含む30シートの累積合計が、元に戻すためのサイドとして設定されたメモリに負担をかけている可能性があると推測していました
はい、元に戻す可能性はありません...しかし、全体的な目的は、古い情報を消去し、分析のために新しい時間に敏感なデータを取り込むことであるため、問題はありませんでした
陳腐に聞こえますが、私の問題は解決しました