Как сделать матрицу в vba

Обновлено: 05.07.2024

Можно объявить массив для работы с набором значений одного типа данных. Массив представляет собой одиночную переменную с множеством ячеек для хранения значений, тогда как типовая переменная имеет только одну ячейку хранилища, в которой может храниться только одно значение. Следует обращаться к массиву как одному целому, когда необходимо сослаться на все значения, хранящиеся в нем, или можно обращаться к отдельным элементам.

Например, чтобы хранить ежедневные расходы по каждому дню года, можно объявить одну переменную массива с 365 элементами, а не объявлять 365 переменных. Каждый элемент массива содержит одно значение. В следующем заявлении объявляется переменная массива с 365 элементами. По умолчанию массив индексируется, начиная с нуля, так что верхняя граница массива равна 364, а не 365.

Чтобы установить значение отдельного элемента, указывается индекс этого элемента. В следующем примере каждому элементу массива присваивается начальное значение, равное 20.

Изменение нижней границы

Вы можете использовать заявление Option Base в верхней части модуля, чтобы изменить индекс по умолчанию первого элемента с 0 на 1. В следующем примере в заявлении Option Base изменяется индекс для первого элемента, а в заявлении Dim объявляется переменная массива с 365 элементами.

Можно также в явном виде установить нижнюю границу массива, используя выражение To, как показано в следующем примере.

Хранение значений Variant в массивах

Существует два способа создания массивов значений Variant. Один способ — объявление массива с типом данных Variant, как показано в следующем примере:

Другой способ — присвоение массива, возвращаемого функцией Array, переменной Variant, как показано в следующем примере.

Независимо от способа создания массива элементы в массиве значений Variant идентифицируют по индексу. Например, в любом из предыдущих примеров может быть добавлен следующий оператор.

Использование многомерных массивов

В Visual Basic допускается объявлять массивы с 60 размерностями, максимум. Например, следующий оператор объявляет 2-мерный массив 5 на 10.

Если рассматривать массив как матрицу, первый аргумент представляет строки, а второй аргумент представляет столбцы.

Использование вложенных для. Следующие утверждения для обработки многомерных массивов. Следующая процедура позволяет заполнить двумерный массив значениями Single.

См. также

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.

Задачи, перечисленные в заголовке, возникают достаточно часто в различных сферах деятельности, требующих применения математического аппарата. По этой причине в библиотеке Excel есть встроенные функции, позволяющие решить эти задачи. О встроенных функциях умножения матриц МУМНОЖ (MMULT) и транспонирования матриц МТРАНСП (MTRANSP) я уже упоминал, есть и функция для нахождения обратной матрицы - МОБРАТ (MINVERSE) . Зная обратную матрицу и умея умножать матрицы, найти решение системы уравнений не представляет труда. Но поскольку умение решать эти задачи входит в круг начального образования программиста, то я полагаю уместным рассмотреть создание собственных аналогов этих функций на VBA . Заодно это позволит рассмотреть некоторые важные моменты в создании пользовательских функций, вызываемых в формулах рабочего листа. Многое мы уже знаем. Знаем, как написать пользовательскую функцию, какие ограничения накладываются на ее параметры с тем, чтобы ее можно было вызывать из формул рабочего листа Excel , передавая ей в качестве фактических параметров массивы рабочего листа. Знаем, как анализировать тип переданных данных. Знаем, как такая функция может вернуть массив и изменить содержимое рабочего листа. В последующих примерах я еще раз коснусь всех этих вопросов, а, кроме того, появятся и другие вопросы, на которые стоит обратить внимание.

Задача 11 Произведение матриц

Постановка задачи: Найти произведение прямоугольных матриц A*B

Из того, что мы узнали ранее, следует, какой вид может иметь заголовок пользовательской функции, решающей эту задачу. Два входных параметра функции должны быть типа Variant . Этот же тип должен быть у возвращаемого функцией значения. Конечно, это не единственно возможное решение. Можно было бы иметь один входной параметр, используя спецификатор ParamArray . Такой способ был бы единственно возможным, если обобщить постановку и попытаться создать функцию, которая должна перемножать произвольное число матриц. Но при умножении двух матриц естественнее иметь и два соответствующих им параметра. Поэтому заголовок получился таким:

