Директива &ИзменениеИКонтроль является мощным инструментом разработчика, позволяющим модифицировать существующие методы конфигурации, сохраняя контроль над изменениями со стороны поставщика. Однако на практике программисты часто сталкиваются с ситуацией, когда расширение либо «молча» перестает работать, либо выдает ошибки применимости без видимых причин. В этой статье мы подробно разберем, как устроен механизм контроля, почему он крайне чувствителен к форматированию и как заставить его работать стабильно.
Механизм &ИзменениеИКонтроль работает по принципу посимвольного сравнения текста метода в расширении с текстом в основной конфигурации. Платформа ожидает, что весь текст вне специальных тегов #Вставка и #Удаление будет идентичен оригиналу. Рассмотрим ситуацию: если разработчик основной конфигурации изменил хотя бы один символ в методе (например, добавил пробел), расширение должно выдать ошибку применимости.
Проанализируем основную проблему: почему расширение иногда не выдает ошибку, но при этом выполняется оригинальный код? Чаще всего это происходит из-за несоответствия версии платформы или режима совместимости. Если режим совместимости основной конфигурации ниже 8.3.15, директива может вести себя непредсказуемо. Также в ранних версиях 8.3.15-8.3.17 наблюдались баги, при которых проверка применимости игнорировала клиентские методы, просто пропуская выполнение расширения без уведомлений.
Самая распространенная причина сбоев — чувствительность к невидимым символам. Платформа сравнивает текст метода «как есть». Посмотрим на пример типичной ошибки форматирования:
&ИзменениеИКонтроль("РассчитатьСумму")
Процедура РассчитатьСумму(Параметры)
// Текст до изменения
Сумма = Параметры.Цена * Параметры.Количество;
#Вставка
Сумма = Сумма * (1 - Скидка / 100);
#КонецВставки
// ОШИБКА: если здесь в оригинале нет пустой строки, а в расширении она есть — контроль не пройдет
КонецПроцедуры
Разберем основные правила работы с текстом метода:
#Вставка / #Удаление, если их нет в оригинальном коде.#Вставка...#КонецВставки, приведет к ошибке применимости.Alt+Shift+F). Оно может расставить пробелы или табуляции иначе, чем в исходном коде конфигурации, что мгновенно «сломает» связь.Проанализируем еще одну тонкую ситуацию: объявление заголовка функции в несколько строк. Если в основной конфигурации заголовок метода разбит на строки, то и в расширении он должен быть скопирован в точности так же. Рассмотрим пример:
// В основной конфигурации:
Функция ВыполнитьДействие(
Параметр1,
Параметр2) Экспорт
// В расширении ДОЛЖНО БЫТЬ ТАК ЖЕ:
&ИзменениеИКонтроль("ВыполнитьДействие")
Функция ВыполнитьДействие(
Параметр1,
Параметр2) Экспорт
Если вы запишете заголовок в одну строку в расширении, платформа может выдать ошибку несоответствия текста модуля, даже если само тело функции совпадает идеально. Выясним причину: парсер 1С при работе с &ИзменениеИКонтроль учитывает структуру заголовка как часть проверяемого текста.
Для корректной работы механизма контроля необходимо соблюдение следующих условий:
Когда конфигурация поставщика обновляется, нам нужно актуализировать расширение. В конфигураторе предусмотрена кнопка «Восстановить соответствие». Однако она часто бывает неактивна. Посмотрим, как это исправить:
Чтобы система могла автоматически объединить ваш измененный код с новым кодом поставщика, необходимо настроить внешнюю программу сравнения/объединения (например, KDiff3 или P4Merge). Пройдем по шагам настройки:
После этого при возникновении ошибки несоответствия текста модуля вы сможете нажать на гиперссылку в окне проверки применимости и визуально объединить изменения в трехпанельном режиме.
Рассмотрим интересный прием, который позволяет использовать &ИзменениеИКонтроль для передачи дополнительных данных. Платформа позволяет изменять имена параметров в заголовке функции расширения, при условии, что их количество остается неизменным. Проанализируем пример использования:
// Оригинал: Процедура Печать(Объект, ПараметрыПечати)
&ИзменениеИКонтроль("Печать")
Процедура РК_Печать(Объект, ДополнительныеДанные) Экспорт
#Вставка
Если ТипЗнч(ДополнительныеДанные) = Тип("Структура") Тогда
// Обработка данных, переданных из нашего расширения
КонецЕсли;
#КонецВставки
КонецПроцедуры
Это позволяет «подменить» смысл параметра, сохраняя при этом контроль над кодом метода. Главное — следить, чтобы количество аргументов строго совпадало с оригиналом.
Иногда даже после исправления всех пробелов ошибка продолжает возникать. Проанализируем ситуацию с кэшем. Платформа 1С кэширует скомпилированные модули расширений. Если вы столкнулись с необъяснимым поведением &ИзменениеИКонтроль, попробуйте следующее:
Резюмируем: работа с &ИзменениеИКонтроль требует аптекарской точности. Копируйте код из оригинала через Ctrl+C / Ctrl+V, никогда не меняйте форматирование вне блоков вставки и всегда держите под рукой настроенную утилиту трехстороннего сравнения. Только такой подход гарантирует, что ваши изменения не «отвалятся» незаметно для службы поддержки и пользователей.