Страницы: 1
RSS
VBA: хранение 2-d массива констант, Как хранить в коде и как обращаться к такому массиву
 
Добрый день
Прошу помочь как сохранить массив констант в коде модуля (или еще где) чтобы из процедуры можно было к нему обращаться.
Предполагается обращаться к нему часто и должно работать быстро как обращение так и инициализация (если она потребуется)

У меня два решения и оба меня не устраивают в полной мере
1) через Ar2 = Array (Array(2,3,5), Array(7,8,9), Array(11,45,68)) . Но тут  обращение получается не стандартное Ar(2,1), а Ar(2)(1)
2) через Ar2 = Evaluate("{2,3,5;7,8,9;11,45,68}"). Но у меня выдает ошибку Error 2015 на массиве длинном (20*30 double по 10 знаков), хотя на коротком работает исправно.

Есть еще вариант тянуть из файла txt/csv и/или заполнять массив поэлементно, но это долго по времени.

Возможно есть какие-то решения этой задачи?
 
ваш код ведь сохранён в книге Excel, верно?
а где в Excel самое удобное место для хранения массива чисел, догадываетесь?
конечно же, самый обычный лист (который может быть скрытым и очень скрытым)

чтение с листа в массив: ar2 = Sheet2.range("a1:f12").value
где Sheet2 - кодовое имя листа

проще и удобнее, решения просто не придумать
и ограничений по размерам массива нет
 
Идея понятна и проста. Но если я буду считывать с листа - займет много времени. Операция многократная.
Возможно есть внутренние механизмы?
 
Цитата
Игорь написал:
и ограничений по размерам массива нет
Есть -память компа.
К примеру, у меня, при 2 Гигах, "помещается", ЕМНИП, 30 млн ячеек.
 
Если обращение частое в одной процедуре, то можно в начале процедуры загдать массив в словарь
 
Цитата
Александр Моторин написал:
Если обращение частое в одной процедуре, то можно в начале процедуры загдать массив в словарь
У меня сложнее. Несколько процедур и функций из разных модулей будут смотреть этот массив.
Как я понимаю в таком случае можно сделать глобальный массив без явного определения при декларации + процедуру считывания массива из листа в массив vba запустить вначале основной процедуры и всех остальных нуждающихся (можно с проверкой задан ли массив и если нет - вызов заполнения)
 
inkerman, по моему вы себе придумали проблему которой не существует.
считать массив из 600 элементов для вба вообще не проблема по времени в любом виде, если только вы работаете не на калькуляторе.
Код
1
2
3
4
5
6
7
8
9
10
11
Sub test()
    strt = Timer
    For i = 1 To 100
        arr = Cells(1, 1).CurrentRegion
    Next i
 
    fin = Timer
    vrem = fin - strt
       MsgBox (vrem * 1000)
 
End Sub

100 раз считал массив (30*21 ячеек с 15-значными числами) в переменную - 29 миллисекунд. Это долго?
 
Цитата
inkerman написал:
если я буду считывать с листа - займет много времени
Игорь ведь Вам показал, как считать с листа в массив:
Цитата
Игорь написал:
ar2 = Sheet2.range("a1:f12").value
Почему Вы решили, что это займёт много времени?
 
Можно из этого диапазона сделать именованный диапазон - например, MyRange
Код
1
2
Sheet2.range("a1:f12").Name = "MyRange"
arr = Range("MyRange").Value
There is no knowledge that is not power
 
Цитата
inkerman написал:
Предполагается обращаться к нему часто и должно работать быстро как обращение так и инициализация (если она потребуется)
Чтобы работа с массивом происходила быстро, он должен иметь правильный тип. Для чисел - Double, а если числа целые, то Long.
Массив можно считывать с листа один раз при открытии книги, и он будет доступен для всех процедур проекта. Примерно так
Код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'обычный модуль
Public ar2() As Double
 
Sub GetArr()
dim tmp,i&,j&
tmp=Range("MyRange").Value
redim ar2(1 to ubound(tmp),1 to ubound(tmp,2))
for i=1 to ubound(ar2)
  for j=1 to ubound(ar2,2)
    ar2(i,j)=tmp(i,j)
  next
next
end sub
 
'модуль книги
Private Sub Workbook_Open()
  GetArr
End Sub
При создании массива можно поменять индексацию, например чтобы она начиналась с 0, можно транспонировать массив и т.д.
Изменено: Казанский - 24.12.2015 12:37:04
 
Всем большое спасибо за участие и предложенное решение!
Страницы: 1
Читают тему
Наверх
Loading...