Я хочу показать Вам, как написать общую функцию, достаточно широкого назначения. Ее можно будет вызывать в формулах над массивами рабочего листа, передавая ей в качестве фактических параметров A и B массивы рабочего листа (объекты Range ). Но не только объекты Range , но и массивы констант будут допускаться в качестве одного или обоих аргументов. Результат работы функции будет записан в массив, выделенный в момент вызова формулы над массивами. Более того, я хочу, чтобы эту же функцию можно было вызывать в обычных функциях и процедурах VBA, передавая в момент вызова массивы VBA в качестве аргументов. Все это, естественно, утяжелит нашу функцию, но позволит мне обсудить отличия "обычных" и "пользовательских функций. С учетом этих замечаний наша функция выглядит так:

Как видите, функция MultMatr , успешно работающая в роли пользовательской функции, с тем же успехом может выполнять и роль обычной функции. Так что я выполнил поставленную задачу, создав "универсальную" функцию. Но, возможно, предпочтительнее в процедурах VBA работать с MultMatr1 , не прибегая к переменным типа Variant . Обратите внимание на небольшую тестовую функцию ResArray , которую я написал, чтобы в явной форме продемонстрировать способ возвращения массива в функциях VBA.

Матрица VBA - Создание и многое другое

Матрица - это прямоугольный массив чисел с одинаковым количеством строк и столбцов. Вы можете создать матрицу в VBA, заполнив переменные массива и используя циклы VBA.

Создание матрицы в VBA

123456789101112131415 Sub CreateSimpleMatrix ()Матрица Dim matrix () как целое числоDim x, i, j, k как целое число'повторно уменьшите размер массиваМатрица ReDim (от 1 до 3, от 1 до 3) как целое числох = 1Для i = от 1 до 3Для j = от 1 до 3матрица (i, j) = xх = (х + 1)Следующий jДалее я'вернуть результат на лист за один разДиапазон ("A1: C3") = матрицаКонец подписки


Преобразование однострочного вектора в матрицу

Рассмотрим столбец чисел ниже. На каком-то этапе вы можете захотеть преобразовать числовой столбец в матрицу.


Используя приведенную ниже функцию, мы можем создать матрицу из списка чисел.

123456789101112131415161718192021 Функция Create_Matrix (Vector_Range как диапазон, No_Of_Cols_in_output как целое число, No_of_Rows_in_output как целое число) как вариантReDim Temp_Array (1 в No_Of_Cols_in_output, 1 в No_Of_Rows_in_output)Dim No_Of_Elements_In_Vector как целое числоDim Col_Count как целое число, Row_Count как целоеNo_Of_Elements_In_Vector = Vector_Range.Rows.Count'Устранение условий NULLЕсли Vector_Range - ничто, выйти из функцииЕсли No_Of_Cols_in_output = 0, тогда выйти из функцииЕсли No_of_Rows_in_output = 0, тогда выйти из функцииЕсли No_Of_Elements_In_Vector = 0, тогда выйти из функцииДля Col_Count = 1 в No_Of_Cols_in_outputДля Row_Count = 1 до No_of_Rows_in_outputTemp_Array (Col_Count, Row_Count) = Vector_Range.Cells (((No_of_Rows_in_output) * (Col_Count - 1) + Row_Count), 1)Следующий Row_CountСледующий Col_CountCreate_Matrix = Temp_ArrayКонечная функция

Мы можем создать матрицу на нашем листе Excel, вызвав функцию выше.

123 Sub ConvertToMatrix ()Диапазон ("C1: H2") = Create_Matrix (Диапазон ("A1: A10"), 2, 6)Конец подписки


Преобразование матрицы в однорядный вектор

В качестве альтернативы вы можете преобразовать матрицу в одну строку. Рассмотрим матрицу ниже.


Используя приведенную ниже функцию, мы можем преобразовать это в одномерный массив.

