При разработке расширений в системе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией: нужно изменить всего одну строку в модуле формы типовой конфигурации. Однако при переносе процедуры в расширение конфигуратор начинает выдавать массу ошибок о том, что переменные, реквизиты или элементы формы не определены. В этой статье мы подробно разберем, почему это происходит, как правильно добавлять объекты в расширение и какие современные инструменты платформы позволяют минимизировать объем копируемого кода.
Проанализируем механику работы расширений. Когда мы создаем расширение и добавляем в него форму документа, мы получаем «пустую оболочку» формы. Модуль этой формы в расширении изначально пуст, и это нормально. Проблема возникает, когда мы копируем процедуру из основной конфигурации и используем аннотацию &Вместо.
Основная причина ошибок «Переменная не определена» заключается в том, что расширение — это отдельный программный контекст. Для того чтобы код расширения успешно прошел проверку (скомпилировался), он должен «знать» о существовании всех объектов, к которым обращается. Рассмотрим основные сценарии возникновения этих ошибок:
Объект.Дата или ЭтаФорма.Товары, эти реквизиты должны быть явно добавлены в расширение.Элементы.ГруппаКнопки вызовут ошибку, если элемент управления не перенесен в расширение.Экспорт, принципиально недоступны в расширении при использовании аннотации &Вместо.Если вы решили полностью заменить метод основной конфигурации, вам необходимо обеспечить расширение всеми необходимыми метаданными. Разберем по шагам, как это сделать правильно, чтобы избежать ошибок компиляции.
Шаг 1. Добавление реквизитов. Найдите нужный реквизит (например, в объекте или в самой форме) в дереве основной конфигурации, нажмите правую кнопку мыши и выберите «Добавить в расширение». Обратите внимание, что добавлять «весь объект» (весь документ или справочник) целиком обычно не требуется — достаточно перенести только те реквизиты, которые участвуют в коде.
Шаг 2. Добавление элементов формы. Перейдите в редактор формы расширения. В окне элементов формы (слева) вы увидите дерево элементов. Найдите те, к которым обращается ваш код, и также используйте команду «Добавить в расширение». Они станут доступны для обращения через коллекцию Элементы.
Шаг 3. Перенос процедуры. Используйте следующий шаблон кода:
&Вместо("РассчитатьСуммуДокумента")
Процедура расш1_РассчитатьСуммуДокумента()
// Копируем сюда весь текст типовой процедуры
// И вносим свое исправление в нужной строке
Объект.Сумма = Объект.Количество * Объект.Цена; // Наша измененная строка
КонецПроцедуры
Помните: фраза «конфигуратор будет ругаться, но работать будет» — это опасное заблуждение. Если конфигуратор выдает критические ошибки при проверке модуля, расширение может либо вообще не подключиться в режиме Предприятия, либо вызвать аварийное завершение работы при попытке выполнить данный код.
Начиная с версии платформы 8.3.15, появился гораздо более элегантный способ исправления «одной строки». Аннотация &ИзменениеИКонтроль позволяет не просто заменять код, а контролировать изменения в типовой конфигурации. Это значительно упрощает поддержку расширения при обновлениях.
Рассмотрим, как это выглядит на практике. Допустим, нам нужно изменить расчет налога в длинной процедуре:
&ИзменениеИКонтроль("РассчитатьНалоги")
Процедура расш1_РассчитатьНалоги()
// Весь оригинальный код процедуры...
#Вставка
// Наш новый код, который добавится в логику
КоэффициентНалога = 0.2;
#КонецВставки
#Удаление
// Здесь указывается код из типовой конфигурации, который нужно игнорировать
КоэффициентНалога = 0.18;
#КонецУдаления
// Продолжение оригинального кода...
КонецПроцедуры
Преимущества этого метода:
#Вставка, #Удаление или #Изменение.Проанализируем ситуацию, когда нам нужно изменить реакцию на событие (например, при изменении поля). Вместо того чтобы переопределять стандартную процедуру ИмяПоляПриИзменении, мы можем добавить свой собственный обработчик.
Разберем алгоритм действий:
расш1_МояПроцедураПриИзменении.ПриСозданииНаСервере с аннотацией &После.
&После("ПриСозданииНаСервере")
Процедура расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Элемент = Элементы.Найти("Цена");
Если Элемент <> Неопределено Тогда
Элемент.УстановитьДействие("ПриИзменении", "расш1_МояПроцедураПриИзменении");
КонецЕсли;
КонецПроцедуры
Этот метод считается наиболее «чистым», так как он вообще не затрагивает текст типовых процедур и сводит риск конфликтов при обновлении к минимуму.
Рассмотрим несколько технических деталей, без которых работа расширения может быть нестабильной:
Режим совместимости. Это критически важный параметр. Режим совместимости расширения должен строго соответствовать режиму совместимости основной конфигурации. Если в основной базе стоит «8.3.14», а в расширении по умолчанию установилось «8.3.21», многие механизмы работы с формами могут вести себя непредсказуемо, вызывая ошибки типов.
Обход ограничений доступа к переменным. Если вам все же необходимо получить значение переменной модуля, которая не является экспортной и недоступна в расширении, попробуйте использовать методы &Перед или &После. В этих аннотациях вы можете модифицировать параметры, передаваемые в процедуру, или изменять состояние реквизитов объекта, не копируя весь сложный алгоритм целиком.
Безопасность и роли. В свойствах расширения обратите внимание на флаг «Использовать основные роли для всех пользователей». Если этот флаг снят, а вы добавили новые объекты метаданных в расширение, пользователи могут получить ошибку прав доступа, даже если в основной конфигурации у них есть полные права.
Подведем итог: для успешного исправления «одной строки» в расширении важно не просто копировать код, а обеспечивать его контекстом (добавлять реквизиты и элементы в расширение) и выбирать наиболее подходящую аннотацию (предпочтительно &ИзменениеИКонтроль или программное назначение обработчиков). Это сделает вашу разработку надежной и легкой в поддержке.