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

В статье рассмотрены принципы работы технологии 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. Если у пользователя это право стоит, то под ним можно будет выполнять запуск. В противном случае внешний запуск, используя данную технологию, будет невозможен. 

 

9 Comments

  1. kraynev-navi

    Не хватает примеров туда-оттуда. Скажем, как найти в той базе контрагента из нашей базы и обратно. Ссылки-то разные.

    Неплохо бы рассказать как искать там и тут значения перечислений.

    Reply
  2. ya.Avoronov

    (1) kraynev-navi,

    Контрагента можно искать запросом по ключевым полям;

    Перечисление видимо вот так:

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

    Reply
  3. nixel

    К сожалению, большая часть статьи описывает способности, присущие и COM-соединению и Automation-серверу и о том, как же работает COM.

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

    В любом случае, спасибо за статью!

    Reply
  4. jaroslav.h

    Очень понравилось изложенное, не работал с данными объектами еще поэтому как новичку очень интересно и главное очень доходчиво описано, спасибо!

    Прошу еще добвить пару статтей о разных использований данных объектов + эти всякие «Внешний соединение» + Ком, буду очень благодарен.

    Reply
  5. Yashazz

    Очень хочется влепить минус.

    Сведения, давно не новые, откровенно передранные из общедоступных источников, и претендующие на «статью». Помесь баяна с плагиатом, за который незнающие новички накидали плюсов.

    Если кому нужно, поиск в руки — относительно недавно была действительно шикарная статья по COM-взаимодействию, всем советую.

    Reply
  6. Yashazz

    (1) kraynev-navi, элементарно. По их именам и функциям работы с предопределёнными значениями. В синтакс-помощнике всё есть)

    Reply
  7. niko11s

    (5) Yashazz, Ссылку на источник, откуда был «плагиат» скинь плиз, может и дальше оттуда буду брать)

    Reply
  8. kraynev-navi

    (6) Yashazz, в СП есть много. Вероятно 99% от всего того, что написано на инфостарте. А статьи все появляются и появляются. Видимо, люди хотят помогать друг другу не изобретать велосипеды и экономить время.

    Касательно задачи, которую решал я, где заранее было неизвестно какое из перечислений будет передано в другую базу ваш вариант с явным указанием имен не проходит. Для написания одной строчки кода, пришлось полопатить интернет.

     Ставка = ВнешняяБаза.XMLЗначение(ВнешняяБаза.ИзXMLТипа(ВнешняяБаза.XMLТипЗнч(ВнешняяБаза.Перечисления.СтавкиНДС.ПустаяСсылка())),
    XMLСтрокаНаСервере(ПараметрыПисьма.СтавкаНДС));
    Reply
  9. Yashazz

    (7) еле нашёл сейчас даже эту публикацию, чтобы вам ответить. Поищите статью Tormozit’а, вроде его работа была. Ну и основная часть передрана с ИТС и жёлтых книжек, тут ссылки, думаю, сами найдёте.

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

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *