Предел размера массива Excel 2007 VBA - PullRequest
7 голосов
/ 19 октября 2011

Многочисленные источники, которые я обнаружил, предполагают, что размер массивов для кода VBA зависит от объема памяти в машине. Это, однако, не имело место для меня. Я запускаю следующий, очень простой код для тестирования:

Sub test6()
Dim arr(500, 500, 500) As Boolean
End Sub

Однако, если я изменяю размер на 600x600x600, я получаю ошибку нехватки памяти. Машина, на которой я работаю, имеет 16 ГБ ОЗУ, поэтому я сомневаюсь, что проблема в физической памяти.

Я использую Excel 2007. Есть ли хитрость в том, чтобы заставить VBA использовать больше оперативной памяти?

Ответы [ 3 ]

6 голосов
/ 19 октября 2011

Было бы неплохо, если бы была функция Application.UseMoreMemory(), которую мы могли бы просто вызвать: -)

Увы, я не знаю ни одного.

Все документы, которые я видел, говорят, что она ограничена памятью, но проблема не в физической памяти, а в виртуальном адресном пространстве, которое вам доступно.

Вы должны иметь в виду, что, хотя увеличение с 500 до 600 выглядит только как умеренное увеличение (хотя 20% само по себе достаточно велико), потому что вы делаете это в трех измерениях, оно получается почти вдвое больше требований к хранению.

Из памяти Excel 2007 использовал короткие целые числа (16 бит) для логического типа, поэтому, как минимум, ваш массив 500 3 займет около 250M (500x500x500x2).

Увеличение всех размеров до 600 даст вам 600x600x600x2 или около 432M.

Все в пределах доступного адресного пространства 2G, которое вы, вероятно, имеете на 32-битной машине (я не знаю, что в Excel 2007 была 64-битная версия), но эти вещи не маленький, и вы должны разделить это адресное пространство и с другими вещами.

Было бы интересно узнать, с какого момента вы начали получать ошибки.

В качестве первого шага я бы рассмотрел необходимость такого большого массива. Это может быть осуществлено по-другому, например, разделение массива так, чтобы только одна его часть находилась в памяти одновременно (своего рода виртуальная память вручную).

Маловероятно, что это действительно хорошо для действительно произвольного доступа, но не должно быть слишком плохо для более последовательного доступа и, по крайней мере, поможет вам (медленное решение предпочтительнее нерабочего).

Другая возможность - абстрагироваться от обработки битов, чтобы ваши логические значения на самом деле сохранялись в виде битов, а не слов.

Вы должны были бы предоставить функции для getBool и setBool, используя операторы битовой маски для массива слов, и, опять же, производительность не была бы такой высокой, но вы по крайней мере сможете тогда перейти к эквиваленту:

' Using bits instead of words gives 16 times as much. '
Dim arr(8000, 8000, 8000) As Boolean

Как всегда, это зависит от того, для чего вам нужен массив, и от особенностей его использования.

4 голосов
/ 19 октября 2011

После запуска некоторых тестов создается впечатление, что для 32-разрядного VBA установлено ограничение около 500 МБ, а для 64-разрядного VBA - около 4 ГБ (Excel 2010-64).Я не знаю, уменьшатся ли эти пределы VBA, если вы используете много рабочих книг / сводной памяти в одном экземпляре Excel.

0 голосов
/ 19 октября 2011

Как упомянул @paxdiablo, размер массива составляет около 400+ Мб, с теоретическим максимумом 2 Гб для 32-битного Excel. Скорее всего, макросы VBA ограничены в использовании памяти. Также блок памяти для массива должен быть непрерывным блоком памяти, что делает его выделение еще сложнее. Таким образом, возможно, что вы можете выделить десять массивов размером 40 Мб, но не один размером 400 Мб. Проверьте это.

...