При переносе модулей и алгоритмов из современных конфигураций на платформе 1С:Предприятие 8.3 в устаревшие конфигурации на 1С:Предприятие 8.1 разработчики неизбежно сталкиваются с синтаксической ошибкой отсутствия типа ОписаниеОповещения. В платформе 8.1 полностью отсутствует механизм асинхронных вызовов и функций обратного вызова (callback), таких как ПоказатьВопрос, ПоказатьПредупреждение, НачатьПодключениеВнешнейКомпоненты и сопутствующий метод ВыполнитьОбработкуОповещения.
Разберем детально, как адаптировать программный код при подобной миграции, какие существуют варианты замены и с какими ограничениями платформы 8.1 предстоит столкнуться.
Проанализируем природу появления объекта ОписаниеОповещения в 8.3. В платформе 8.3 асинхронная модель внедрялась в первую очередь для работы в веб-клиенте и мобильных приложениях, где блокировка потока интерфейса недопустима, а также в рамках концепции отказа от модальности. В платформе 8.1 модальные окна и синхронное выполнение операций поддерживаются в полном объеме.
Если код обращается к стандартным диалогам или выполняет линейные операции, наиболее надежным и чистым подходом является полный отказ от обратных вызовов и возврат к классическому синхронному алгоритму. Посмотрим на типовой пример в 8.3:
// Код в 1С 8.3
Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект, ДополнительныеПараметры);
ПоказатьВопрос(Оповещение, "Продолжить операцию?", РежимДиалогаВопрос.ДаНет);
&НаКлиенте
Процедура ПослеОтветаНаВопрос(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ВыполнитьДействие(ДополнительныеПараметры);
КонецЕсли;
КонецПроцедуры
Для платформы 8.1 развернем эту конструкцию в единый последовательный блок, убрав лишнюю процедуру обратного вызова:
// Адаптация для 1С 8.1
Ответ = Вопрос("Продолжить операцию?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ВыполнитьДействие(ДополнительныеПараметры);
КонецЕсли;
Такой подход исключает дробление контекста выполнения и делает код простым для отладки и чтения в среде обычных форм 8.1.
Если переносится объемная библиотека (например, модули взаимодействия с внешними системами или торговым оборудованием), переписывать десятки процедур завершения вручную может быть слишком трудоемко. В таком случае реализуем собственную программную эмуляцию ОписаниеОповещения, сохраняющую сигнатуру вызовов.
Создадим функцию-конструктор и универсальный исполнитель в общем модуле или модуле формы:
Функция ОписаниеОповещения(ИмяПроцедуры, Модуль, ДополнительныеПараметры = Неопределено, ИмяПроцедурыОбработкиОшибки = Неопределено, МодульОбработкиОшибки = Неопределено) Экспорт
Возврат Новый Структура(
"ИмяПроцедуры, Модуль, ДополнительныеПараметры, ИмяПроцедурыОбработкиОшибки, МодульОбработкиОшибки",
ИмяПроцедуры, Модуль, ДополнительныеПараметры, ИмяПроцедурыОбработкиОшибки, МодульОбработкиОшибки
);
КонецФункции
Функция ВыполнитьКод(Код, П = Неопределено, П1 = Неопределено, П2 = Неопределено, П3 = Неопределено, П4 = Неопределено) Экспорт
Перем Результат;
Выполнить(Код);
Возврат Результат;
КонецФункции
Процедура ПоказатьВопрос(ОписаниеОповещенияОЗавершении, ТекстВопроса, Кнопки, Таймаут = 0, КнопкаПоУмолчанию = Неопределено, Заголовок = "", КнопкаТаймаута = Неопределено) Экспорт
Ответ = Вопрос(ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок, КнопкаТаймаута);
Попытка
ВыполнитьКод("П." + ОписаниеОповещенияОЗавершении.ИмяПроцедуры + "(П1, П2)",
ОписаниеОповещенияОЗавершении.Модуль,
Ответ,
ОписаниеОповещенияОЗавершении.ДополнительныеПараметры
);
Исключение
Если ОписаниеОповещенияОЗавершении.ИмяПроцедурыОбработкиОшибки <> Неопределено
И ОписаниеОповещенияОЗавершении.МодульОбработкиОшибки <> Неопределено Тогда
ВыполнитьКод("П." + ОписаниеОповещенияОЗавершении.ИмяПроцедурыОбработкиОшибки,
ОписаниеОповещенияОЗавершении.МодульОбработкиОшибки
);
Иначе
Сообщить(ОписаниеОшибки());
КонецЕсли;
КонецПопытки;
КонецПроцедуры
Рассмотрим, как работает эта схема:
ОписаниеОповещения возвращает структуру с указанием целевого модуля, имени процедуры и параметров.ПоказатьВопрос синхронно получает ответ от пользователя через модальный метод Вопрос().Выполнить() происходит вызов целевой процедуры с передачей контекста модуля в переменную П, а параметров — в переменные П1 и П2.При использовании эмуляции через оператор Выполнить() необходимо учитывать технические нюансы платформы 8.1:
П.ИмяПроцедуры(...) через динамический код сработает только в том случае, если вызываемая процедура в модуле формы или объекта объявлена с ключевым словом Экспорт. Приватные неэкспортные методы вызвать таким способом невозможно.РаботаСТорговымОборудованием и обработки обслуживания из релизов «Управление торговлей 10.3» или «Управление производственным предприятием 1.2/1.3».ОбработкаВнешнегоСобытия(Источник, Событие, Данные) в формах документов или глобальном модуле без каких-либо цепочек оповещений.ПодключитьОбработчикОжидания("ИмяПроцедуры", Интервал, Истина), а параметры передаются через переменные модуля.