VBA обеспечивает два основных типа процедуры: функции и стандартные подпрограммы.
Вы получаете доступ к функции VBA непосредственно от ячейки в рабочем листе как функция формул. Используйте функциональные процедуры, когда исходная функция MATLAB® возьмет одни или несколько входных параметров и возвратит нулевые выходные параметры.
Вы получаете доступ к стандартной подпрограмме как к общему макросу. Используйте процедуру стандартной подпрограммы, когда исходная функция MATLAB возвращает массив значений или нескольких выходных параметров, потому что необходимо сопоставить эти выходные параметры в несколько ячеек/областей значений в рабочем листе.
Когда вы создаете компонент, MATLAB Compiler™ производит модуль VBA (.bas
файл). Этот файл содержит простые обертки вызова, каждый реализованный как функциональная процедура для каждого метода класса.
Прежде чем вы будете использовать любой компонент MATLAB Compiler, будете инициализировать библиотеки поддержки текущим экземпляром Microsoft® Excel®. Сделайте это однажды для сеанса Excel, который использует компоненты MATLAB Compiler.
Чтобы сделать эту инициализацию, вызовите служебную библиотечную функцию MWInitApplication
, который является членом MWUtil
класс. Этот класс является частью MWComUtil
библиотека. Смотрите Класс MWUtil.
Один способ добавить этот код инициализации в модуль VBA состоит в том, чтобы обеспечить стандартную подпрограмму, которая делает инициализацию однажды, и просто выходит для всех последующих вызовов. Следующий пример кода Microsoft Visual Basic® инициализирует библиотеки текущим экземпляром Excel. Глобальная переменная типа Object
названный MCLUtil
содержит экземпляр MWUtil
класс и другая глобальная переменная типа Boolean
названный bModuleInitialized
хранит состояние процесса инициализации. Частная стандартная подпрограмма InitModule()
создает экземпляр MWComUtil
класс и вызовы MWInitApplication
метод с аргументом Application
. Если эта функция успешно выполняется, весь последующий выход вызовов без переинициализации.
Dim MCLUtil As Object Dim bModuleInitialized As Boolean Private Sub InitModule() If Not bModuleInitialized Then On Error GoTo Handle_Error If MCLUtil Is Nothing Then Set MCLUtil = CreateObject("MWComUtil.MWUtil") End If Call MCLUtil.MWInitApplication(Application) bModuleInitialized = True Exit Sub Handle_Error: bModuleInitialized = False End If End Sub
Этот код похож на код инициализации по умолчанию, сгенерированный в модуле VBA, созданном, когда компонент создается. Каждая функция, которая использует компоненты MATLAB Compiler, может включать вызов InitModule
вначале, чтобы гарантировать, что инициализация всегда выполняется по мере необходимости.
Прежде, чем вызвать метод класса (скомпилированная функция MATLAB), необходимо создать экземпляр класса, который содержит метод. VBA обеспечивает два метода для того, чтобы сделать это:
CreateObject
функция
New
оператор
Этот метод использует прикладной программный интерфейс (API) Microsoft Visual Basic CreateObject
функция, чтобы создать экземпляр класса. Microsoft называет вызов CreateObject late binding и использованием new
как early binding.
Чтобы использовать этот метод, объявите переменную типа Object
использование Dim
содержать ссылку на экземпляр класса и вызывать CreateObject
использование программного идентификатора класса (ProgID
) в качестве аргумента, как показано в следующем примере:
Function foo(x1 As Variant, x2 As Variant) As Variant Dim aClass As Object On Error Goto Handle_Error Set aClass = CreateObject("mycomponent.myclass.1_0") ' (call some methods on aClass) Exit Function Handle_Error: foo = Err.Description End Function
Этот метод использует Visual Basic New
оператор на переменной, явным образом определенной размеры как класс, который будет создан. Перед использованием этого метода необходимо сослаться на библиотеку типов, содержащую класс в текущем проекте VBA. Сделайте это путем выбора меню Tools из Visual Basic Editor, и затем выбора References, чтобы отобразить Доступный список Ссылок. Из этого списка выберите необходимую библиотеку типов.
Следующий пример иллюстрирует использование New
оператор, чтобы создать экземпляр класса. Это принимает, что вы выбрали библиотеку типов mycomponent 1.0 из Доступного списка Ссылок прежде, чем вызвать эту функцию.
Function foo(x1 As Variant, x2 As Variant) As Variant Dim aClass As mycomponent.myclass On Error Goto Handle_Error Set aClass = New mycomponent.myclass ' (call some methods on aClass) Exit Function Handle_Error: foo = Err.Description End Function
В этом примере экземпляр класса может быть определен размеры как просто myclass
. Полное объявление в форме <component-name>.<class-name>
принимает меры против столкновений имени, которые могут произойти, если другие библиотеки в текущем проекте содержат типы под названием myclass
.
Используя оба CreateObject
и New
произведите определенный размеры экземпляр класса. Первый метод не требует ссылки на библиотеку типов в проекте VBA; вторые результаты в более быстром выполнении кода. Второй метод имеет добавленное преимущество включения "Автоматических членов Списка" и возможностей "Автоматическая Быстрая Информация" редактора Microsoft Visual Basic, чтобы работать с вашими классами. Функциональные обертки по умолчанию создали с каждым созданным компонентом все использование первый метод для создания объекта.
В предыдущих двух примерах экземпляр класса, используемый, чтобы сделать вызов метода, был локальной переменной процедуры. Это создает и уничтожает новый экземпляр класса для каждого вызова. Альтернативный подход должен объявить один один ограниченный по объему модулем экземпляр класса, который снова используется всеми вызовами функции, как в коде инициализации предыдущего примера.
Следующий пример иллюстрирует этот метод со вторым методом:
Dim aClass As mycomponent.myclass Function foo(x1 As Variant, x2 As Variant) As Variant On Error Goto Handle_Error If aClass Is Nothing Then Set aClass = New mycomponent.myclass End If ' (call some methods on aClass) Exit Function Handle_Error: foo = Err.Description End Function
MATLAB Compiler создает один MATLAB Runtime, когда первая Microsoft COM class инстанцируют в приложении. Этот MATLAB Runtime снова используется и общий для все последующие экземпляры класса в компоненте, приводящем к более эффективному использованию памяти и устраняющем стоимость запуска MATLAB Runtime в каждом последующем инстанцировании класса.
Все экземпляры класса совместно используют одно рабочее пространство MATLAB и совместно используют глобальные переменные в файлах MATLAB, используемых, чтобы создать компонент. Это заставляет свойства COM-класса вести себя как статические свойства вместо мудрых экземпляром свойств.
После того, как вы создали экземпляр класса, можно вызвать методы класса получить доступ к скомпилированным функциям MATLAB. MATLAB Compiler применяет стандартное отображение от исходного синтаксиса функции MATLAB до списка аргументов метода. Смотрите Ссылочные Служебные Классы для подробного описания отображения от функций MATLAB до вызовов метода COM-класса.
Когда метод имеет выходные аргументы, первым аргументом всегда является nargout
, который имеет тип Long
. Этот входной параметр передает нормальный MATLAB nargout
параметр к скомпилированной функции и задает, сколько требуют выходные параметры. Методы, которые не имеют выходных аргументов, не передают nargout
аргумент. Следующий nargout
выходные параметры, перечисленные в том же порядке, как они появляются на левой стороне исходной функции MATLAB. Затем существуйте входные параметры, перечисленные того же порядка, как они появляются на правой стороне исходной функции MATLAB. Все аргументы ввода и вывода вводятся как Variant
, тип данных Visual Basic по умолчанию.
Variant
тип может содержать любой из основных типов VBA, массивы любого типа и ссылки на объект. См. Правила Преобразования Данных для подробного описания того, как преобразовать Variant
типы любого основного типа к и от типов данных MATLAB. В общем случае можно предоставить любой тип Visual Basic в качестве аргумента к методу класса, за исключением Visual Basic UDT
s. Можно также передать Microsoft Excel Range
объекты непосредственно в качестве аргументов ввода и вывода.
Когда вы передаете простой Variant
введите как выходной параметр, вызываемый метод выделяет полученные данные и освобождает исходное содержимое Variant
. В этом случае достаточно определить размеры каждого выходного аргумента как одного Variant
. Когда тип объекта (как Excel Range
) передается как выходной параметр, ссылка на объект передается в обоих направлениях и Value
объекта свойство получает данные.
Следующие примеры иллюстрируют процесс передачи параметров ввода и вывода от VBA до методов класса компонента MATLAB Compiler.
Первым примером является функция формул, которая берет два входных параметров и возвращает один выходной параметр. Эта функция диспетчеризирует вызов метода класса, который соответствует функции MATLAB формы function y = foo(x1,x2)
.
Function foo(x1 As Variant, x2 As Variant) As Variant Dim aClass As Object Dim y As Variant On Error Goto Handle_Error Set aClass = New mycomponent.myclass aClass = CreateObject("mycomponent.myclass.1_0") Call aClass.foo(1,y,x1,x2) foo = y Exit Function Handle_Error: foo = Err.Description End Function
Второй пример переписывает ту же функцию как стандартная подпрограмма и использует области значений Excel во вводе и выводе.
Sub foo(Rout As Range, Rin1 As Range, Rin2 As Range) Dim aClass As Object On Error Goto Handle_Error aClass = CreateObject("mycomponent.myclass.1_0") Call aClass.foo(1,Rout,Rin1,Rin2) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
Когда varargin
и/или varargout
присутствуют в функции MATLAB, которую вы используете в компоненте Excel, эти параметры добавляются к списку аргументов метода класса как последние параметры ввода/вывода в списке. Можно передать несколько аргументов как varargin
массив путем создания Variant
массив, присваивая каждый элемент массива к соответствующему входному параметру.
Следующий пример создает varargin
массив, чтобы вызвать метод, следующий из функции MATLAB формы y = foo(varargin)
:
Function foo(x1 As Variant, x2 As Variant, x3 As Variant, _ x4 As Variant, x5 As Variant) As Variant Dim aClass As Object Dim v As Variant Dim y As Variant Dim MCLUtil As Object On Error GoTo Handle_Error set aClass = CreateObject("mycomponent.myclass.1_0") Set MCLUtil = CreateObject("MWComUtil.MWUtil") Call MCLUtil.MWPack(v, x1, x2, x3, x4, x5) Call aClass.foo(1, y, v) foo = y Exit Function Handle_Error: foo = Err.Description End Function
MWUtil
класс включен в MWComUtil
служебная библиотека обеспечивает MWPack
функция помощника, чтобы создать varargin
параметры. Смотрите Класс MWUtil для получения дополнительной информации.
Следующий пример обрабатывает varargout
параметр в три отдельных Excel Range
s. Эта функция использует MWUnpack
функция в служебной библиотеке. Используемой функцией MATLAB является varargout = foo(x1,x2)
.
Sub foo(Rout1 As Range, Rout2 As Range, Rout3 As Range, _ Rin1 As Range, Rin2 As Range) Dim aClass As Object Dim aUtil As Object Dim v As Variant On Error Goto Handle_Error aUtil = CreateObject("MWComUtil.MWUtil") aClass = CreateObject("mycomponent.myclass.1_0") Call aClass.foo(3,v,Rin1,Rin2) Call aUtil.MWUnpack(v,0,True,Rout1,Rout2,Rout3) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
В MATLAB, varargin
входные параметры функций являются дополнительными, и могут присутствовать или не использованы от вызова функции. Однако от Microsoft Visual Basic, функциональные подписи более строги — если varargin
присутствует среди входных параметров функции MATLAB, вызов VBA должен включать varargin
, даже если вы хотите, чтобы он был пуст. Передать в пустом varargin
, передайте Null
вариант, который преобразован в пустой массив ячеек MATLAB, когда передано.
Передайте Пустой varargin из Кода VBA. Следующий пример иллюстрирует, как передать пустой вариант для того, чтобы передать пустой varargin
:
Function foo(x1 As Variant, x2 As Variant, x3 As Variant, _ x4 As Variant, x5 As Variant) As Variant Dim aClass As Object Dim v(1 To 5) As Variant Dim y As Variant On Error Goto Handle_Error v(1) = x1 v(2) = x2 v(3) = x3 v(4) = x4 v(5) = x5 aClass = CreateObject("mycomponent.myclass.1_0") 'Call aClass.foo(1,y,v) Call aClass.foo(1,y,Null) foo = y Exit Function Handle_Error: foo = Err.Description End Function
Для получения дополнительной информации о работе с аргументами переменной длины, смотрите работу с Вводами и выводами Переменной длины.
Каждый компонент MATLAB Compiler отсоединяет одно свойство чтения/записи под названием MWFlags
из типа MWFlags
. MWFlags
свойство состоит из двух наборов констант: флаги форматирования массивов и флаги преобразования данных. Array formatting flags влияет на преобразование массивов, тогда как соглашение data conversion flags с преобразованиями типов отдельных элементов массива.
Преобразование данных отмечает изменение выбранные поведения процесса преобразования данных от Variant
s к типам MATLAB и наоборот. По умолчанию компоненты MATLAB Compiler позволяют устанавливать флаги преобразования данных на уровне класса через MWFlags
свойство класса. Это сохраняется для всех типов Visual Basic, за исключением MATLAB Compiler MWStruct
, MWField
, MWComplex
, MWSparse
, и MWArg
типы. Каждый из этих типов отсоединяет свой собственный MWFlags
свойство и игнорирует свойства класса, метод которого называется. MWArg
класс предоставляется специально для случая, когда конкретному аргументу нужны различные настройки из свойств класса по умолчанию.
Этот раздел обеспечивает общее обсуждение того, как установить эти флаги и что они делают. Смотрите Класс MWFlags (MATLAB Compiler SDK) для детального обсуждения MWFlags
введите, а также выборки дополнительного кода.
Флаги форматирования массивов ведут преобразование данных, чтобы произвести или массив ячеек MATLAB или матрицу от общего Variant
данные по входу или произвести массив Variant
s или один Variant
содержа массив основного типа на выходе.
Следующие примеры принимают, что вы сослались на MWComUtil
библиотека в текущем проекте путем выбора Tools> References и выбора библиотеки типов MWComUtil 7.5 из списка:
Sub foo( ) Dim aClass As mycomponent.myclass Dim var1(1 To 2, 1 To 2), var2 As Variant Dim x(1 To 2, 1 To 2) As Double Dim y1,y2 As Variant On Error Goto Handle_Error var1(1,1) = 11# var1(1,2) = 12# var1(2,1) = 21# var1(2,2) = 22# x(1,1) = 11 x(1,2) = 12 x(2,1) = 21 x(2,2) = 22 var2 = x Set aClass = New mycomponent.myclass Call aClass.foo(1,y1,var1) Call aClass.foo(1,y2,var2) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
Кроме того, эти примеры принимают, что вы сослались на COM-объект, созданный с MATLAB Compiler (mycomponent
) как упомянуто в Новом Операторе.
Здесь, два Variant
переменные, var1
и var2
создаются с теми же числовыми данными, но внутренне они структурированы по-другому: var1
массив 2 на 2 Variant
s с каждым элементом, содержащим Double
1 на 1, в то время как
var2
Variant
1 на 1 содержа массив 2 на 2
Double
s.
В MATLAB Compiler, при использовании настроек по умолчанию, оба из этих массивов будут преобразованы в массивы 2 на 2 double
s. Это не следует общему соглашению, перечисленному в ВАРИАНТЕ COM к Правилам Преобразования MATLAB. Согласно этим правилам, var1
преобразует в массив ячеек 2 на 2 с каждой ячейкой, занятой двойным 1 на 1, и var2
преобразует непосредственно в двойную матрицу 2 на 2.
Эти два массива оба преобразуют, чтобы удвоить матрицы потому что значение по умолчанию для InputArrayFormat
флагом является mwArrayFormatMatrix
. InputArrayFormat
отметьте средства управления, как обработаны массивы этих двух типов. Это значение по умолчанию используется, потому что данные массива, происходящие из областей значений Excel, всегда в форме массива Variant
s (как var1
из предыдущего примера), и функции MATLAB чаще всего имеют дело с матричными аргументами.
Но что, если вы хотите массив ячеек? В этом случае вы устанавливаете InputArrayFormat
отметьте к mwArrayFormatCell
. Сделайте это путем добавления следующей линии после создания класса и перед вызовом метода:
aClass.MWFlags.ArrayFormatFlags.InputArrayFormat = mwArrayFormatCell
Установка этого флага представляет весь вход массивов скомпилированной функции MATLAB как массивы ячеек.
Точно так же можно управлять форматом выходных аргументов с помощью OutputArrayFormat
флаг. Можно также изменить массив выход с AutoResizeOutput
и TransposeOutput
флаги.
AutoResizeOutput
используется в Excel Range
объекты передали непосредственно как выходные параметры. Когда этот флаг установлен, целевой диапазон автоматически изменяет размер, чтобы соответствовать полученному массиву. Если этот флаг не установлен, целевой диапазон должен быть, по крайней мере, столь же большим как выходной массив, или данные являются усеченными.
TransposeOutput
флаг транспонирует весь массив выход. Этот флаг полезен при контакте с функциями MATLAB, которые выводят одномерные массивы. По умолчанию MATLAB осознает одномерные массивы как матрицы 1 на n (векторы-строки), которые становятся строками в рабочем листе Excel.
Если ваша функция MATLAB в частности возвращает вектор-строку, например, гарантируйте, что вы присваиваете подобный вектор-строку из ячеек в Excel.
Можно предпочесть столбцы рабочего листа от вектора-строки выход. Этот пример автоизменяет размер и транспонирует выходную область значений:
Sub foo(Rout As Range, Rin As Range ) Dim aClass As mycomponent.myclass On Error Goto Handle_Error Set aClass = New mycomponent.myclass aClass.MWFlags.ArrayFormatFlags.AutoResizeOutput = True aClass.MWFlags.ArrayFormatFlags.TransposeOutput = True Call aClass.foo(1,Rout,Rin) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
Преобразование данных отмечает соглашение с преобразованиями типов отдельных элементов массива. Два флага преобразования данных, CoerceNumericToType
и InputDateFormat
, управляйте, как числовой и типы даты преобразованы от VBA до MATLAB. Рассмотрите пример:
Sub foo( ) Dim aClass As mycomponent.myclass Dim var1, var2 As Variant Dim y As Variant On Error Goto Handle_Error var1 = 1 var2 = 2# Set aClass = New mycomponent.myclass Call aClass.foo(1,y,var1,var2) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
Этот пример преобразует var1
из типа Variant/Integer
к int16
и var2
из типа Variant/Double
к double
.
Если исходная функция MATLAB ожидает double
s для обоих аргументов, этот код может вызвать ошибку. Одно решение состоит в том, чтобы присвоить double
к var1
, но это не может быть возможно или желательно. В таком случае устанавливает CoerceNumericToType
отметьте к mwTypeDouble
, то, чтобы заставлять преобразователь данных преобразовать весь числовой вход в double
. В предыдущем примере поместите следующую линию после создания класса и прежде, чем вызвать методы:
aClass.MWFlags.DataConversionFlags.CoerceNumericToType = mwTypeDouble
InputDateFormat
отметьте средства управления как Date
VBA тип преобразован. Этот пример отправляет текущую дату и время как входной параметр и преобразует его в строку:
Sub foo( ) Dim aClass As mycomponent.myclass Dim today As Date Dim y As Variant On Error Goto Handle_Error today = Now Set aClass = New mycomponent.myclass aClass. MWFlags.DataConversionFlags.InputDateFormat = mwDateFormatString Call aClass.foo(1,y,today) Exit Sub Handle_Error: MsgBox(Err.Description) End Sub
Ошибки, которые происходят при создании экземпляра класса или во время метода класса, создают исключение в текущей процедуре. Microsoft Visual Basic предусматривает возможность обработки исключений через On Error Goto <label>
оператор, в котором выполнение программы переходит к <label>
когда ошибка происходит. (<label>
должен быть расположен в той же процедуре как On Error Goto
оператор). Все ошибки обрабатываются этот путь, включая ошибки в оригинальном коде MATLAB. Исключение создает Visual Basic ErrObject
объект в текущем контексте в переменной под названием Err
. (См. документацию Visual Basic for Applications для детального обсуждения обработки ошибок VBA.) Все примеры в этом разделе иллюстрируют типичную логику обнаружения ошибок, используемую в обертках вызова функции в компонентах MATLAB Compiler.