Интегрируйте Компоненты с помощью Приложения Visual Basic

Когда использовать функцию формул или стандартную подпрограмму

VBA обеспечивает два основных типа процедуры: функции и стандартные подпрограммы.

Вы получаете доступ к функции VBA непосредственно от ячейки в рабочем листе как функция формул. Используйте функциональные процедуры, когда исходная функция MATLAB® возьмет одни или несколько входных параметров и возвратит нулевые выходные параметры.

Вы получаете доступ к стандартной подпрограмме как к общему макросу. Используйте процедуру стандартной подпрограммы, когда исходная функция MATLAB возвращает массив значений или нескольких выходных параметров, потому что необходимо сопоставить эти выходные параметры в несколько ячеек/областей значений в рабочем листе.

Когда вы создаете компонент, MATLAB Compiler™ производит модуль VBA (файл .bas). Этот файл содержит простые обертки вызова, каждый реализованный как функциональная процедура для каждого метода класса.

Инициализируйте библиотеки MATLAB Compiler с Microsoft Excel

Прежде чем вы будете использовать любой компонент 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

Этот метод использует прикладной программный интерфейс (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 Runtime является общими для классами

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 Аргументы

Когда 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

Передайте Пустой varargin из Кода Microsoft Visual Basic

В 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 VARIANT к Правилам Преобразования 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. Можно также изменить массив вывод с флагами TransposeOutput и AutoResizeOutput.

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.