При переносе кода или интеграции сторонних подсистем между базами с разными версиями платформы 1С:Предприятие разработчики часто сталкиваются с неожиданным поведением системы. Одной из таких неприятных проблем является ошибка «Конструктор не найден» при вызове процедуры или функции общего модуля на клиенте. Особенно остро эта проблема проявляется, когда на компьютере разработчика установлена современная версия платформы (например, 8.3.13 и выше), а у конечного пользователя или на сервере внедрения крутится более старый релиз (например, 8.3.10).
В этой статье мы подробно разберем, почему возникает данная ошибка, как она связана с эволюцией встроенного языка 1С, изучим правила работы с объектом ОписаниеОповещения, а также рассмотрим практические способы решения проблемы без необходимости экстренного обновления платформы.
Давайте проанализируем ситуацию. Источником проблемы в подавляющем большинстве случаев является создание объекта обратного вызова через конструктор Новый ОписаниеОповещения. В зависимости от версии платформы встроенный язык по-разному интерпретирует синтаксис этого конструктора:
Новый ОписаниеОповещения вообще без параметров. Это очень удобно, когда нам нужно вызвать асинхронный метод платформы (например, открыть форму или показать предупреждение), но реальной обработки результата или закрытия окна в коде делать не требуется. Платформа позволяет опустить параметры, чтобы не создавать пустые процедуры-заглушки.Новый ОписаниеОповещения() приводила к мгновенной ошибке компиляции «Конструктор не найден», поскольку система ожидала обязательного указания целевой процедуры и модуля для обратного вызова.Таким образом, если код разрабатывался и успешно тестировался на платформе 8.3.13, а затем был запущен на платформе 8.3.10, выполнение прервется ошибкой на первой же строчке с пустым конструктором оповещения.
Даже если мы откроем Синтакс-Помощник в старой версии платформы, мы можем увидеть следующее описание конструктора:
Новый ОписаниеОповещения(<ИмяПроцедуры>, <Модуль>, <ДополнительныеПараметры>, <ИмяПроцедурыОбработкиОшибки>, <МодульОбработкиОшибки>)
Знак угловых скобок традиционно указывает на то, что параметры являются необязательными. Однако здесь кроется важная логическая взаимосвязь, несоблюдение которой также вызывает ошибку «Конструктор не найден»:
Новый ОписаниеОповещения("ОбработатьВыбор") вернет ошибку, так как системе неизвестно, где искать эту процедуру. Правильный вызов требует явного указания контекста: Новый ОписаниеОповещения("ОбработатьВыбор", ЭтотОбъект) или ЭтотОбъект (в зависимости от контекста формы/модуля).Если перед вами стоит задача запустить конфигурацию на старом релизе платформы (например, 8.3.10) без возможности ее немедленного обновления, нам придется отказаться от использования пустого конструктора. Для этого применим классический паттерн разработки с использованием процедуры-заглушки.
Рассмотрим по шагам, как переписать проблемный участок кода:
Шаг 1. Создадим в модуле формы или в клиентском общем модуле пустую экспортную процедуру, которая будет выступать в роли приемника вызова. Она должна содержать стандартные параметры для обработки оповещения.
&НаКлиенте
Процедура ЗаглушкаОповещения(Результат, ДополнительныеПараметры) Экспорт
// Здесь ничего не делаем, процедура нужна только для прохождения валидации конструктора
КонецПроцедуры
Шаг 2. Заменим инициализацию пустого объекта ОписаниеОповещения на явный вызов с указанием нашей заглушки и контекста модуля:
// Старый код, вызывавший ошибку на 8.3.10:
// Оповещение = Новый ОписаниеОповещения;
// Новый кроссплатформенный код:
Оповещение = Новый ОписаниеОповещения("ЗаглушкаОповещения", ЭтотОбъект);
Такой подход гарантированно запустится на любой версии платформы 1С:Предприятие 8.3, обеспечивая стабильную работу вашего прикладного решения.
Если в перспективе ваша компания планирует обновить технологическую платформу до современных релизов, мы рекомендуем полностью отказаться от использования механизма ОписаниеОповещения в пользу новых конструкций встроенного языка.
Начиная с версии платформы 8.3.18, разработчикам стал доступен механизм асинхронного программирования с использованием ключевых слов Асинх и Ждать. Это позволяет писать лаконичный и понятный линейный код без создания «спагетти» из разрозненных процедур-обработчиков.
Давайте сравним два подхода на примере вызова простого вопроса пользователю.
Традиционный подход с Описанием Оповещения:
&НаКлиенте
Процедура ВыполнитьДействие(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеВопроса", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Вы уверены?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
// Основная логика обработки
КонецЕсли;
КонецПроцедуры
Современный подход с использованием Асинх/Ждать:
&НаКлиенте
Асинх Процедура ВыполнитьДействие(Команда)
Результат = Ждать ПоказатьВопросАсинх("Вы уверены?", РежимДиалогаВопрос.ДаНет);
Если Результат = КодВозвратаДиалога.Да Тогда
// Основная логика обработки пишется прямо здесь!
КонецЕсли;
КонецПроцедуры
Как мы видим, современный подход избавляет нас от необходимости плодить вспомогательные экспортные процедуры, снижает вероятность ошибок при передаче параметров контекста и делает код значительно более читаемым и простым в поддержке.
В процессе интеграции новых подсистем разработчики часто упускают из виду проверку синтаксиса, надеясь на то, что «у меня на компьютере все работает». Чтобы избежать подобных проблем при развертывании у клиентов, возьмите за правило использовать встроенный инструмент проверки конфигурации.
Вы можете эмулировать проверку кода под требования конкретной версии платформы. Для этого выполните следующие действия:
Платформа автоматически проанализирует весь исходный код конфигурации и подсветит строки, содержащие конструкции, недопустимые в выбранном режиме обратной совместимости. Это позволит вам обнаружить некорректно инициализированные объекты ОписаниеОповещения еще до того, как код попадет к конечным пользователям.