С выходом платформы «1С:Предприятие» версии 8.3.15 у разработчиков появился мощный инструмент для кастомизации конфигураций через расширения — аннотация &ИзменениеИКонтроль. Этот механизм позволяет точечно внедряться в код типовых процедур и функций, избегая полного замещения метода (как это происходит при использовании &Вместо). Однако на практике программисты часто сталкиваются с неочевидными синтаксическими ошибками компилятора, наиболее популярная из которых: «Ожидается оператор препроцессора».
В этой статье мы подробно разберем причины возникновения данной ошибки, проанализируем синтаксис директив, рассмотрим влияние режима совместимости и изучим важные архитектурные правила работы с механизмом &ИзменениеИКонтроль.
Разберем ситуацию, с которой сталкиваются многие разработчики. При попытке применить аннотацию компилятор выдает ошибку следующего вида:
{РасширениеУТ11_ЮК Обработка.ПечатьСчетовНаОплату.МодульМенеджера(98,3)}: Ожидается оператор препроцессора
#<<?>>Вставить (Проверка: Сервер)
{РасширениеУТ11_ЮК Обработка.ПечатьСчетовНаОплату.МодульМенеджера(117,3)}: Ожидается оператор препроцессора
#<<?>>КонецВставить (Проверка: Сервер)
Выясним причину этой проблемы. В предварительных анонсах компании «1С» и ранних маркетинговых материалах на зазеркалье фигурировали глагольные формы директив препроцессора: #Вставить / #КонецВставить и #Удалить / #КонецУдалить.
Однако в финальный релиз платформы вошли существительные. Компилятор ожидает строго определенные операторы:
#Удаление и #КонецУдаления#Вставка и #КонецВставкиЕсли вы напишете глагол (например, #Вставить), платформа вас не поймет и выдаст ошибку ожидания оператора. Перейдем к правильному примеру написания кода.
Рассмотрим, как должен выглядеть корректный шаблон процедуры с использованием правильного синтаксиса:
&ИзменениеИКонтроль("ЗаполнитьРеквизитыПодвалаСчетаНаОплату")
Процедура Расш1_ЗаполнитьРеквизитыПодвалаСчетаНаОплату(ДанныеПечати, Макет, ТабличныйДокумент, ТаблицаЭтапыОплаты, СоответствиеСтавокНДС, ПараметрыПечати)
// Какой-то оригинальный код процедуры...
#Удаление
// Здесь находится оригинальный код, который мы хотим исключить из выполнения
СуммаДокумента = ДанныеПечати.Всего;
#КонецУдаления
#Вставка
// Здесь пишем наш собственный измененный код
СуммаДокумента = ДанныеПечати.Всего + СкидкаКлиента;
#КонецВставки
// Продолжение оригинального кода...
КонецПроцедуры
Довольно часто разработчики полагают, что если основная конфигурация (например, УТ 11, ERP или БП) находится на старом режиме совместимости (например, 8.3.12 или 8.3.14), то использовать новый механизм &ИзменениеИКонтроль невозможно до полного обновления базы. Это заблуждение.
Проанализируем ключевые факторы работы компилятора:
Если в свойствах расширения остался старый режим совместимости (например, скопированный из основной конфигурации 8.3.14), платформа применит старые правила парсинга кода, проигнорирует существование новых директив и выдаст синтаксическую ошибку.
Разберем еще одну неочевидную ошибку, которая часто возникает сразу после того, как программист исправляет синтаксис директив. При попытке применить расширение система выдает ошибку вида: «Код модуля изменился» или «Текст метода не соответствует методу...».
Платформа осуществляет строжайший посимвольный контроль оригинального кода внутри заимствованного метода. Любое изменение за пределами блоков #Вставка...#КонецВставки и #Удаление...#КонецУдаления расценивается как нарушение целостности контроля.
Что категорически нельзя делать в тексте метода:
// приведет к ошибке).Разработчикам важно знать об одной очень удобной особенности синтаксического контроля при использовании &ИзменениеИКонтроль. Платформа 1С «прощает» отсутствие заимствованных объектов и переменных в расширении, если они не задействованы непосредственно в вашем измененном коде.
При проверке модуля конфигуратор полностью игнорирует ошибки вида «Переменная не определена» во всех частях метода, кроме тех, которые находятся внутри добавленного вами блока #Вставка ... #КонецВставки.
Это избавляет нас от рутинной необходимости переносить в расширение множество служебных переменных, реквизитов формы или объектов метаданных, которые просто упоминаются в теле оригинальной процедуры, но никак не затрагивают логику нашей точечной доработки.
При проектировании архитектуры доработок обязательно учитывайте ключевое отличие &ИзменениеИКонтроль от классической аннотации &Вместо:
&Вместо несколько расширений могут последовательно перехватывать один и тот же метод, образуя цепочку вызовов.&ИзменениеИКонтроль действует правило эксклюзивности. Один и тот же метод основной конфигурации может быть изменен с помощью этой аннотации ровно один раз во всей системе.Если в системе будет активировано второе расширение, пытающееся модифицировать ту же самую процедуру через контроль изменений, база данных выдаст ошибку применимости, и второе расширение просто не подключится.
Подведем итог и составим пошаговый чек-лист для исправления ошибок препроцессора:
#Вставка и #Удаление.Следуя этим правилам, вы сможете эффективно использовать один из самых безопасных и изящных механизмов кастомизации решений на платформе «1С:Предприятие 8.3».