gifts2017

Знакомство с технологией Automation-сервер на примерах

Опубликовал Николай С (niko11s) в раздел Программирование - Теория программирования

В статье рассмотрены принципы работы технологии Automation-сервер на конкретных примерах.

     Система 1С:Предприятие может использоваться внешними приложениями в качестве Automation-сервера. При работе в качестве Automation-сервера 1С:Предприятие предоставляет доступ ко всем свойствам и методам своего глобального контекста, а также включение и выключение пользовательского интерфейса (главного окна 1С:Предприятия 8). Кроме того, Automation-сервер 1С:Предприятия имеет дополнительные свойства и методы для выполнения действий, специфичных для работы в режиме Automation.
     Основное назначение Automation-сервера 1С:Предприятие в управлении приложением 1С:Предприятия 8 из других приложений и выполнение действий аналогичных интерактивным действиям, например, построение отчетов.
Для запуска системы 1С:Предприятие в качестве Automation-сервера из внешнего приложения, выполняется следующая последовательность действий:

     создается COMОбъект с идентификатором V83.Application (для тонкого клиента V83C.Application);

     выполняется инициализация системы 1С:Предприятие методом Connect (для тонкого клиента существует возможность передать в строке соединения дополнительные параметры прокси сервера);

     вызываются свойства и методы системы 1С:Предприятие как Automation-сервера.

     Многие современные программные продукты (MS Office, MS FoxPro и т.п.) могут выступать в роли клиентов Automation, что позволяет обмениваться данными между этими продуктами и системой 1С:Предприятие.

Замечание 1: Поскольку система 1С:Предприятие может создавать и использовать Automation-серверы, предоставляемые внешними приложениями (т.е. является Automation-клиентом), то имеется возможность из 1С:Предприятия обращаться к другой копии 1С:Предприятия (например, к другой конфигурации) для обмена данными.

Замечание 2: Нелокализованные версии внешних программ, обращающихся к программе 1С:Предприятие посредством Automation, могут неправильно интерпретировать русские идентификаторы объектов, например, реквизитов справочников. Данное замечание не относится к продуктам MS Office и к программам, использующим в качестве языка обращения к COM-объектам Microsoft Visual Basic. Рекомендуется использовать локализованные версии программных продуктов, либо в конфигурации использовать идентификаторы без символов кириллицы. Для обращения к свойствам и методам объектов системы 1С:Предприятие из внешних приложений рекомендуется использовать их англоязычные синонимы.

Замечание 3: Все созданные объекты Automation существуют до тех пор, пока существует переменная, которая содержит значение данного объекта. Следовательно, сама программа 1С:Предприятие, выступающая в качестве объекта Automation в другой программе, будет находиться в памяти компьютера до удаления или изменения значения переменной, содержащей ее в качестве объекта.
     

Система 1С:Предприятие в качестве Automation-сервера предоставляет полный доступ к своему глобальному контексту. Поэтому объект Automation-сервер 1С:Предприятие в качестве своих свойств может иметь: системные константы, значения заданных в Конфигураторе объектов, доступ к которым осуществляется с помощью менеджеров (например, константы, перечисления, справочники, документы, журналы документов, отчеты, обработки, планы видов характеристик, планы счетов, планы видов расчета, регистры), а также переменные, объявленные в модуле приложения (управляемого / обычного) с ключевым словом Экспорт.
     Automation-сервер 1С:Предприятие в качестве своих методов может иметь: системные процедуры и функции, а также процедуры и функции модуля приложения и общих модулей, объявленные с ключевым словом Экспорт.

     Итак, рассмотрим данную технологию на примерах. Для начала решим простую задачу. Мы подключимся из нашей информационной базы к другой информационной базе и обратимся к некоторым свойствам и методам глобального контекста. Для этого мы создадим внешнюю обработку - "РаботаСДругойБазой". Создадим команду, перетащим её на форму. При нажатии на эту кнопку наша обработка будет выполнять определенные действия. Создаем обработчик действия.

     В обработчике действия мы создаем новый СОМ - объект. Далее используем метод "Connect(<СтрокаСоединения>) " . В строке соединения данного метода мы укажем путь к нашей информационной базе и имя пользователя, под которым мы будем в неё заходить.

     В случае, если подключение выполнить не удалось, мы сообщим об этом пользователю, а если все прошло удачно, то мы обратимся к методу глобального контекста "ИмяПользователя()" для того, чтобы сообщить, под каким пользователем мы заходим в базу. Данная функция доступна в режиме "Внешнее соединение":

