tldr;
Вы не можете "обработать" это - LongLong
не совместимо с вашим утверждением ReDim
.(Хотя 999999999
технически вписывается в Long
, компилятор не допускает там сужающего преобразования).
Максимальный размер любого массива в VBA определяется SAFEARRAY
структура (определена в разделе 2.2.30.10 спецификации OLE Automation Protocol), для которой она поддерживается внутренне.Определение структуры в C ++ таково:
typedef struct tagSAFEARRAY {
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
PVOID pvData;
SAFEARRAYBOUND rgsabound[1];
}
Обратите внимание, cbElements
размер в байтах элемента массива.Это эффективно ограничивает каждый элемент до ~ 4 ГБ.
Проблема, с которой вы столкнулись, заключается в SAFEARRAYBOUND
структурах , которые хранят информацию о размерах массива:
typedef struct tagSAFEARRAYBOUND {
ULONG cElements;
LONG lLbound;
} SAFEARRAYBOUND, *LPSAFEARRAYBOUND;
Это означает, что максимальное количество элементов, которое вы можете втиснуть в любое измерение SAFEARRAY
независимо от языка программирования, равно ULONG_MAX
(4 294 967 295).Таким образом, следующие компиляции (хотя на моей машине не хватает памяти при выделении):
Dim foo(-2147483646 To 2147483647) As Byte
Обратите внимание, что в приведенном выше примере нижняя граница отрицательна, поскольку VBA также не поддерживает неподписанные типы,что представляет собой другое препятствие для кода VBA, который определяет размеры массивов.Технически вы можете получить массив с границами 0 To 4294967294
, запросив его через функцию SafeArrayCreate , экспортированную oleaut32.dll, но я подозреваю, что вы столкнетесь с подобными проблемами при индексации.
Сняв слои еще дальше, вы начинаете преодолевать некоторые из наиболее интересных пределов.Например, оглядываясь на структуру SAFEARRAYBOUND
выше, вы заметите, что, хотя у вас может быть ULONG_MAX
элементов , нижняя граница массива ограничена знаком LONG
.Это ограничение переносится на большинство других OLE-автоматов, которые занимаются обработкой SAFEARRAY
с, включая SafeArrayGetLBound
и другие (интересно, что SafeArrayGetUBound
- это также подписано, что заставляет меня задуматься, не могли бы вы переполнить его ...).
Так почему же MS не обновили это, когда добавили 64-битную поддержку?Ну, это сломало бы в значительной степени все .Кроме того, на самом деле не было никакой насущной необходимости - как только вы выйдете за пределы ULONG
элементов, вы начнете сталкиваться с очень реальными проблемами с памятью в том, что память для области данных должна быть выделена , когдаструктура создана - в противном случае ее невозможно использовать через COM, поскольку в корне этой структуры находится указатель, а в контракте говорится, что вызывающий код (независимо от клиента) должен иметь возможность использовать любой адрес, попадающий вобласть данных, включая VBA.