Почему в расширении 1С не определены процедуры ПоказатьПредупреждение и ЗаписатьНаКлиенте?

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

При разработке расширений для конфигураций на базе 1С:Предприятие 8.3 (например, ЗУП 3.1 или БУХ 3.0) программисты часто сталкиваются с ситуацией, когда стандартный код, скопированный из основной конфигурации, отказывается компилироваться в расширении. Система выдает ошибки вида «Процедура или функция с указанным именем не определена», сопровождая их пометкой «Проверка: Сервер», даже если процедура помечена директивой &НаКлиенте. В этой статье мы подробно разберем причины этой проблемы, проанализируем нюансы работы с асинхронными вызовами и определим наиболее безопасные методы модификации типового кода.

Причина 1: Неправильная компиляция и контекст модуля

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

Несмотря на то что вы могли написать директиву &НаКлиенте, механизм проверки расширения может пытаться скомпилировать этот код для серверного контекста. Это происходит в следующих случаях:

Для исправления ситуации необходимо убедиться, что перед процедурой &Вместо (или другой аннотацией) явно указана директива &НаКлиенте. Рассмотрим правильный пример оформления:


&Вместо("КомандаВыполнитьСейчас")
&НаКлиенте
Процедура Рассылка_КомандаВыполнитьСейчасВместо(Команда)
    // Ваш измененный код
    Если Не Объект.Подготовлена Тогда
        ПоказатьПредупреждение(, НСтр("ru = 'Рассылка не подготовлена!'"));
        Возврат;
    КонецЕсли;
    
    ПараметрыЗаписи = Новый Структура;
    ПараметрыЗаписи.Вставить("ИмяКоманды", "КомандаВыполнитьСейчас");
    ЗаписатьНаКлиенте(Неопределено, ПараметрыЗаписи);
КонецПроцедуры

Причина 2: Заимствование объектов vs Ручное написание

Проанализируем спор о том, как лучше добавлять код в расширение. Существует два подхода: заимствование метода через контекстное меню («Добавить в расширение») и ручное написание кода с использованием аннотаций.

Мы рекомендуем использовать механизм заимствования. Когда вы нажимаете правой кнопкой мыши на процедуру в основной конфигурации и выбираете «Добавить в расширение», платформа автоматически:

  1. Создает правильную структуру аннотаций (&Вместо, &Перед и т.д.).
  2. Переносит правильные директивы компиляции (&НаКлиенте, &НаСервере).
  3. Связывает контекст формы расширения с контекстом основной формы, что позволяет корректно обращаться к реквизиту Объект и стандартным методам платформы.

Если вы пишете код вручную, вы рискуете допустить синтаксическую ошибку в аннотации или не заимствовать необходимые реквизиты формы, без которых методы платформы не пройдут проверку на клиенте.

Порядок выполнения процедур при использовании &Перед

Рассмотрим ситуацию, когда при использовании директивы &Перед предупреждение из расширения визуально срабатывает после кода основной конфигурации. Это вызывает путаницу, но имеет логическое объяснение в архитектуре 1С.

Метод ПоказатьПредупреждение является асинхронным. В отличие от старого модального вызова Предупреждение, он не останавливает выполнение программного кода. Выясним, что происходит в стеке вызовов:

  1. Выполняется процедура расширения &Перед.
  2. Вызывается ПоказатьПредупреждение. Программа просто дает команду системе отрисовать окно и сразу идет дальше.
  3. Завершается код расширения и тут же начинает работать код основной конфигурации.
  4. Основная конфигурация тоже вызывает свое окно предупреждения.

В итоге в очереди графического интерфейса оказываются сразу две команды. Визуально пользователь может увидеть их в обратном порядке или перекрывающими друг друга. Чтобы проверить реальный порядок выполнения кода, мы рекомендуем заменить ПоказатьПредупреждение на Сообщить(). Сообщения выводятся в окно сообщений строго в порядке их вызова в коде, что позволит вам убедиться в работоспособности расширения.

Выбор между &Вместо и &ИзменениеИКонтроль

Проанализируем вопрос стабильности вашего расширения при обновлениях программы. Использование директивы &Вместо является радикальным методом, так как оно полностью подменяет логику типовой конфигурации. Если в новом релизе ЗУП фирма «1С» добавит в эту процедуру критически важную проверку, ваше расширение ее проигнорирует, что может привести к ошибкам в данных.

Рассмотрим альтернативу — директиву &ИзменениеИКонтроль. Этот механизм позволяет:

Пример использования &ИзменениеИКонтроль:


&ИзменениеИКонтроль("КомандаВыполнитьСейчас")
&НаКлиенте
Процедура Рассылка_КомандаВыполнитьСейчас(Команда)
    Если Не Объект.Подготовлена Тогда
        #Вставка
        ПоказатьПредупреждение(, НСтр("ru = 'Внимание! Рассылка еще не подготовлена специалистом.'"));
        #КонецВставки
        #Удаление
        // ПоказатьПредупреждение(, НСтр("ru = 'Рассылка не подготовлена.'"));
        #КонецУдаления
        Возврат;
    КонецЕсли;
    
    // Остальной код остается без изменений и контролируется платформой
    ПараметрыЗаписи = Новый Структура;
    ПараметрыЗаписи.Вставить("ИмяКоманды", "КомандаВыполнитьСейчас");
    ЗаписатьНаКлиенте(Неопределено, ПараметрыЗаписи);
КонецПроцедуры

Подведем итоги

Для успешного создания расширения в ЗУП 3.1 придерживайтесь следующих правил:

  1. Всегда проверяйте наличие директивы &НаКлиенте непосредственно перед аннотацией метода.
  2. Предпочитайте заимствование методов через интерфейс конфигуратора ручному набору кода.
  3. Помните об асинхронности методов ПоказатьПредупреждение и ПоказатьВопрос — они не блокируют выполнение последующего кода.
  4. Если нужно гарантированно прервать выполнение стандартной логики, используйте &Вместо или &ИзменениеИКонтроль, так как &Перед не позволяет отменить вызов основной процедуры.
← На главную