&НаКлиенте
Процедура Запуск(Команда)
	ДругаяБаза = Новый COMObject("V83.Application");
	Подключение = ДругаяБаза.Connect("File=C:\ДругаяБаза;Usr=Администратор;");
	Если НЕ Подключение Тогда
		Сообщить("Подключение не удалось");
		Возврат;
	КонецЕсли;
	
	Сообщить(ДругаяБаза.ИмяПользователя());

КонецПроцедуры

     Итак, сохраняем обработку и запускаем ее в пользовательском режиме. Нажимаем кнопку "Запуск" и спустя некоторое время система нам сообщает имя пользователя. При этом у нас открывается "ДругаяБаза" в пользовательском режиме. 

     Теперь немного усложним задачу. Допустим, нам нужно обратиться к справочнику в другой базе при помощи запроса. Если бы мы писали запрос в текущей базе, то мы бы объявили переменную класса "Запрос". Но сейчас мы будем выполнять запрос в рамках другой информационной базы. Для этого мы будем использовать метод NewObject(<Имя>). Далее мы пишем текст запроса. Мы можем напрямую обращаться к свойствам и методам данного запроса. Мы будем использовать методы "Выполнить()" и "Выбрать()". Казалось бы, на выходе у нас должна получиться "ВыборкаИзРезультатаЗапроса". Однако если мы поставим точку останова и посмотрим на выполнение нашего кода в отладчике, то мы увидим, что тип данных - это "CОМОбъект". Более того, все типы другой информационной базы у нас также будут CОМОбъектами.  Есть и еще одна странность, мы работаем на клиенте, но при этом выполняем запрос. Дело в том, что мы обращаемся к ДругойБазе, а там программный код исполняется в режиме внешнего соединения.

&НаКлиенте
Процедура Запуск(Команда)
	ДругаяБаза = Новый COMObject("V83.Application");
	Подключение = ДругаяБаза.Connect("File=C:\ДругаяБаза;Usr=Администратор;");
	Если НЕ Подключение Тогда
		Сообщить("Подключение не удалось");
		Возврат;
	КонецЕсли;
	
	Сообщить(ДругаяБаза.ИмяПользователя());

	Запрос = ДругаяБаза.NewObject("Запрос");
	Запрос.Текст =
	
	"ВЫБРАТЬ
	|	Номенклатура.Ссылка
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура";
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Сообщить(Выборка.Ссылка.НаименованиеПолное);
	КонецЦикла;	
КонецПроцедуры
 

     Отметим также, что если мы используем следующий код Сообщить(Выборка.Ссылка.НаименованиеПолное); сообщения мы получаем в той же базе, из которой мы запускаем нашу обработку. Если же нам нужно вывести сообщение в "ДругойБазе", то код должен быть следующий: ДругаяБаза.Сообщить(Выборка.Ссылка.НаименованиеПолное);

 

Отметим также тот факт, что несмотря на то, что "Выборка.Ссылка" у нас имеет тип "CОМОбъект" мы можем получить строковое представление этого значения. Для этого у нас есть метод "String(<Параметр>)". Т.е. вместо Выборка.Ссылка.НаименованиеПолное мы могли использовать ДругаяБаза.String(Выборка.Ссылка), чтобы получить наименование элемента справочника.

Решим еще одну задачу. Из текущей информационной базы нам нужно будет обратиться к "ДругойБазе" и создать элемент справочника "Контрагенты". Вначале код у нас будет похожий, нам прежде всего нужно будет выполнить подключение к информационной базе. Нам нужно будет обратиться к классу СправочникиМенеджер (CatalogsManager).

Код у нас будет аналогичный тому, как если бы мы создавали элемент справочника в нашей базе. Единственное, вначале мы должны указать "ДругаяБаза.":

&НаКлиенте
Процедура Запуск(Команда)
	ДругаяБаза = Новый COMObject("V83.Application");
	Подключение = ДругаяБаза.Connect("File=C:\ДругаяБаза;Usr=Администратор;");
	КонтрагентыОбъект = ДругаяБаза.Справочники.Контрагенты.СоздатьЭлемент();
	КонтрагентыОбъект.Наименование = "Контрагент из вызывающей базы";
	КонтрагентыОбъект.Записать();
