При разработке расширений для конфигураций на базе 1С:Предприятие 8.3 (например, ЗУП 3.1 или БУХ 3.0) программисты часто сталкиваются с ситуацией, когда стандартный код, скопированный из основной конфигурации, отказывается компилироваться в расширении. Система выдает ошибки вида «Процедура или функция с указанным именем не определена», сопровождая их пометкой «Проверка: Сервер», даже если процедура помечена директивой &НаКлиенте. В этой статье мы подробно разберем причины этой проблемы, проанализируем нюансы работы с асинхронными вызовами и определим наиболее безопасные методы модификации типового кода.
Разберем ситуацию, когда при добавлении процедуры в модуль формы расширения система сообщает, что методы ПоказатьПредупреждение или ЗаписатьНаКлиенте не найдены. Обратите внимание на текст ошибки в конфигураторе: (Проверка: Сервер). Это ключевой индикатор проблемы.
Несмотря на то что вы могли написать директиву &НаКлиенте, механизм проверки расширения может пытаться скомпилировать этот код для серверного контекста. Это происходит в следующих случаях:
Для исправления ситуации необходимо убедиться, что перед процедурой &Вместо (или другой аннотацией) явно указана директива &НаКлиенте. Рассмотрим правильный пример оформления:
&Вместо("КомандаВыполнитьСейчас")
&НаКлиенте
Процедура Рассылка_КомандаВыполнитьСейчасВместо(Команда)
// Ваш измененный код
Если Не Объект.Подготовлена Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Рассылка не подготовлена!'"));
Возврат;
КонецЕсли;
ПараметрыЗаписи = Новый Структура;
ПараметрыЗаписи.Вставить("ИмяКоманды", "КомандаВыполнитьСейчас");
ЗаписатьНаКлиенте(Неопределено, ПараметрыЗаписи);
КонецПроцедуры
Проанализируем спор о том, как лучше добавлять код в расширение. Существует два подхода: заимствование метода через контекстное меню («Добавить в расширение») и ручное написание кода с использованием аннотаций.
Мы рекомендуем использовать механизм заимствования. Когда вы нажимаете правой кнопкой мыши на процедуру в основной конфигурации и выбираете «Добавить в расширение», платформа автоматически:
&Вместо, &Перед и т.д.).&НаКлиенте, &НаСервере).Объект и стандартным методам платформы.Если вы пишете код вручную, вы рискуете допустить синтаксическую ошибку в аннотации или не заимствовать необходимые реквизиты формы, без которых методы платформы не пройдут проверку на клиенте.
Рассмотрим ситуацию, когда при использовании директивы &Перед предупреждение из расширения визуально срабатывает после кода основной конфигурации. Это вызывает путаницу, но имеет логическое объяснение в архитектуре 1С.
Метод ПоказатьПредупреждение является асинхронным. В отличие от старого модального вызова Предупреждение, он не останавливает выполнение программного кода. Выясним, что происходит в стеке вызовов:
&Перед.ПоказатьПредупреждение. Программа просто дает команду системе отрисовать окно и сразу идет дальше.В итоге в очереди графического интерфейса оказываются сразу две команды. Визуально пользователь может увидеть их в обратном порядке или перекрывающими друг друга. Чтобы проверить реальный порядок выполнения кода, мы рекомендуем заменить ПоказатьПредупреждение на Сообщить(). Сообщения выводятся в окно сообщений строго в порядке их вызова в коде, что позволит вам убедиться в работоспособности расширения.
Проанализируем вопрос стабильности вашего расширения при обновлениях программы. Использование директивы &Вместо является радикальным методом, так как оно полностью подменяет логику типовой конфигурации. Если в новом релизе ЗУП фирма «1С» добавит в эту процедуру критически важную проверку, ваше расширение ее проигнорирует, что может привести к ошибкам в данных.
Рассмотрим альтернативу — директиву &ИзменениеИКонтроль. Этот механизм позволяет:
Пример использования &ИзменениеИКонтроль:
&ИзменениеИКонтроль("КомандаВыполнитьСейчас")
&НаКлиенте
Процедура Рассылка_КомандаВыполнитьСейчас(Команда)
Если Не Объект.Подготовлена Тогда
#Вставка
ПоказатьПредупреждение(, НСтр("ru = 'Внимание! Рассылка еще не подготовлена специалистом.'"));
#КонецВставки
#Удаление
// ПоказатьПредупреждение(, НСтр("ru = 'Рассылка не подготовлена.'"));
#КонецУдаления
Возврат;
КонецЕсли;
// Остальной код остается без изменений и контролируется платформой
ПараметрыЗаписи = Новый Структура;
ПараметрыЗаписи.Вставить("ИмяКоманды", "КомандаВыполнитьСейчас");
ЗаписатьНаКлиенте(Неопределено, ПараметрыЗаписи);
КонецПроцедуры
Для успешного создания расширения в ЗУП 3.1 придерживайтесь следующих правил:
&НаКлиенте непосредственно перед аннотацией метода.ПоказатьПредупреждение и ПоказатьВопрос — они не блокируют выполнение последующего кода.&Вместо или &ИзменениеИКонтроль, так как &Перед не позволяет отменить вызов основной процедуры.