Как заменить ОписаниеОповещения при переносе кода из 1С 8.3 в 1С 8.1?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При переносе модулей и алгоритмов из современных конфигураций на платформе 1С:Предприятие 8.3 в устаревшие конфигурации на 1С:Предприятие 8.1 разработчики неизбежно сталкиваются с синтаксической ошибкой отсутствия типа ОписаниеОповещения. В платформе 8.1 полностью отсутствует механизм асинхронных вызовов и функций обратного вызова (callback), таких как ПоказатьВопрос, ПоказатьПредупреждение, НачатьПодключениеВнешнейКомпоненты и сопутствующий метод ВыполнитьОбработкуОповещения.

Разберем детально, как адаптировать программный код при подобной миграции, какие существуют варианты замены и с какими ограничениями платформы 8.1 предстоит столкнуться.

Способ 1. Отказ от асинхронности и разворачивание логики в синхронный код

Проанализируем природу появления объекта ОписаниеОповещения в 8.3. В платформе 8.3 асинхронная модель внедрялась в первую очередь для работы в веб-клиенте и мобильных приложениях, где блокировка потока интерфейса недопустима, а также в рамках концепции отказа от модальности. В платформе 8.1 модальные окна и синхронное выполнение операций поддерживаются в полном объеме.

Если код обращается к стандартным диалогам или выполняет линейные операции, наиболее надежным и чистым подходом является полный отказ от обратных вызовов и возврат к классическому синхронному алгоритму. Посмотрим на типовой пример в 8.3:


// Код в 1С 8.3
Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект, ДополнительныеПараметры);
ПоказатьВопрос(Оповещение, "Продолжить операцию?", РежимДиалогаВопрос.ДаНет);

&НаКлиенте
Процедура ПослеОтветаНаВопрос(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        ВыполнитьДействие(ДополнительныеПараметры);
    КонецЕсли;
КонецПроцедуры

Для платформы 8.1 развернем эту конструкцию в единый последовательный блок, убрав лишнюю процедуру обратного вызова:


// Адаптация для 1С 8.1
Ответ = Вопрос("Продолжить операцию?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
    ВыполнитьДействие(ДополнительныеПараметры);
КонецЕсли;

Такой подход исключает дробление контекста выполнения и делает код простым для отладки и чтения в среде обычных форм 8.1.

Способ 2. Эмуляция ОписаниеОповещения через структуру и оператор Выполнить

Если переносится объемная библиотека (например, модули взаимодействия с внешними системами или торговым оборудованием), переписывать десятки процедур завершения вручную может быть слишком трудоемко. В таком случае реализуем собственную программную эмуляцию ОписаниеОповещения, сохраняющую сигнатуру вызовов.

Создадим функцию-конструктор и универсальный исполнитель в общем модуле или модуле формы:


Функция ОписаниеОповещения(ИмяПроцедуры, Модуль, ДополнительныеПараметры = Неопределено, ИмяПроцедурыОбработкиОшибки = Неопределено, МодульОбработкиОшибки = Неопределено) Экспорт
    Возврат Новый Структура(
        "ИмяПроцедуры, Модуль, ДополнительныеПараметры, ИмяПроцедурыОбработкиОшибки, МодульОбработкиОшибки",
        ИмяПроцедуры, Модуль, ДополнительныеПараметры, ИмяПроцедурыОбработкиОшибки, МодульОбработкиОшибки
    );
КонецФункции

Функция ВыполнитьКод(Код, П = Неопределено, П1 = Неопределено, П2 = Неопределено, П3 = Неопределено, П4 = Неопределено) Экспорт
    Перем Результат;
    Выполнить(Код);
    Возврат Результат;
КонецФункции

Процедура ПоказатьВопрос(ОписаниеОповещенияОЗавершении, ТекстВопроса, Кнопки, Таймаут = 0, КнопкаПоУмолчанию = Неопределено, Заголовок = "", КнопкаТаймаута = Неопределено) Экспорт
    Ответ = Вопрос(ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок, КнопкаТаймаута);
    
    Попытка
        ВыполнитьКод("П." + ОписаниеОповещенияОЗавершении.ИмяПроцедуры + "(П1, П2)", 
            ОписаниеОповещенияОЗавершении.Модуль, 
            Ответ, 
            ОписаниеОповещенияОЗавершении.ДополнительныеПараметры
        );
    Исключение
        Если ОписаниеОповещенияОЗавершении.ИмяПроцедурыОбработкиОшибки <> Неопределено 
           И ОписаниеОповещенияОЗавершении.МодульОбработкиОшибки <> Неопределено Тогда
            ВыполнитьКод("П." + ОписаниеОповещенияОЗавершении.ИмяПроцедурыОбработкиОшибки, 
                ОписаниеОповещенияОЗавершении.МодульОбработкиОшибки
            );
        Иначе
            Сообщить(ОписаниеОшибки());
        КонецЕсли;    
    КонецПопытки;    
КонецПроцедуры

Рассмотрим, как работает эта схема:

  1. Функция ОписаниеОповещения возвращает структуру с указанием целевого модуля, имени процедуры и параметров.
  2. Процедура ПоказатьВопрос синхронно получает ответ от пользователя через модальный метод Вопрос().
  3. С помощью вспомогательной функции и конструкции Выполнить() происходит вызов целевой процедуры с передачей контекста модуля в переменную П, а параметров — в переменные П1 и П2.

Важные ограничения и особенности реализации в 8.1

При использовании эмуляции через оператор Выполнить() необходимо учитывать технические нюансы платформы 8.1:

  1. Модификатор Экспорт: Вызов П.ИмяПроцедуры(...) через динамический код сработает только в том случае, если вызываемая процедура в модуле формы или объекта объявлена с ключевым словом Экспорт. Приватные неэкспортные методы вызвать таким способом невозможно.
  2. Ограничения торгового оборудования (БПО): Прямой перенос Библиотеки подключаемого оборудования (БПО) из 8.3 в 8.1 нецелесообразен. Современные драйверы используют стандарт интеграции версий 2.x–3.x и Native API, требующие асинхронных очередей. Платформа 8.1 работает строго в 32-разрядном режиме со старыми COM-компонентами. Для работы с оборудованием в 8.1 надежнее использовать модуль РаботаСТорговымОборудованием и обработки обслуживания из релизов «Управление торговлей 10.3» или «Управление производственным предприятием 1.2/1.3».
  3. Обработка событий оборудования: Для оборудования, отправляющего данные по факту считывания (сканеры штрихкодов, считыватели магнитных карт), в 8.1 используется предопределенная системная процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные) в формах документов или глобальном модуле без каких-либо цепочек оповещений.
  4. Имитация асинхронности: Если требуется прервать текущий контекст и вернуть управление интерфейсу до запуска обработчика, в 8.1 применяется метод ПодключитьОбработчикОжидания("ИмяПроцедуры", Интервал, Истина), а параметры передаются через переменные модуля.
← На главную