Как правильно выполнить процедуру на клиенте через ОписаниеОповещения в 1С

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

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

Суть проблемы: почему процедура не найдена?

Рассмотрим стандартную ситуацию: нам нужно открыть форму для ввода данных (например, уточнения количества товара) и по завершении выполнить какой-то код на клиенте, чтобы обновить показатели в основной форме. Мы создаем объект ОписаниеОповещения, указываем имя процедуры и модуль, но при попытке вызова получаем системную ошибку о том, что метод не обнаружен. Проанализируем типичный ошибочный код:


// Вызов открытия формы
ПараметрыТовара = Новый Структура("Артикул, Количество", "001", 10);
Оповещение = Новый ОписаниеОповещения("ОбновитьПоказатели", ЭтаФорма, ПараметрыТовара);

ОткрытьФорму("ОбщаяФорма.ЗапросКоличества", , , , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);

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

Решение: ключевое слово Экспорт

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

Правильное объявление процедуры в модуле формы должно выглядеть следующим образом:


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

Обратите внимание, что автор исходного вопроса использовал Функция. Технически платформа проглотит это, но хорошим тоном и стандартом разработки 1С считается использование именно Процедура, так как возвращаемое значение всё равно никуда не передается.

Разбор параметров ОписанияОповещения

Давайте проанализируем структуру конструктора Новый ОписаниеОповещения, чтобы понимать, как передавать данные между вызовами:

  1. ИмяПроцедуры (Строка): Имя той самой экспортной процедуры, которую мы создали.
  2. Модуль (Объект): Обычно это ЭтаФорма, если обработчик находится в текущей форме. Если обработчик в общем модуле — передается сам общий модуль.
  3. ДополнительныеПараметры (Произвольный): Любые данные, которые вам понадобятся «потом». Это критически важно, так как при асинхронном вызове контекст локальных переменных теряется, и всё нужное нужно «упаковать» в этот параметр.

Важные требования к процедуре-обработчику

Чтобы всё «взлетело», недостаточно просто добавить Экспорт. Проанализируем еще несколько жестких требований платформы:

1. Количество параметров. Процедура-обработчик обязана принимать ровно два параметра. Даже если вы не собираетесь использовать ДополнительныеПараметры, они должны быть в заголовке процедуры. В противном случае возникнет ошибка времени выполнения.

2. Контекст исполнения. Если вы вызываете оповещение из модуля команды, вы не можете передать ЭтаФорма в качестве модуля. В этом случае обработчик должен располагаться либо в самом модуле команды (с Экспорт), либо в общем модуле, у которого стоят флаги Клиент (управляемое приложение) и Вызов сервера (если нужно).

3. Отладка. Помните, что при срабатывании оповещения стек вызовов обрывается. Вы не увидите в отладчике ту процедуру, из которой открывали форму. Это особенность асинхронности — выполнение кода «засыпает» и просыпается уже в новой точке.

Современный подход: Асинхронные вызовы (Ждать)

Начиная с версии платформы 8.3.18, фирма «1С» представила более элегантный механизм — асинхронные функции. Вместо того чтобы дробить код на «вызывающий» и «обрабатывающий», мы можем писать линейный код. Рассмотрим, как это упрощает жизнь:


&НаКлиенте
Асинх Процедура ИзменитьКоличествоНаКлиенте()
    
    ПараметрыФормы = Новый Структура("ТекущееКоличество", 10);
    
    // Вместо ОписанияОповещения используем Ждать
    Результат = Ждать ОткрытьФормуАсинх("ОбщаяФорма.ЗапросКоличества", ПараметрыФормы);
    
    Если Результат <> Неопределено Тогда
        // Код выполняется здесь же, сохраняя доступ к локальным переменным!
        ОбновитьПоказателиНаСервере(Результат.Количество);
    КонецЕсли;
    
КонецПроцедуры

Использование оператора Ждать и метода ОткрытьФормуАсинх избавляет от необходимости плодить экспортные процедуры и вручную пробрасывать структуру дополнительных параметров. Это делает код чище и понятнее для поддержки.

Выводы и рекомендации

Если вы работаете на версиях платформы ниже 8.3.18 или поддерживаете старый код, помните золотые правила ОписаниеОповещения:

Соблюдение этих простых правил убережет вас от трудноуловимых ошибок «Метод не найден» и позволит строить отзывчивые интерфейсы с блокировкой только нужных участков программы.

← На главную