Интегрируйте компоненты Используя приложение 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 UDTs. Можно также передать 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 Ranges. Эта функция использует 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 с Несколькими Аргументами.

Измените флаги

Каждый компонент MATLAB Compiler отсоединяет одно свойство чтения/записи под названием MWFlags из типа MWFlags. MWFlags свойство состоит из двух наборов констант:   флаги форматирования массивов и   флаги преобразования данных. Array formatting flags влияет на преобразование массивов, тогда как соглашение data conversion flags с преобразованиями типов отдельных элементов массива.

Преобразование данных отмечает изменение выбранные поведения процесса преобразования данных от Variants к типам MATLAB и наоборот. По умолчанию компоненты MATLAB Compiler позволяют устанавливать флаги преобразования данных на уровне класса через MWFlags свойство класса. Это сохраняется для всех типов Visual Basic, за исключением MATLAB Compiler MWStruct, MWField, MWComplex, MWSparse, и MWArg типы. Каждый из этих типов отсоединяет свой собственный MWFlags свойство и игнорирует свойства класса, метод которого называется. MWArg класс предоставляется специально для случая, когда конкретному аргументу нужны различные настройки из свойств класса по умолчанию.

Этот раздел обеспечивает общее обсуждение того, как установить эти флаги и что они делают. Для детального обсуждения MWFlags введите, а также выборки дополнительного кода, смотрите Класс MWFlags (MATLAB Compiler SDK).

Флаги форматирования массивов

Флаги форматирования массивов ведут преобразование данных, чтобы произвести или массив ячеек MATLAB или матрицу от общего Variant данные по входу или произвести массив Variants или один 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-объект (файл DLL) созданный с MATLAB Compiler (mycomponent) как упомянуто в Новом Операторе.

Здесь, два Variant переменные, var1 и var2 создаются с теми же числовыми данными, но внутренне они структурированы по-другому: var1 массив 2 на 2 Variants с каждым элементом, содержащим Double 1 на 1, в то время как var2 Variant 1 на 1 содержа массив 2 на 2 Doubles.

В MATLAB Compiler, при использовании настроек по умолчанию, оба из этих массивов будут преобразованы в массивы 2 на 2 doubles. Это не следует общему соглашению, перечисленному в ВАРИАНТЕ COM к Правилам Преобразования MATLAB. Согласно этим правилам, var1 преобразует в массив ячеек 2 на 2 с каждой ячейкой, занятой двойным 1 на 1, и var2 преобразует непосредственно в двойную матрицу 2 на 2.

Эти два массива оба преобразуют, чтобы удвоить матрицы потому что значение по умолчанию для InputArrayFormat флагом является mwArrayFormatMatrix. InputArrayFormat отметьте средства управления, как обработаны массивы этих двух типов. Это значение по умолчанию используется, потому что данные массива, происходящие из областей значений Excel, всегда в форме массива Variants (как 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 ожидает doubles для обоих аргументов, этот код может вызвать ошибку. Одно решение состоит в том, чтобы присвоить 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.