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