
Excel VBAでは大きな配列を生成しようとすると
メモリ不足でエラーが出るため、
どの程度のサイズまで作れるか試してみました。
Dim aaa() as Single
ReDim aaa(xxxxx)
というようにして定義しています。
Singleの配列を一つの場合には、
132813299
が上限であることが分かりました。
Singleの配列を2つの場合には、
132813299
130009804
が上限となりました。
Singleの配列を3つの場合には、
132813299
130009804
9
が上限となりました。
なぜか3つめは9より大きな配列を作ることができません。
それで配列サイズを小さくして試してみたところ
60000000
60000000
60000000
60000000
60000000
32000000
のようにして、3つの場合の合計よりも
大きなメモリを確保することができました。
つまり、合計のサイズに上限が決められているわけでもなく
配列一つ一つのサイズに上限が決められているわけでもないということが分かりました。
一体どういう法則でメモリサイズの上限が決定しているのでしょうか?
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
まず配列があるプログラム共通ですが、絶対的な配列の限界としてaaa(xxxxx)のxxxxxに限界があります
xxxxxはプログラム上変数として扱われており、変数が扱える数の限界が存在します
その限界が"132813299"だと思われます
変数の限界に関してはVBAならIntegerやLongなどを調べると記載されていますが、元から変数としての最大値が決定されているため、メモリにどれだけ余裕があろうとそれ以上取る事はできません
そのため配列を増やすと変数の上限は回避できます
ここからは完全に予測なりますが、前述のとおり配列の数を表すのにも変数が使われております
そして変数は型を宣言した時点で、通常はメモリが確保されています
特に動的配列は配列の数を変更する度に、使用するメモリサイズを宣言しなおしているため、動的配列として扱えてます
ここで問題となるのは事前に確保されるメモリの話で10個程度の配列を表すのに、"132813299"の数を表せる変数を使うのはメモリの無駄です
ですから無駄を避けるためには、小さ目の型でメモリを確保して置き、後から必要となった際に大きな型に変更する処理を行っていると思われます
この結果、配列の数を表す変数に大きくメモリサイズが消費されていない細かく分割した3番目のケースが最も効率よく配列を多く取れたとしても不自然ではありません
配列の大きさで変わる原因としては以上が考えられます
最もシステムのメモリ使用状態が同一であると仮定した上での話ですから、複数回試さないと確実とは言えません