КонецПроцедуры

 

     Следует отметить и одно неудобство при работе с "CОМОбъект" - это то, что у нас не работает контекстная подсказка.

     Итак, мы уже научились создавать новые элементы в другой информационной базе, а теперь попробуем открыть только что созданный элемент. Для того, чтобы открыть форму, нам будет необходимо обратиться к методу глобального контекста "ОткрытьФорму()". Отличие будет в том, что мы будем обращаться не напрямую, а используя наш "СОМОбъект" "ДругаяБаза". Мы указываем имя нашего открываемого объекта. Кроме того, нам нужно передать второй параметр, который у нас является структурой, которая будет включать в себя "Ключ" и "Значение", которое будет являться ссылкой на наш элемент справочника:

&НаКлиенте
Процедура Запуск(Команда)
	ДругаяБаза = Новый COMObject("V83.Application");
	Подключение = ДругаяБаза.Connect("File=C:\ДругаяБаза;Usr=Администратор;");
	КонтрагентыОбъект = ДругаяБаза.Справочники.Контрагенты.СоздатьЭлемент();
	КонтрагентыОбъект.Наименование = "Контрагент из вызывающей базы";
	КонтрагентыОбъект.Записать();
	ДругаяБаза.ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта", новый Структура("Ключ", КонтрагентыОбъект.Ссылка));
КонецПроцедуры

 

     Однако, если мы запустим нашу обработку с таким кодом система нам выдаст ошибку:

"Произошла исключительная ситуация (1C:Enterprise8.3.6.2237) несоответствие типов (параметр номер 2)". Подобные ошибки очень часто возникают при использовании технологии Automation. Дело в том, что мы создаем структуру в текущей базе, а её нужно создать в "ДругаяБаза". Правильный программный код будет следующий:

 

&НаКлиенте
Процедура Запуск(Команда)
	ДругаяБаза = Новый COMObject("V83.Application");
	Подключение = ДругаяБаза.Connect("File=C:\ДругаяБаза;Usr=Администратор;");
	КонтрагентыОбъект = ДругаяБаза.Справочники.Контрагенты.СоздатьЭлемент();
	КонтрагентыОбъект.Наименование = "Контрагент из вызывающей базы";
	КонтрагентыОбъект.Записать();
	Параметр = ДругаяБаза.NewObject("Структура");
	Параметр.Вставить("Ключ", КонтрагентыОбъект.Ссылка);
	ДругаяБаза.ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта", Параметр);
КонецПроцедуры  

 

     Когда мы подключаемся к "ДругойБазе", используя технологию OLE Automation у нас происходит обычный запуск приложения. Это означает, что когда мы обращаемся к базе, у нас будут работать обычные модули. Это модуль сеанса, модуль управляемого приложения со всеми событиями ПередНачаломРаботыСистемы(), ПередЗавершениемРаботыСистемы(). Но у нас еще есть модуль внешнего соединения, и в случае использования Automation он не вызывается. Он будет вызываться только когда мы будем подключаться через СОМ напрямую, используя "Менеджер COM-соединений", который обеспечивает возможность надежного и быстрое программного доступа к данным 1С:Предприятия 8 из внешних приложений через Внешнее соединение (External connection).

     В общем и целом работа с 1С:Предприятием 8 через внешнее соединение подобна работе с 1С:Предприятием в режиме Automation сервера. Основные отличия заключаются в следующем:

     В случае Automation сервера запускается полноценное приложение 1С:Предприятия 8, а в случае внешнего соединения запускается относительно небольшой внутрипроцессный COM-сервер.

     При работе через внешнее соединение не доступны функциональные возможности, так или иначе связанные с организацией пользовательского интерфейса 1С:Предприятия 8;

     При работе внешнего соединения не используется модуль управляемого приложения (модуль обычного приложения) конфигурации 1С:Предприятия 8. Его роль при работе с внешним соединением играет модуль внешнего соединения.

     При использовании внешнего соединения имеются следующие преимущества по сравнению с использованием Automation сервера:

     Более быстрая установка соединения, так как не требуется создания отдельного процесса операционной системы, а все действия производятся в рамках вызывающего процесса;

     Более быстрое обращение к свойствам и методам объектов 1C:Предприятия, так как для организации обращения не требуется организации межпроцессной коммуникации;

     Меньший расход ресурсов операционной системы.

     Для организации доступа к данным 1С:Предприятия 8 через внешнее соединение, выполняется следующая последовательность действий:

     создается менеджер COM-соединений, с помощью которого производится установка соединения;

     производится обращение к методу Connect менеджера COM-соединений. Метод Connect возвращает внешнее соединение с информационной базой 1С:Предприятия 8; 

     через внешнее соединение производится обращение к допустимым методам, свойствам и объектам информационной базы, с которой установлено соединение.

     Важно! В связи с отсутствием пользовательского интерфейса не все объекты, а также свойства и методы можно использовать во внешнем соединении.
     Внешнее соединение предоставляет полный доступ к своему глобальному контексту. Поэтому внешнее соединение в качестве своих методов может иметь: системные константы, значения заданных в Конфигураторе объектов, доступ к которым осуществляется с помощью менеджеров (например, константы, перечисления, справочники, документы, журналы документов, отчеты, обработки, планы видов характеристик, планы счетов, планы видов расчета, регистры), а также переменные, объявленные в модуле внешнего соединения с ключевым словом Экспорт.

 

