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