При разработке внешних обработок в конфигурациях, работающих на платформе 1С:Предприятие 8 в режиме обычного приложения (как, например, типовая УПП), разработчики часто сталкиваются с жестким ограничением: директива препроцессора #Если Клиент Тогда всегда срабатывает, если код выполняется в контексте толстого клиента. В этой статье мы разберем, почему это происходит и как правильно проектировать логику заполнения документов, чтобы избежать нежелательных диалоговых окон.
Первое, что нам нужно уяснить: #Если Клиент Тогда — это не просто условие в коде, а директива препроцессора. Она не вычисляется в процессе выполнения кода (в байт-коде), а влияет на этап компиляции модуля.
Когда конфигурация 1С компилирует модуль, она анализирует эти директивы и «вырезает» из итогового байт-кода те части, которые не соответствуют текущему контексту запуска (клиент или сервер). Если вы запускаете внешнюю обработку в толстом клиенте, платформа считает, что она находится в «клиентском» контексте. Следовательно, блок кода, обернутый в эту директиву, будет включен в компиляцию и обязательно выполнится при вызове соответствующей процедуры.
Напрямую «отменить» действие этой директивы, находясь внутри блока кода, невозможно. Если логика типового документа жестко завязана на вызов #Если Клиент Тогда с выводом Предупреждение() или Вопрос(), вы не сможете просто игнорировать этот вызов из внешней обработки, работающей в обычном режиме.
Однако, мы можем изменить контекст выполнения. Рассмотрим основные способы, как это сделать:
Если вам необходимо выполнить заполнение объекта без участия интерфейса пользователя, самым надежным способом будет использование фонового задания. Даже если вы запускаете выполнение из толстого клиента, фоновое задание всегда работает на сервере.
Рассмотрим пример того, как это можно реализовать:
Процедура ЗаполнитьДокументНаСервере(СсылкаНаДокумент) Экспорт
// Здесь происходит обращение к методам заполнения
// Поскольку код выполняется в фоновом задании (на сервере),
// блоки #Если Клиент Тогда будут проигнорированы препроцессором.
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокументОбъект.Заполнить(ДанныеОснования);
ДокументОбъект.Записать();
КонецПроцедуры
// Вызов из внешней обработки:
ФоновыеЗадания.Выполнить("МойОбщийМодуль.ЗаполнитьДокументНаСервере", Параметры);
Часто возникает вопрос: «Подходят ли управляемые формы для внешних обработок в УПП?». Ответ — да, но с оговорками. В режиме толстого клиента управляемая форма будет функционировать, однако выполнение серверных вызовов будет происходить в том же контексте процесса толстого клиента.
Если вы все же хотите использовать управляемую форму, убедитесь, что вы правильно вызываете её открытие. В коде внешней обработки вы можете предусмотреть выбор формы:
Если ЭтоУправляемыйРежим() Тогда
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.УправляемаяФорма");
Иначе
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.ОбычнаяФорма");
КонецЕсли;
Если ваша задача — однократная, как в описанном случае, лучше всего воспользоваться «запасным» вариантом: встроить обработку в конфигурацию. Это позволит использовать преимущества управляемых форм в полной мере и избежать проблем с контекстами. Если же встраивание невозможно, следуйте этим правилам:
ОбработкаЗаполнения структуры с флагами, которые логика документа может распознать как сигнал «не показывать диалоги».Подводя итог: «обход» директивы препроцессора — это всегда переход в контекст, где эта директива неактивна (то есть на сервер). Планируйте архитектуру ваших обработок так, чтобы тяжелая логика и работа с документами происходили на сервере, а на клиенте оставался только ввод данных и отображение результата.