Также важно помнить, что у нас на уровне роли есть такое право, как возможность подключения к базе, используя технологию  Automation. Если у пользователя это право стоит, то под ним можно будет выполнять запуск. В противном случае внешний запуск, используя данную технологию, будет невозможен. 

 

См. также

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

Комментарии

1. С К (kraynev-navi) 29.09.15 10:48
Не хватает примеров туда-оттуда. Скажем, как найти в той базе контрагента из нашей базы и обратно. Ссылки-то разные.
Неплохо бы рассказать как искать там и тут значения перечислений.
2. Александр Воронов (ya.Avoronov) 29.09.15 11:22
(1) kraynev-navi,
Контрагента можно искать запросом по ключевым полям;

Перечисление видимо вот так:
НужноеПеречисление = ДругаяБаза.Перечисления.ВидыОперацийППИсходящее.ОплатаПоставщику



3. Никита Грызлов (nixel) 30.09.15 11:37
К сожалению, большая часть статьи описывает способности, присущие и COM-соединению и Automation-серверу и о том, как же работает COM.
Понимаю, что про Automation рассказывать в принципе немного (создается отдельный процесс да есть работа с интерфейсом), но по заголовку статьи ожидал чего-то более специфичного.
В любом случае, спасибо за статью!
4. Ярослав Володимирович (myr4ik07) 30.09.15 11:49
Очень понравилось изложенное, не работал с данными объектами еще поэтому как новичку очень интересно и главное очень доходчиво описано, спасибо!
Прошу еще добвить пару статтей о разных использований данных объектов + эти всякие "Внешний соединение" + Ком, буду очень благодарен.
5. Яков Коган (Yashazz) 01.10.15 14:12
Очень хочется влепить минус.
Сведения, давно не новые, откровенно передранные из общедоступных источников, и претендующие на "статью". Помесь баяна с плагиатом, за который незнающие новички накидали плюсов.

Если кому нужно, поиск в руки - относительно недавно была действительно шикарная статья по COM-взаимодействию, всем советую.
6. Яков Коган (Yashazz) 01.10.15 14:14
(1) kraynev-navi, элементарно. По их именам и функциям работы с предопределёнными значениями. В синтакс-помощнике всё есть)
7. Николай С (niko11s) 01.10.15 15:05
(5) Yashazz, Ссылку на источник, откуда был "плагиат" скинь плиз, может и дальше оттуда буду брать)
8. С К (kraynev-navi) 01.10.15 15:46
(6) Yashazz, в СП есть много. Вероятно 99% от всего того, что написано на инфостарте. А статьи все появляются и появляются. Видимо, люди хотят помогать друг другу не изобретать велосипеды и экономить время.
Касательно задачи, которую решал я, где заранее было неизвестно какое из перечислений будет передано в другую базу ваш вариант с явным указанием имен не проходит. Для написания одной строчки кода, пришлось полопатить интернет.
	Ставка = ВнешняяБаза.XMLЗначение(ВнешняяБаза.ИзXMLТипа(ВнешняяБаза.XMLТипЗнч(ВнешняяБаза.Перечисления.СтавкиНДС.ПустаяСсылка())),
		XMLСтрокаНаСервере(ПараметрыПисьма.СтавкаНДС));
9. Яков Коган (Yashazz) 02.10.15 17:53
(7) niko11s, еле нашёл сейчас даже эту публикацию, чтобы вам ответить. Поищите статью Tormozit'а, вроде его работа была. Ну и основная часть передрана с ИТС и жёлтых книжек, тут ссылки, думаю, сами найдёте.

(8) kraynev-navi, а что мешало передавать имя всего перечисления и определять на месте, куда его девать? В упор не понимаю, зачем вы так усложняете. Мне при любых обменах (а их, поверьте, было много) хватало функций "ПолучитьПолноеИмяПредопределенногоЗначения" и "ПредопределенноеЗначение", ну и немножко работы с метаданными конкретных реквизитов, чтоб узнать имена их типов.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа