エラー内容
エラー7(メモリが不足しています)はプログラムで利用するメモリ領域が不足している場合か、VBAのモジュールサイズが制限を超えている場合に出るエラーです。
エラー原因
エラー7は主に2つの原因で発生します。
1つはフォームや標準モジュールなどで1ファイルの最大サイズが64KBを超えた場合です。こちらの解決方法は簡単です。
もう1つは要素数が多い配列や動的配列を利用している場合で、VBAが利用できるメモリが不足している場合に発生します。特に多次元の動的配列を利用している場合に発生しやすいです。こちらはコードの修正が伴うことがありますので解決に時間が掛かることがあります。
エラー対応方法
モジュールが大きいことがエラー7の原因の場合は、モジュールを分割すれば解決します。関数が長くてモジュールの分割が出来ない場合は、関数内部の処理を細かい関数に切り出して、その上で新しく別の標準モジュールを追加し、そちらにpublicの関数として移動させることでモジュールの分割が出来ます。
問題なのは配列のサイズが大きい場合です。
以下はエラー7が発生する関数です。環境によっては発生しないかもしれないので、その場合は動的配列の値を変えて実行してみてください。
1 2 3 4 5 6 7 8 9 10 |
Sub Err7Test() Dim ar() Dim i ReDim ar(300000, 80) For i = 0 To 10 ReDim Preserve ar(300000, i + 80) Next End Sub |
結論から言うと、こんな大きい配列は使わないようにするしかありません。なんらかの方法で配列のサイズを減らすようにします。
あと、大きいサイズの場合は二次元配列もやめる方ことを検討した方がよいでしょう。
二次元配列で動的配列の場合、領域の確保のたびに処理時間がかなり掛かる欠点があります。
どうしても二次元配列のようなXとYの関係性が必要な場合は、1次元配列としてXとYを連結して持たせる形を取る方法などを採用します。
上のコードを1次元配列に変更した内容が以下になります。ついでですが、考え方の1例としてデータの持ち方も書いていますので参考にしてください。
配列の要素数が減るためエラー7は発生しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Sub Err7Test2() Dim ar() Dim i Dim s Dim div Dim div2 Dim str Dim l '// 300000 * 80がRedim Preserveで300000 * 90となる部分を1000分の1に変更 ReDim ar(27000) For i = 0 To 27000 ReDim Preserve ar(i) str = CStr(i) & "@" '// 1000分の1とした部分をここで/区切りで連結 For l = 1 To 1000 '// 「0@x1:y1/x2:y2/x3:y3/・・・・x1000:y1000」 str = str & "x" & CStr(l) & ":" & "y" & CStr(l) & "/" Next ar(i) = str Next For Each s In ar '// 「1@x1:y1/x2:y2/x3:y3/・・・・x1000:y1000」を@で左右に分割 div = Split(s, "@") '// 1000分の1用のため連結した文字列を/区切りで分割 div2 = Split(div(1), "/") For l = 0 To UBound(div2) Debug.Print div2(l) Next Next End Sub |
その他の対応方法として、事前に外部のテキストファイルやCSVファイルにデータを持たせておいてファイル処理を行うことや、Excelのセルにデータを入力しておいてそちらを参照する方法などを検討してみてください。