No.2
- 回答日時:
それはExcelというアプリケーションの構造に由来する話になるでしょう。
まず、どういった確保方法であれ、Windowsの32ビットアプリケーションで使用できるメモリの最大量(2GB)が絶対の上限として存在します。この2GBの中でVBAとExcel本体が使用するメモリの両方をやりくりするので、VBAが使用できる量は当然ながらもっと少なくなります。
またExcel本体側のメモリ使用状況によっては、空きメモリ領域が複数に分断されているかも知れません。例えばVBA側にメモリを1GB渡せるとしても、それは1つの固まりではなく、128MBや64MBなどの断片をかき集めたものかも知れないと言うことです。メモリの使用状況は予測が難しいため、最初から断片になることを見越して、あまり連続するメモリを取れなくしてある可能性も十分にありえます。配列は連続するメモリ領域に収まる分しか確保できないため、これが配列を小さくした方が、トータルではより多い配列を確保できる理由として考えられる点です。
メモリ使用状況起因だとすると、今出ている数値はどのPCでもそうなるとは限らないし、もしかすると今のそのPCでも毎回そうなる保証がないということになります。
No.1
- 回答日時:
先に断っておきますが、私はVBAについての見識はほとんどありません。
ですのでうそ情報かもしれないことを念頭にお聞きください。
あくまでプログラム全般の法則として回答します。
まずさきに質問の答えとしては、
「合計のサイズに上限が決められている」だと思われます。
プログラムのメモリ確保にはスタックとヒープからの二種類の確保があります。
スタックから確保されるのは、関数のなかのローカル変数のメモリ割り当てになります。
今回のReDimの場合は、おそらくヒープからメモリ確保されているように思います。
ヒープからのメモリ確保というのは、ヒープというある程度大きいメモリから要求されたサイズの
メモリを割り当てることです。
今回のケースでの確保できる最大値というのは単純にヒープのサイズに依存するということです。
ですが、ヒープとは他からもメモリを確保されるため、
すでに使用されている分だけ確保できるメモリサイズは小さくなります。
また、メモリの確保と開放(ReDimでサイズを変えたり、不要なオブジェクトにnullを代入したり等)を行うことで
ヒープは分断化され確保できるメモリの最大値が変わってきます。
(おつかいのVBAのバージョンによっては、可能な限り確保する努力をしてくれるはずですが)
ヒープのサイズに関してですが、こちらはPCの環境(エクセルのバージョンやPCのスペック)に
依存するかと思いますので、ご自身のPCでメモリ確保できたものが、
別のPCではメモリを確保できないなどの現象もあるかもしれません。
不用意に巨大なメモリ確保を行うようなマクロは控えたほうがいいと思います。
ちなみに132813299の値を調べる際どのようなコードで調べられたでしょうか?
下記のようにループで検証した場合、ReDimの仕様上(新しいメモリへデータをコピーする可能性もある)
ヒープ上に以前の確保したメモリと、
これから新規に確保しようとしたメモリの二つが存在する可能性があり、
単純に最大サイズを検証することはできないと思います。
i = 1
Do
i = i + 1
ReDim aaa(i)
While
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- ホームページ作成・プログラミング グリッドレイアウトHTMLとCSS 1 2023/02/22 02:36
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- JavaScript Javascript の配列の削除 (初心者) 4 2022/05/02 11:12
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- Java Java 南京錠 2 2023/02/04 11:46
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- Visual Basic(VBA) 複数シートの複数列に入力されているデータを重複なしで抽出するVBAを作りたいです。 9 2022/06/17 10:33
- Perl perl このテキストファイルを簡単に配列に入れるには? 2 2022/04/27 20:24
- Visual Basic(VBA) 【VBA】写真の縦横比を変えずに貼り付ける 5 2023/06/13 11:42
このQ&Aを見た人はこんなQ&Aも見ています
-
vbaのエラー対応(実行時エラー7:メモリが不足しています)
Visual Basic(VBA)
-
エクセルVBA 配列からセルに「関数式」を一気代入したい
Visual Basic(VBA)
-
配列をEraseしてもメモリが開放されていない?
Visual Basic(VBA)
-
-
4
Excelのメモリ(配列)の上限は2Gではないのか
Excel(エクセル)
-
5
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
6
メモリが不足しています(VBA)
Visual Basic(VBA)
-
7
VBA 1次元配列を2次元に追加する
Visual Basic(VBA)
-
8
worksheetFunctionクラスのVlookupプロパティを取得できません エラーへの対応
Visual Basic(VBA)
-
9
エクセルVBA 2千万行のCSVファイルを開きたい
Visual Basic(VBA)
-
10
Application.ScreenUpdating = Falseが効きません
Visual Basic(VBA)
-
11
array関数で格納した配列の型を変更する
Visual Basic(VBA)
-
12
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
13
VBA シートをコピーする際に Copyメソッドは失敗しましたのエラーが出てしまいます
Visual Basic(VBA)
-
14
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
15
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
16
EXCELのVBAで作業ファイルを閉じてもメモリの解放をしなくて困っています
Excel(エクセル)
-
17
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
18
VBAを何回も作り直して、容量が増えた
Excel(エクセル)
-
19
IF関数で空欄(")の時、Nullにしたい
その他(Microsoft Office)
-
20
DoEventsが必要な理由について
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
メモリが不足しています(VBA)
-
計算速度が遅い
-
メモリのセグメント違反の解決...
-
バッチファイルでの実行EXEのメ...
-
VBAの配列サイズとメモリに関して
-
PC-98で拡張メモリを使え...
-
「memcpy」と「strcpy」について
-
組み込み系でのmallocについて
-
エクセルのメモリ使用状況/Appl...
-
エクセルVBA 大容量CSVファイル...
-
DirectDrawによるブレンディン...
-
malloc関数の使い終わった後の...
-
closeとメモリの開放について
-
Macターミナルで実行中のプログ...
-
家電製品の電力周波数を変える機械
-
ウインドウにデータを入力する...
-
VBSでのSendKeysでの画面の最小化
-
ACCESS側からEXCELの書式を設定...
-
第三者に画面を同期するソフト...
-
フィボナッチヒープです
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
メモリが不足しています(VBA)
-
メモリのセグメント違反の解決...
-
「memcpy」と「strcpy」について
-
メモリ不足
-
「ヒープサイズの設定」て何?
-
エクセルのメモリ使用状況/Appl...
-
C言語における再帰呼び出しの...
-
ファイルマッピング関数で失敗
-
ExitProcessの関数コールについ...
-
EXCEL-VBAにてADOのレコードセ...
-
エクセルVBA 大容量CSVファイル...
-
ExcelのVBAでメモリ解放できない
-
メモリを解放しないとどうなる?
-
バッチファイルでの実行EXEのメ...
-
ルネサスマイコン(R8C) ビルド...
-
Bitmapを重ね合わせる方法
-
C,C++プログラムの強制終了時の...
-
C言語:関数のメモリ上でのサイ...
おすすめ情報