Заполнение динамических многомерных массивов массивов массивов 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 Sub

Public 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 для заполнения массива, содержащего три массива. Первый - это массив строковых типов, а два других - массивы целочисленного типа. Соответствующая часть макроса приведена ниже.

Option Explicit Option Base 1 Private Type T_small myStr() As String y() As Integer z() As Integer End Type Sub ColorByPoint() On Error GoTo ErrHandler Dim I As Integer, SCCount As Integer, PCCount As Integer, CLCount As Integer Dim N As Integer, M As Integer, K As Integer, P As Integer Dim x() As String, y() As Integer, z() As Integer Dim pvtItM As Variant Dim xName As String, str As String Dim xlRowField As Range Dim PC As ChartObjects Dim WS As Sheet3 Dim SC As SeriesCollection Dim MyObj As Object Dim PvTbl As Object Dim CelVal As Integer Dim rng As Variant, lbl As Variant, vlu As Variant Dim ItemField1 As PivotItem, ItemField2 As PivotItem Dim ValueField As PivotField Dim dField As PivotCell Dim oPi As PivotItem Dim acolRng As Range Dim arowRng As Range Dim myStr() As String Dim iData() As T_small Dim xSSN() As String Set WS = Application.ActiveWorkbook.ActiveSheet Set MyObj = Worksheets("Pivot1").ChartObjects("MyChart").Chart Set PvTbl = Worksheets("Pivot1").PivotTables("PivotTable1") Set rng = PvTbl.PivotFields("SSN").PivotItems Set lbl = PvTbl.DataFields M = 1 SCCount = MyObj.SeriesCollection.Count 'Series count PCCount = PvTbl.TableRange1.Rows.Count 'Rows Count CLCount = PvTbl.TableRange1.Columns.Count 'Columns Count Set acolRng = PvTbl.ColumnRange Set arowRng = PvTbl.RowRange Worksheets("Pivot1").Activate P = PCCount ReDim Preserve myStr(P) ReDim Preserve y(P) ReDim Preserve z(P) ReDim Preserve iData(P) For N = 2 To PCCount ReDim Preserve iData((iData(2).myStr(2)), (iData(N).y(N)),(iData(N).z(N))) Next N For I = 2 To PvTbl.TableRange1.Rows.Count Step 1 For K = 2 To PvTbl.TableRange1.Columns.Count Step 1 M = K N = K iData(I).myStr(I) = PvTbl.Cells("myStr" & I, "K").Value iData(I).y(I) = PvTbl.Cells("I", "M").Value iData(I).z(I) = PvTbl.Cells("I", "N").Value Next K Next I

Проблема заключается в том, что линия

ReDim Preserve iData((iData(2).myStr(2)), (iData(N).y(N)), (iData(N).z(N)))

продолжает давать мне "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Нужно создать программу, выполняющую, те же действия, что и в этом коде, но использующую динамический массив для хранения данных в переменной пользовательского типа.

studassistent.ru

Заполнение динамических массивов VBA [arrays]

в вашем цикле for используйте Redim для массива, как здесь:

For i = 0 to 3 ReDim Preserve test(i) test(i) = 3 + i Next i

Первый плакат, долгое время читатель. Как упомянуто Коди и Бреттом, вы можете уменьшить замедление VBA с разумным использованием Redim Preserve . Брет предложил Mod сделать это.

Вы также можете использовать пользовательский 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