При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда логика, заложенная в модуль объекта внешней обработки, должна быть выполнена строго на стороне клиента. Типичный пример — использование COM-соединений, драйверов торгового оборудования или специфических библиотек (DLL), которые зарегистрированы только на локальной рабочей станции пользователя и отсутствуют на сервере. В управляемом приложении стандартный механизм РеквизитФормыВЗначение работает только на сервере, что создает тупиковую ситуацию: нам нужен объект для вызова его методов, но на сервере он бесполезен из-за отсутствия окружения, а на клиенте (в тонком клиенте) получить полноценный «объект» из данных формы невозможно.
Однако, если мы используем Толстый клиент (управляемое приложение), перед нами открываются дополнительные возможности. Разберем подробно, как инициализировать объект внешней обработки в клиентском контексте и синхронизировать его с текущими данными формы.
Проанализируем техническую разницу. В тонком клиенте менеджеры ВнешниеОбработки или Справочники недоступны — любой вызов требует перехода на сервер. В толстом клиенте, даже если используются управляемые формы, менеджеры объектов доступны в контексте &НаКлиенте. Это позволяет нам программно создать экземпляр обработки прямо в памяти клиентского приложения.
Рассмотрим основной способ, который позволяет обойти серверный вызов. Если нам нужно выполнить код из модуля объекта, который обращается к COM-объекту на клиенте, мы можем заново создать этот объект на клиенте, используя путь к текущему файлу обработки.
Для этого нам понадобится путь к файлу .epf. В управляемой форме внешней обработки его можно получить через свойство ЭтаФорма.ИспользуемоеИмяФайла. Рассмотрим пример реализации процедуры:
&НаКлиенте
Процедура ВыполнитьЛогикуНаКлиенте()
// 1. Подготавливаем описание защиты, чтобы избежать лишних вопросов системы
Защита = Новый ОписаниеЗащитыОтОпасныхДействий;
Защита.ПредупреждатьОбОпасныхДействиях = Ложь;
// 2. Создаем объект обработки на клиенте
// Используем путь к текущему файлу обработки
ПутьКФайлу = ЭтаФорма.ИспользуемоеИмяФайла;
ОбъектНаКлиенте = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь, Защита);
// 3. Синхронизируем данные из формы в созданный объект
// Это важно, если в модуле объекта используются реквизиты обработки
ЗаполнитьЗначенияСвойств(ОбъектНаКлиенте, Объект);
// 4. Вызываем экспортный метод модуля объекта
// Теперь этот метод выполнится на клиенте и сможет создать COM-объект
ОбъектНаКлиенте.ВыполнитьДействиеС_COM();
// 5. Если метод изменил данные объекта, возвращаем их в форму
ЗаполнитьЗначенияСвойств(Объект, ОбъектНаКлиенте);
КонецПроцедуры
Разберем, что происходит в этом коде. Мы используем метод ВнешниеОбработки.Создать, который в толстом клиенте возвращает тип ВнешняяОбработкаОбъект. Параметр Ложь во втором аргументе отключает безопасный режим, что критически важно для создания COMОбъект. Метод ЗаполнитьЗначенияСвойств позволяет быстро перенести состояние реквизитов из экранной формы (переменная Объект) в наш новый программный экземпляр.
В некоторых случаях, если обработка уже была подключена или загружена в сеанс определенным образом, можно попытаться использовать упрощенный синтаксис создания объекта. Посмотрим на этот вариант:
&НаКлиенте
Процедура ВариантЧерезНовый()
Попытка
// Пытаемся создать объект по имени типа
ИмяТипа = "ВнешняяОбработкаОбъект." + Объект.Метаданные().Имя;
Об = Новый(ИмяТипа);
ЗаполнитьЗначенияСвойств(Об, Объект);
Об.ВашаЭкспортнаяПроцедура();
Исключение
Сообщить("Метод создания через 'Новый' не сработал: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Стоит отметить, что данный способ менее надежен для внешних обработок, так как тип ВнешняяОбработкаОбъект.Имя может быть не зарегистрирован в глобальном контексте клиента до момента явного подключения файла. Первый способ через ВнешниеОбработки.Создать является более стабильным.
ActiveX или библиотеки Excel). Толстый клиент, запущенный как 32-битное приложение, успешно решит эту проблему.ЗаполнитьЗначенияСвойств корректно переносит только простые типы (числа, строки, даты) и ссылки. Если у вас в обработке есть табличные части, их придется копировать вручную через ОбъектНаКлиенте.ТабличнаяЧасть.Загрузить(Объект.ТабличнаяЧасть.Выгрузить()).ОписаниеЗащитыОтОпасныхДействий с установкой свойства ПредупреждатьОбОпасныхДействиях = Ложь позволяет сделать процесс бесшовным для пользователя.Проанализировав ситуацию, мы видим, что использование толстого клиента в связке с управляемыми формами — это мощный инструмент для решения специфических интеграционных задач. Несмотря на общую рекомендацию переносить логику на сервер, «клиентский» модуль объекта остается незаменимым при работе с локальным окружением пользователя.