При интеграции 1С с внешними системами часто возникает задача передать данные непосредственно в открытое окно пользователя (например, заполнить реквизиты открытого документа или активировать форму при звонке из софтфона/сканировании). В среде Windows для многих офисных программ применяется COM-автоматизация через вызов GetObject(,"Application"), однако с 1С данный подход не работает. Выясним причину такого поведения платформы и разберем проверенные способы решения этой задачи.
Проанализируем технические ограничения COM-технологии платформы 1С. При создании объекта через CreateObject("V83.Application") операционная система всегда запускает новый фоновый сеанс 1С со своим контекстом.
Интерактивные клиенты платформы (1cv8.exe или 1cv8c.exe) по умолчанию не регистрируют себя в таблице активных объектов Windows (Running Object Table — ROT). По этой причине подключиться к уже работающему интерфейсному процессу через стандартные системные механизмы OLE/COM невозможно. Кроме того, серверный контекст 1С не имеет прямого доступа к открытым формам конкретного пользователя на клиенте. Передать данные в форму можно только в рамках клиентского сеанса этого пользователя.
Классический и наиболее надежный путь для организации локального взаимодействия (по аналогии со сканерами штрихкодов и торговым оборудованием) — подключение внешней компоненты. Сторонняя программа связывается с компонентой (например, через локальный сокет или именованный пайп), а компонента генерирует внешнее событие в платформе 1С через интерфейс IExternalEvent.
Разберем по шагам процесс загрузки и подключения Native-компоненты из макета конфигурации:
Посмотрим на пример кода на встроенном языке 1С:
&НаКлиенте
Процедура ПодключитьКомпонентуНаКлиенте()
МакетВК = ПолучитьМакетНаСервере("МакетКомпоненты");
АдресВК = ПоместитьВоВременноеХранилище(МакетВК, Новый УникальныйИдентификатор);
// Устанавливаем и подключаем компоненту
Если УстановитьВнешнююКомпоненту(АдресВК) Тогда
ИмяПодключения = "MyNetDriver";
Если ПодключитьВнешнююКомпоненту(АдресВК, ИмяПодключения, ТипВнешнейКомпоненты.Native) Тогда
// Инициализация объекта: AddIn.[ИмяПодключения].[ИмяКлассаИзКомпоненты]
Попытка
ПодключаемыйМодуль = Новый("AddIn." + ИмяПодключения + ".WebExtEvent");
Сообщить("Компонента успешно подключена!");
Исключение
ВызватьИсключение "Ошибка создания объекта: " + ОписаниеОшибки();
КонецПопытки;
Иначе
Сообщить("Не удалось подключить внешнюю компоненту.");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьМакетНаСервере(ИмяМакета)
Возврат Обработки.ИнтеграцияВнешнихСобытий.ПолучитьМакет(ИмяМакета);
КонецФункции
Разбор частой ошибки: «Тип не определен (AddIn.Имя.Класс)»
При вызове конструктора Новый("AddIn...") крайне важно соблюдать строгое соответствие наименований. Шаблон вызова выглядит следующим образом: AddIn.[ИмяПодключения].[ИмяКласса]. Здесь ИмяПодключения — строка, переданная вторым параметром в метод ПодключитьВнешнююКомпоненту, а ИмяКласса — внутреннее имя класса, возвращаемое самой компонентой в методе GetClassNames(). Несовпадение регистра или имен приводит к ошибке неопределенного типа.
Перехват полученных данных в управляемом приложении выполняется через предопределенную процедуру ОбработкаВнешнегоСобытия в модуле управляемого приложения или в модуле открытой формы:
&НаКлиенте
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
// Проверяем источник события от нашей компоненты
Если Источник = "MyNetDriver" Тогда
// Обрабатываем входящие данные (например, распарсиваем JSON/текст и заполняем форму)
ЗаполнитьРеквизитыФормыПоДанным(Данные);
КонецЕсли;
КонецПроцедуры
В современных конфигурациях 1С можно отказаться от разработки и поддержки низкоуровневых внешних компонент на клиентах, используя штатные механизмы платформы. Рассмотрим архитектуру такого решения:
СистемаВзаимодействия.ОтправитьСообщение конкретному пользователю.Данный способ исключает открытие локальных сетевых портов на рабочих станциях пользователей и работает стабильно даже через веб-клиент.
Платформа 1С регистрирует в операционной системе схему URL-протоколов e1c:// и e1cib://. Если стороннему приложению требуется открыть конкретный объект или выполнить команду в уже запущенном сеансе, достаточно выполнить системный вызов операционной системы с навигационной ссылкой.
При передаче навигационной ссылки Windows автоматически активирует окно существующего запущенного сеанса 1С и открывает запрашиваемый элемент метаданных с переданными параметрами без необходимости писать собственный транспорт данных.
Если нет возможности использовать внешние компоненты или публиковать HTTP-сервисы, рассмотрим простой вариант с буферизацией данных:
ПодключитьОбработчикОжидания("ПроверитьВходящиеДанные", 2).Важно: Данный вариант создает дополнительную нагрузку на базу данных частыми запросами, поэтому его рекомендуется применять только при невозможности реализации решений на базе внешних событий или Системы взаимодействия.