Директива &ИзменениеИКонтроль — это мощный, но чрезвычайно чувствительный инструмент в арсенале разработчика 1С. Она позволяет внедряться в логику типовых решений, сохраняя при этом контроль над тем, чтобы наши изменения не конфликтовали с обновлениями от вендора. Однако на практике многие сталкиваются с ситуацией, когда расширение внезапно перестает работать, а система просто игнорирует модифицированный код. Разберем детально, как укротить этот механизм и заставить его работать стабильно.
Прежде всего, нам нужно понять, как платформа 1С обрабатывает &ИзменениеИКонтроль. В отличие от директивы &Вместо, которая просто подменяет метод целиком, &ИзменениеИКонтроль выполняет проверку (хеширование) текста метода. Если в основной конфигурации текст метода изменился хотя бы на один невидимый символ, платформа считает, что контроль не пройден, и выполняет оригинальный код вместо кода из расширения.
Рассмотрим ситуацию: вы добавили пустую строку или лишний пробел вне блоков #Вставка или #Удаление. Для нас, людей, код выглядит одинаково. Для платформы — это два разных текста. В результате ваше расширение «отваливается», и вы видите выполнение стандартной процедуры, как это описано в проблеме автора.
Один из самых надежных способов избежать проблем с лишними пробелами — это техника полного копирования строк. Проанализируем, как это делать правильно:
Enter в конце строки. Вместо этого выделите всю строку, которую вы хотите взять за основу, продублируйте ее, а затем замените содержимое второй строки вашим кодом, обернутым в теги.Рассмотрим пример правильного оформления вставки:
&ИзменениеИКонтроль("НачатьВнесениеДенег")
Процедура НачатьВнесениеДенег(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Касса", Объект.КассаККМ);
#Вставка
// Наш дополнительный код, строго внутри блока
ПараметрыФормы.Вставить("ДополнительныйФлаг", Истина);
#КонецВставки
ОткрытьФорму("Обработка.ВнесениеДенег.Форма", ПараметрыФормы);
КонецПроцедуры
Важный нюанс: Любое смещение табуляции вне тегов приведет к ошибке контроля. Если в оригинале используются пробелы, а у вас в конфигураторе настроены табы — контроль не пройдет.
Это критически важный момент, который часто упускают из виду. Директива &ИзменениеИКонтроль начала поддерживаться платформой начиная с версии 8.3.15. Однако работоспособность напрямую зависит от режима совместимости основной конфигурации.
Проанализируем ситуацию, описанную в обсуждении: если конфигурация (например, старая версия «Розницы») имеет режим совместимости 8.3.12, то даже на платформе 8.3.20 директива может вести себя неадекватно. Типичный симптом: код срабатывает один раз после сохранения расширения, а при повторном вызове — игнорируется.
Выясним, что делать в этом случае:
&ИзменениеИКонтроль (особенно в функциях) режим должен быть не ниже 8.3.15.&Перед, &После или &Вместо.Чтобы не гадать, сколько пробелов вставил вендор, воспользуемся штатным механизмом платформы, который появился в современных версиях. Рассмотрим алгоритм действий:
Платформа сама создаст в расширении заготовку метода с правильными заголовками и аннотациями. Это гарантирует 100% соответствие текста оригинала и расширения на момент создания. Вам останется только аккуратно вставить свой код в блоки #Вставка.
Если вы уверены, что режим совместимости в порядке, но код всё равно не подхватывается, проведем диагностику ситуации. Выясним причину расхождения с помощью встроенных инструментов:
Воспользуйтесь инструментом «Проверка возможности применения». В окне списка расширений (Конфигурация — Расширения конфигурации) нажмите кнопку «Проверить». Система выведет список методов, которые не могут быть применены из-за ошибок контроля. Это первый сигнал о том, что текст в расширении «протух» относительно оригинала.
Еще один эффективный метод — сравнение текстов. Рассмотрим по шагам:
Часто выясняется, что проблема в символах переноса строки (CRLF против LF) или в случайном пробеле в самом конце строки после КонецПроцедуры.
Посмотрим на особенности использования директивы в функциях. До версии 8.3.15 программисты были вынуждены использовать &Вместо, копируя весь код функции, чтобы просто изменить одну строку. С &ИзменениеИКонтроль мы можем точечно менять логику расчёта. Посмотрим на пример:
&ИзменениеИКонтроль("РассчитатьСкидку")
Функция РассчитатьСкидку(Цена, Процент)
#Удаление
Результат = Цена * (Процент / 100);
#КонецУдаления
#Вставка
Результат = Окр(Цена * (Процент / 100), 2, РежимОкругления.Окр15как20);
#КонецВставки
Возврат Результат;
КонецФункции
Здесь мы не просто добавили код, а заменили существующий с помощью пары тегов #Удаление и #Вставка. Обратите внимание, что внутри #Удаление должен находиться точный текст оригинальной строки. Любая опечатка там также приведет к отказу расширения.
Подводя итог, можно сказать, что &ИзменениеИКонтроль — это «хирургический» инструмент. Чтобы операция прошла успешно, соблюдайте следующие правила:
#Вставка и #Удаление должен быть идентичен оригиналу.Соблюдение этих простых, но строгих правил позволит вам избежать «маразматических» ситуаций и сделает разработку на расширениях предсказуемой и стабильной.