Приятель попросил поставить Матлаб для курсовой по вейвлетам. Решил попутно посмотреть как вызывать из 1С.
Как всегда в таких ситуациях начал искать COM-интерфейс.
Получилось вот что.
Текст общего модуля matlab:
&AtServer
Function CreateMatlabInstance() Export
Try
matlabInstance = New ComObject("Matlab.Application");
matlabInstance.MinimizeCommandWindow();
Return New Structure("Answer,Result","Success",matlabInstance);
Except
Return New Structure("Answer,Result","Error",ErrorDescription());
Endtry
EndFunction
Procedure DestroyMatlabInstance(MatlabInstance) Export
MatlabInstance.Quit();
EndProcedure
Показать
И текст модуля формы
&AtClient
Procedure OnOpen(Cancel)
EndProcedure
&AtServer
Function CallMatlabAtServer()
RealArray = New Array(4);
ImageArray = New Array(4);
CreateMatlabResult = matlab.CreateMatlabInstance();
Result = "";
If CreateMatlabResult.Answer = "Success" Then
matlabinstance = CreateMatlabResult.Result;
Result = Result + CHARS.CR + matlabinstance.Execute("HelloString = ""Hello world from Matlab""");
Result = Result + CHARS.CR + matlabinstance.Execute("a = [1 2 3 4; 5 6 7 8]");
Result = Result + CHARS.CR + matlabinstance.Execute("b = a + a ");
//matlabinstance.GetFullMatrix("b", "base", RealArray, ImageArray);
matlab.DestroyMatlabInstance(matlabinstance);
Return Result;
Else
Return CreateMatlabResult.Result;
EndIF
EndFunction
&AtClient
Procedure CallMatlab(Command)
HelloText = CallMatlabAtServer(); // multiline text control
EndProcedure
Показать
Пока получилось применить четыре интерфейсных метода объекта:
Quit - Terminate MATLAB Automation server
Execute - Execute MATLAB command in Automation server
MinimizeCommandWindow - Minimize size of Automation server window - не работает. рабочее окно так и остается открытым вне 1с
MaximizeCommandWindow - Open Automation server window - соответственно тоже. но ошибок не вываливает.
Не работает GetFullMatrix. Может не правильно задал параметры.... (см комменты)
GetFullMatrix - Matrix from Automation server workspace
Но то что есть в принципе для исследования достаточно.
Может кто юзал матлаб в 1С как com-объект? На инфостарте нашел только одну тему, ито там чел заморочился DLL оберткой на Си...
Посмотрите книжку, раздел 10 посвящен COM (прикрепил)
The MATLAB ProgIDs are
• Matlab.Application — Starts a command window Automation server
with the version of MATLAB that was most recently used as an Automation
server (might not be the latest installed version of MATLAB).
• Matlab.Autoserver — Starts a command window Automation server using
the most recent version of MATLAB.
• Matlab.Desktop.Application — Starts the full desktop MATLAB as an
Automation server using the most recent version of MATLAB.
Matlab = CreateObject("matlab.application")
Matlab.MinimizeCommandWindow
'Now return the server window to its former state on
'the desktop and make it the currently active window.
Matlab.MaximizeCommandWindow
(2) Спасибо. Почитать. Интересно можно ли создать типизированные массивы в 1с. Которые в VB объявляются as double например... может можно просто создать массив и заполнить его 0.00
попытался типизировать массив... не получилось. то есть этот метод в 1с не рабочий. а жаль. думал Массив в 1С идентичен массиву в VB... ан нет... но в принципе мне этот метод особо и не нужен.
&AtServer
Function ArrayAs(Strings,Columns,TypeZero) Export
Result = new Array(Strings,Columns);
For i = 1 to Strings Do
For j = 1 to Columns Do
Result[i-1][j-1] = TypeZero;
EndDo;
EndDo;
Return Result;
EndFunction
..............
..............
RealArray = matlab.ArrayAs(2,4,0.0);
ImageArray = matlab.ArrayAs(2,4,0.0);
Try
matlabinstance.GetFullMatrix("b", "base", RealArray, ImageArray);
Except
err = ErrorDescription();
EndTry;
(8) вообще тут серверные вызовы не к месту имхо. все должно делаться &AtClient :) А если половина методов матлаба не будет работать то серверной частью тут будет рабочая область матлаба. сейчас еще копаьт в сторону VBScript с HTML5 и Веб-сервисы и SOAP
Тоже не помогло. все таки тут 1снега недостаточно. нужно быть низкоуровневым программистом, чтобы правильно настроить матла как аутомейшн сервер... Пока же придется вернуться в сам матлаб )
&AtClient
Procedure OnOpen(Cancel)
matlabHTML =
"<HT ML>
|<HEAD>
|<TITLE>Example of calling MATLAB from VBScript</TITLE>
|</HEAD>
|<BODY>
|
|Example of calling MATLAB from VBScript
|
|
|<!-- %%%%%%%%%%%%%%%%%%%% BEGIN SCRIPT %%%%%%%%%%%%%%%%%%%% -->
|<SC RIPT LANGUAGE=""VBScript"">
|<!-- Invoke MATLAB as a COM Automation server upon loading page
|' Initialize global variables
|Dim MatLab 'COM Automation server variable
|Dim MLcmd 'string to send to MATLAB for execution
|' Invoke COM Automation server
|Set MatLab = CreateObject(""Matlab.Application"")
|' End initialization script -->
|</SC RIPT>
|<!-- %%%%%%%%%%%%%%%%%%%% END SCRIPT %%%%%%%%%%%%%%%%%%%% -->
|<!-- Create form to contain controls -->
|<FO RM NAME=""Form"">
|<!-- Create pulldown menu to sel ect which plot to view -->
|<P>Select type of plot:
|<SELECT NAME=plot_choice>
|<OPTION SELECTED VALUE=first>Line</OPTION>
|<OPTION VALUE=second>Peaks</OPTION>
|<OPTION VALUE=third>Logo</OPTION>
|</SELECT>
|<!-- Create button to create plot and fill text area -->
|<P>Create figure:
|<INPUT TYPE=""button"" NAME=""plot_but"" VALUE=""Plot"">
|<!-- %%%%%%%%%%%%%%%%%%%% BEGIN SCRIPT %%%%%%%%%%%%%%%%%%%% -->
|<SC RIPT FOR=""plot_but"" EVENT=""onClick"" LANGUAGE=""VBScript"">
|<!-- Start script
|Dim plot_choice
|Dim text_str 'string to display in text area
|Dim form_var 'form object variable
|Set form_var = Document.Form
|plot_choice = form_var.plot_choice.value
|' Condition MATLAB command to execute based on plot choice
|If plot_choice = ""first"" Then
|MLcmd = ""figure; plot(1:10);""
|text_str = ""Simple line plot of 1 to 10""
|Call MatLab.PutCharArray(""text"",""base"",text_str)
|Elseif plot_choice = ""second"" Then
|MLcmd = ""figure; mesh(peaks);""
|text_str = ""Mesh plot of peaks""
|Call MatLab.PutCharArray(""text"",""base"",text_str)
|Elseif plot_choice = ""third"" Then
|MLcmd = ""figure; logo;""
|text_str = ""MATLAB logo""
|Call MatLab.PutCharArray(""text"",""base"",text_str)
|End If
|' Execute command in MATLAB
|MatLab.execute(MLcmd)
|' Get variable fr om MATLAB into VBScript
|Call MatLab.GetWorkspaceData(""text"",""base"",""text_str"")
|' Update text area
|form_var.plottext.value = text_str
|' End script -->
|</SC RIPT>
|<!-- %%%%%%%%%%%%%%%%%%%% END SCRIPT %%%%%%%%%%%%%%%%%%%% -->
|<!-- Create text area to show text -->
|<P><TEXTAREA NAME=""plottext"" ROWS=""1"" COLS=""50""
|CONTENTEDITABLE=""false""></TEXTAREA>
|
|</FORM>
|</BODY>
|</HTML>";
EndProcedure
По массиву попробуйте
Массив = Новый COMSafeArray("VT_R8", 4);
Массив.SetValue(0, 23,0);
Массив.SetValue(1, 13.5);
COMОбъект = Новый COMObject("ExampleCOMObject.ECOMClass");
COMОбъект.ProcessSafeArray(Массив);
Новый COMSafeArray(<ТипЭлемента>, <<разм0>,...,<размN-1>>)
Параметры:
<ТипЭлемента> (обязательный)
Тип: Строка.
Определяет тип элемента COMSafeArray.
Тип элемента задается строкой и может принимать одно из следующих значений:
VT_I1 - знаковое целое 1 байт;
VT_I2 - знаковое целое 2 байта;
VT_I4 - знаковое целое 4 байта;
VT_I8 - знаковое целое 8 байт;
VT_INT - знаковое целое;
VT_UI1 - беззнаковое целое 1 байт;
VT_UI2 - беззнаковое целое 2 байта;
VT_UI4 - беззнаковое целое 4 байта;
VT_UI8 - беззнаковое целое 8 байт;
VT_UINT - беззнаковое целое;
VT_R4 - действительное число 4 байта;
VT_R8 - действительное число 8 байт;
VT_DECIMAL - десятичное число с фиксированной точкой 12 байт;
VT_CY - значение денежного типа;
VT_DATE - значение типа дата;
VT_BSTR - значение типа строка;
VT_DISPATCH - указатель на интерфейс IDispatch;
VT_ERROR - код ошибки;
VT_BOOL - значение логического типа;
VT_UNKNOWN - указатель на интерфейс IUnknown;
VT_VARIANT - вариантный тип.
(11) О. спасибо. попробую. Ато я уже думал сделать аналоги функций которые разбирают текстовый результат, там в принципе можно матрицу выбрать через разделители строк.
Я думаю что 1С общается с com-объектами только через тип VT_VARIANT
(12)
Передача объектов 1С:Предприятия через COM
Раздел содержит описание некоторых особенностей передачи данных 1С:Предприятия через механизм COM/Automation.
ссылка