Заполнение динамических многомерных массивов массивов массивов Excel VBA. Динамические массивы vba
VBA. Язык VBA. Массивы в VBA
Язык VBA
Язык VBA
Язык VBA достаточно простой. Ниже приводится краткий курс языка VBA. Аббревиатура VBA означает Visual Basic for Applications, т.е. Visual Basic для приложений.
Объявление переменных в VBA
Пример объявления локальной переменной в VBA:
Dim intVar As Integer
здесь объявлена локальная, т.е. видимая в пределах функции, переменная типа Integer.
Пример объявления глобальной переменной в VBA:
Public intVar As Integer
такая перемнная доступна из своего и других модулей.
Пример объявления переменной, видимой только в своём модуле:
Private intVar As Integer
Пример объявления статической переменной в VBA:
Dim Static intVar As Integer
Статические переменные в VBA можно объявлять только на уровне процедуры. Значение статической переменной в этом примере равно нулю, т.е. при объявлении числовая переменная инициализируется нулем.
Особенность объявления переменных в VBA состоит в том, что переменную можно и не объявлять, но использовать. Тип таких переменных – Variant. Но рекомендуется объявлять переменные, указывать их тип, а не использовать тип Variant.
Константы в VBA
Константы в VBA объявляют с помощью Const:
Const intValue As Integer = 1234
Константам значение присваивается при их объявлении.
Массивы в VBA
Пример объявления массива в VBA:
Dim intArray(0 To 5) As Integer
объявлен массив типа Integer, индексы элементов изменяются от нуля до пяти.
Многомерные массивы в VBA
Пример двумерного массива в VBA:
Dim intArray(0 To 5, 0 To 2) As Integer
Динамические массивы в VBA
Динамические массивы могут изменять свой размер. Объявление динамического массива:
Dim intArray() As Integer
здесь размер массива не указан. Но перед использованием такого массива следует объявить его размер:
ReDim intArray(5)
Можно и изменить его размер после предыдущего определения:
ReDim intArray(15)
Процедуры в VBA
Пример объявления процедуры в VBA:
Public Sub aProcedure(ByVal intA As Integer, ByRef lngSqr As Long) lngSqr = intA * intAEnd Sub
В этом примере объявлена процедура, видимая из всех модулей, на это указывает слово Public, принимающая два параметра: intA по значению, на это указывает ключевое слово ByVal, и параметр lngSqr по ссылке, на это указывает ключевое слово ByRef. Ключевое слово Sub говорит, что объявлена процедура.
По умолчанию аргументы передаются в процедуры по ссылке.
Функции в VBA
Функции отличаются от процедур тем, что возвращают значение. Пример функции в VBA:
Public Function lngFunc(ByVal intA As Integer) As Long lngFunc = intA * intAEnd Sub
Для задания функции используем ключевое слово Function, после списка аргументов указываем тип возвращаемого значения. Строка
lngFunc = intA * intA
возвращает значение из данной функции, слева – имя функции, в данном случае оно играет роль return.
Первая программа на VBA
Откройте Excel, в строке меню окна Excel выберете Сервис - > Макрос - > Редактор Visual Basic. Откроется окно редактора, оно называется Microsoft Visual Basic. В окне Project – VBA Project кликаем дважды по Лист1. Вводим код:
Public Sub aMessage() MsgBox ("It is my first VBA program.")End Sub
Далее Debug - > Compile VBA Project. Если нет ошибок, то запускаем нашу программу: Run - > Run Sub/UserForm.
Видим такую картину:
Если у вас так получилось, то это значит, что самое трудное позади и очень скоро вы освоите VBA окончательно.
Использование функций в VBA
Сделаем программу с использованием функций. Напомню, что функция – это процедура, которая возвращает значение. Пусть наша программа возводит целое число в квадрат. Код на VBA:
Public Function lngSqr(ByVal intVal As Integer) As Long lngSqr = intVal * intVal End SubPublic Sub calculation() lngSqr = intVal * intVal Dim intVar As Integer Dim lngResult As Long intVar = 5 lngResult = lngSqr(intVar) MsgBox ("The result is " & lngResult)End Sub
Получаем:
Это результат работы.
www.sbp-program.ru
Заполнение динамических многомерных массивов массивов массивов Excel VBA
Я пытаюсь использовать excel 2010 VBA для заполнения массива, содержащего три массива. Первый - это массив строковых типов, а два других - массивы целочисленного типа. Соответствующая часть макроса приведена ниже.
продолжает давать мне "Run Time Ошибка 9 Подстрочный из диапазона" ошибка. Я пробовал все, что мог, чтобы преодолеть это, включая использование «N» вместо индексов «2», добавление и удаление круглых скобок и т. Д.
Что вызывает ошибку времени выполнения?
stackoverrun.com
Решение: Динамический массив для хранения данных в переменной пользовательского типа
С пользовательским типом вродь разобралась, а вот с динамическим массивом не получается. В справках есть и описание, и создание таких массивов( Dim Array() as …ReDim Array(5)…или ReDim Preserve Array(Ubound(Array)+2)) , но у меня применить его на деле не получается. Помогите,плиzzz, разобраться:‘Описываем пользовательский тип: Type Gragdanin Name As String * 30 DatRog As Date DopInf As String * 25 End Type ‘Описываем свойства и методы переменной пользовательского типа Public Sub Gen_Zap(Zapis As Gragdanin, Имя As String, ByVal Д_Рож As Date, Прим As String) Zapis.Name = Имя ‘"Петров Иван Денисович" Zapis.DatRog = Д_Рож ‘#10/11/1992#, Zapis.DopInf = Прим ‘"Внук" End Sub Public Sub Print_Zap(Zapis As Gragdanin) Debug.Print "Имя:"; Zapis.Name, "Дата рождения:"; Zapis.DatRog, "Примечания:"; Zapis.DopInf End Sub ‘Сама процедура, кот создает файл произвольного доступа, работает с переменными пользовательского типа , записывает данные в этот файл Sub Sozd_WR_File_7() Dim i As Integer Dim Zap_Gr As Gragdanin Dim PahtFile As String Dim b_int As Integer, b_int_1 As Integer PahtFile = "D:excelОфисное программирование 2" Open PahtFile & "File_BD_1.dat" For Random As #1 Len = Len(Zap_Gr) Call Gen_Zap(Zap_Gr, "Петров Иван Денисович", #10/11/1992#, "Внук") Put #1, 1, Zap_Gr Call Print_Zap(Zap_Gr) Call Gen_Zap(Zap_Gr, "Виктория Олеговна", #2/18/1973#, "Бухгалтер") Put #1, 2, Zap_Gr Call Print_Zap(Zap_Gr) Call Gen_Zap(Zap_Gr, "Мороховец Катя", #6/11/1992#, "Внук") Put #1, 3, Zap_Gr Call Print_Zap(Zap_Gr) Call Gen_Zap(Zap_Gr, "Денис Вадимыч", #2/1/1973#, "Автомобилист") Put #1, 4, Zap_Gr Call Print_Zap(Zap_Gr) b_int = LOF(1) Debug.Print "Длина файла="; b_int Close #1 End SubНужно создать программу, выполняющую, те же действия, что и в этом коде, но использующую динамический массив для хранения данных в переменной пользовательского типа.Заполнение динамических массивов VBA [arrays]
в вашем цикле for используйте Redim для массива, как здесь:
For i = 0 to 3 ReDim Preserve test(i) test(i) = 3 + i Next iВы также можете использовать пользовательский Type и Sub для этого. Рассмотрим мой код ниже:
Public Type dsIntArrayType eElems() As Integer eSize As Integer End Type Public Sub PushBackIntArray( _ ByRef dsIntArray As dsIntArrayType, _ ByVal intValue As Integer) With dsIntArray If UBound(.eElems) < (.eSize + 1) Then ReDim Preserve .eElems(.eSize * 2 + 1) End If .eSize = .eSize + 1 .eElems(.eSize) = intValue End With End SubЭто вызывает ReDim Preserve только тогда, когда размер удваивается. Переменная eSize отслеживает фактический размер данных eElems . Такой подход помог мне повысить производительность, когда конечная длина массива неизвестна до времени выполнения.
Надеюсь, это тоже поможет другим.
Я вижу много (все) сообщений выше, полагаясь на LBound / UBound на потенциально неинициализированный динамический массив VBA, что вызывает неизбежную смерть приложения ...
Ошибочный код:
Dim x As Long Dim arr1() As SomeType ... x = UBound(arr1) 'crashes
Правильный код:
Dim x As Long Dim arr1() As SomeType ... ReDim Preserve arr1(0 To 0) ... x = UBound(arr1)
... т.е. любой код, в котором Dim arr1() следует немедленно с помощью LBound(arr1) / UBound(arr1) вызывает без ReDim arr1(...) между ними, сбой. Err.Number развязку состоит в том, чтобы использовать следующее сообщение об On Error Resume Next при Err.Number и проверить номер Err.Number сразу после LBound(arr1) / UBound(arr1) - он должен быть 0, если массив инициализирован, иначе UBound(arr1) нуля. Поскольку существует некоторая некорректная ошибка VBA, необходима дальнейшая проверка пределов массива. Подробное объяснение может быть прочитано на веб-сайте Чипа Пирсона (который следует отмечать как сокровище человечества мудрости VBA ...)
Хех, это мой первый пост, верьте, что это разборчиво.
code-examples.net
Всего понемногу - Visual Basic - Разное
Массивы
Для хранения величин кроме простых переменных можно использовать массивы. Массив представляет собой набор переменных с одним именем и разными индексами. Каждая такая переменная называется элементом массива. Количество хранящихся в массиве элементов называется размером массива. Размер массива ограничен объемом оперативной памяти и типом данных элементов массива.
Все элементы массива имеют одинаковый тип. Однако если массив имеет тип variant, то отдельные элементы могут содержать данные разных типов. Например, одни элементы могут быть числами, другие — строками или объектами.
Индекс элемента указывается в круглых скобках после имени массива. Например, strNames(l), strNames(2), strNames(lO) ЯВЛЯЮТСЯ элементами массива с именем strNames. Вы можете использовать каждый из элементов массива точно так же, как и простую переменную.
Объявление массива
В Visual Basic существуют массивы фиксированного размера и динамические массивы. Массив фиксированного размера имеет неизменный размер, заданный при его объявлении. Динамические массивы могут изменять размер в процессе выполнения.
Объявление массива фиксированного размера
Объявление массива фиксированного размера зависит от области его видимости и осуществляется следующим образом:
- глобальный массив объявляется с помощью оператора public в секции Declaration модуля:
- массив уровня модуля — с помощью оператора private в секции Declaration модуля;
- локальный массив — с помощью оператора private процедуры.
При объявлении массива после его имени в круглых скобках указывается верхняя граница массива. По умолчанию нижней границей массива является 0. Например, в приведенном ниже коде, который вводится в секцию Declaration модуля, задается массив из 21 элемента. Индекс элементов массива изменяется от 0 до 20:
Dim intCountPar (20) As Integer
Для создания глобального массива такого же размера необходимо использовать следующий код:
Public intCountPar (20) As Integer Можно явно задать нижнюю границу массива, используя ключевое слово то:
Dim intCountPar (1 To 20) As Integer
В этом случае задается массив из 20 элементов. Индекс элементов массива изменяется от 1 до 20.
Visual Basic позволяет использовать многомерные массивы. Например, в следующем коде объявляется двумерный массив размерностью 21х21:
Dim intCountPar (20, 20) As Integer
При использовании многомерных массивов, как и в случае одномерных, можно явно задавать нижнюю границу:
Dim intCountPar (1 To 20, 1 То 20) As Integer Dim intCountPar (20, 1 То 20) As Integer
В верхней строке кода явно заданы верхняя и нижняя граница обеих размерностей. В нижней строке задана верхняя и нижняя граница только для второй размерности.
Объявление динамического массива
В случае, когда размер массива заранее неизвестен. Visual Basic позволяет использовать динамические массивы, размеры которых можно изменять во время выполнения. Применение динамических массивов позволяет эффективно управлять памятью, выделяя память под большой массив лишь на то время, когда этот массив используется, а затем освобождая ее.
Создание динамического массива осуществляется следующим образом:
1. Объявляется массив с помощью ключевых слов, используемых при создании массива фиксированного размера. Список размерностей массива остается пустым. При объявлении глобального массива необходимо выбрать ключевое слово Public, при объявлении массива на уровне модуля — Dim, при объявлении массива в процедуре — Dim или static. Например,
Dim intCountPar О As Integer
2. С помощью выполняемого оператора ReDim указывается размерность массива в виде числа или выражения. Синтаксис оператора ReDim аналогичен синтаксису оператора объявления массива фиксированного размера. Например, размерность массива может быть задана любым из следующих способов:
ReDim intCountPar (х)
ReDim intCountPar (20)
ReDim intCountPar (1 То 20)
При выполнении оператора ReDim данные, размещенные в массиве ранее, теряются. Это удобно в том случае, если данные вам больше не нужны и вы хотите переопределить размерность массива и подготовить его для размещения новых данных. Если вы хотите изменить размер массива, не потеряв при этом данных, то необходимо воспользоваться оператором ReDim с ключевым словом Preserve. Например, приведенный ниже программный код увеличивает размер массива на единицу без потери хранящихся в массиве данных:
ReDim Preserve intCountPar (X + 1)
ЗамечаниеИспользование оператора ReDim с ключевым словом Presterve позволяет изменять только верхнюю границу последней размерности многомерных размеров.
figaro.clan.su