12345678910111213141516171819202122 Функция Create_Vector (Matrix_Range как диапазон) как вариантDim No_of_Cols как целое число, No_Of_Rows как целое числоDim i как целое числоDim j как целое число'забираем строки и столбцы из матрицыNo_of_Cols = Matrix_Range.Columns.CountNo_Of_Rows = Matrix_Range.Rows.CountReDim Temp_Array (No_of_Cols * No_Of_Rows)'Устранение условий NULLЕсли Matrix_Range ничего не значит, выйти из функцииЕсли No_of_Cols = 0, тогда выйти из функцииЕсли No_Of_Rows = 0, тогда выйти из функции'цикл по массиву - первый элементДля j = 1 до No_Of_Rows'теперь перебираем второй элементДля i = 0 до No_of_Cols - 1'присвоить одномерному временному массивуTemp_Array ((i * No_Of_Rows) + j) = Matrix_Range.Cells (j, i + 1)Далее яСледующий jCreate_Vector = Temp_ArrayКонечная функция

Теперь мы можем вызвать эту функцию, используя процедуру, описанную ниже.

1234567891011 Sub GenerateVector ()Тусклый вектор () как вариантDim k как целое числоDim No_of_Elements'получить массивВектор = Create_Vector (Sheets ("Sheet1"). Range ("A1: D5"))'пройти через массив и заполнить листДля k = 0 в UBound (вектор) - 1Листы ("Лист1"). Диапазон ("G1"). Смещение (k, 0). Значение = Вектор (k + 1)Следующие kКонец подписки

Эта процедура вернет следующий результат.


Использование WorksheetFunction.MMULT для создания матричного массива

Рассмотрим следующую таблицу.


Мы можем использовать приведенную ниже процедуру для расчета суммы процентов для вышеприведенной сетки на основе процентной ставки и суммы, которую человек хочет занять.

123456789101112 Дополнительное использованиеMMULT ()Dim rngIntRate As RangeДиапазон значений Dim rngAmtLoan AsТусклый результат () как вариант'заполняем объекты нашего диапазонаУстановить rngIntRate = Range ("B4: B9")Установить rngAmtLoan = Range ("C3: H3")'используйте формулу MMULT для заполнения массива результатовРезультат = WorksheetFunction.MMult (rngIntRate, rngAmtLoan)'заполнить листДиапазон ("C4: H9") = РезультатКонец подписки


На листе выше вы заметите, что приведенная выше процедура заполняет ячейки значениями, а не формулами - см. C4 на приведенном выше рисунке - в нем указано значение 200, а не формула. С помощью Рабочий лист Метод всегда возвращает статическое значение на рабочий лист, а не формулу. Это означает, что в случае изменения процентной ставки или суммы кредита соответствующие значения в заполненной матрице НЕ БУДУ изменение.

Вместо использования Рабочий листFunction.MMULT, вы можете использовать VBA для применения функции MMULT к ячейке с помощью FormulaArray метод.

123 Sub InsertMMULT ()Диапазон ("C4: H9"). FormulaArray = "= MMULT (B4: B9, C3: H3)"Конец подписки

Обратите внимание, что теперь при заполнении электронной таблицы в ячейках используется формула.

Матрица А занимает ячейки Cells(1, 1) : Cells(n, m), матрица B ячейки Cells(1, m+2) : Cells(m, m+p+1).
То есть матрица А имеет n строк и m столбцов, а матрица В имеет m строк и p столбцов.
То, что кол-во столбцов матрицы А равно кол-ву строк матрицы В - обязательное условие для существования произведения этих матриц.
Матрица С будет иметь n строк и p столбцов и занимать ячейки Cells(1, m+p+3) : Cells(n, m+2p+2).

Sub MulMatrix
Dim A() As Integer, B() As Integer, C() As Integer
Dim m As Integer, n As Integer, p As Integer, i As Integer, j As Integer, k As Integer
n = InputBox ("Введите кол-во строк матрицы А")
m = InputBox ("Введите кол-во строк матрицы B, равное кол-ву столбцов матрицы А")
p = InputBox ("Введите кол-во столбцов матрицы B")
ReDim A(n, m), B(m, p), C(n, p)
For i = 1 To n
For k = 1 To p
C(i, k) = 0
For j = 1 To m
A(i, j) = Cells(i, j): B(j, k) = Cells(j, m+1+k)
C(i, k) = C(i, k) + A(i, j) * B(j, k)
Cells(i, m+p+2+k) = C(i, k)
Next j
Next k
Next i
End Sub
Кажется, ничего не напутал с номерами столбцов.

Читайте также: