В практике разработки на платформе 1С:Предприятие 8, особенно при работе с управляемыми формами и расширениями, программисты часто сталкиваются с ситуацией, когда визуально настроенное событие ПриИзменении для поля ввода отказывается выполняться. Вроде бы процедура написана, аннотации &НаКлиенте расставлены, а точка останова в отладчике упорно игнорируется. Разберем подробно, почему так происходит, и проанализируем основные технические причины этой проблемы.
Первое, что мы должны сделать — это убедиться, что процедура в программном модуле физически связана с элементом формы. В управляемом интерфейсе наличие кода в модуле формы еще не означает, что платформа вызовет его. Рассмотрим порядок действий для проверки:
Часто при копировании элементов или ручном написании кода эта связь «отваливается». Если поле пустое, необходимо нажать на кнопку с лупой, чтобы платформа автоматически создала заготовку или предложила выбрать существующую процедуру из модуля. Как показала практика обсуждения на форумах, банальная ошибка в выборе реквизита (когда на форме несколько похожих полей) является одной из самых частых причин «нерабочего» кода.
Если мы работаем в контексте расширения, ситуация усложняется. Проанализируем специфику взаимодействия основной конфигурации и расширения. Когда мы заимствуем форму в расширение, связи событий могут вести себя непредсказуемо.
Во-первых, важно проверить, какой тип вызова используется. Если в основной конфигурации уже есть обработчик ПриИзменении, а мы добавляем свой в расширении через аннотацию &Вместо, то код основной конфигурации не выполнится, если мы явно не вызовем ПродолжитьВызов().
Во-вторых, при добавлении нового элемента формы непосредственно в расширении, убедимся, что процедура-обработчик также находится в модуле формы расширения, а не была случайно написана в модуле объекта или менеджера.
Важно помнить фундаментальное правило платформы 1С: событие ПриИзменении генерируется только при интерактивном действии пользователя. Разберем этот момент подробнее. Если пользователь выбрал значение из списка, ввел текст руками или нажал кнопку выбора — событие сработает.
Однако, если мы в коде пишем конструкцию вида:
Объект.ВидСтрахов = Справочники.ВидыСтрахования.НайтиПоНаименованию("ОСАГО");
В этом случае платформа «промолчит», и обработчик ПриИзменении вызван не будет. Если нам нужно, чтобы логика отработала и при программном изменении, мы должны вызвать процедуру вручную сразу после присваивания значения:
Объект.ВидСтрахов = НовоеЗначение;
ЭлементФормы = Элементы.ВидСтрахов;
ВидСтраховПриИзменении(ЭлементФормы);
Рассмотрим пример кода, который часто вызывает вопросы у начинающих разработчиков. Посмотрим на типичную структуру вызова:
&НаСервере
Процедура ВидСтраховПриИзмененииНаСервере()
// Пытаемся изменить заголовок элемента
Элементы.Серия3.Заголовок = Объект.ПотерпПолис.серия;
КонецПроцедуры
&НаКлиенте
Процедура ВидСтраховПриИзменении(Элемент)
ВидСтраховПриИзмененииНаСервере();
КонецПроцедуры
В данной ситуации может возникнуть скрытая ошибка. Проанализируем строку Объект.ПотерпПолис.серия. Если реквизит ПотерпПолис является ссылочным типом (например, справочником) и он не заполнен (пустая ссылка), то при обращении через точку к свойству серия на сервере может возникнуть исключение. В управляемых формах такие ошибки внутри обработчиков событий иногда «проглатываются» платформой или приводят к тихому прекращению работы метода. Для пользователя это выглядит так, будто метод просто не сработал.
Выясним причину через отладчик. Убедитесь, что в параметрах отладки включена "Отладка на сервере". Установите точку останова в клиентской процедуре и по шагам (клавиша F11) зайдите в серверный контекст. Проверьте, не возвращает ли обращение к реквизитам Неопределено или пустую ссылку.
Необходимо понимать, когда именно платформа инициирует событие ПриИзменении. Это происходит не в момент ввода каждого символа, а в момент потери фокуса элементом или нажатия клавиши Enter.
Рассмотрим сценарии:
ПриИзменении может сработать позже, чем код самой команды.ОбработкаВыбора. Если для поля определено событие ОбработкаВыбора и в нем установлен параметр СтандартнаяОбработка = Ложь, то значение в поле может не обновиться должным образом, что заблокирует последующий вызов ПриИзменении.Проанализируем ситуацию, когда на форме есть несколько элементов, отображающих один и тот же путь к данным (например, реквизит Объект.Контрагент выведен в шапке и на отдельной вкладке). Если мы привязали событие ПриИзменении к элементу в шапке, но пользователь изменил значение через поле на вкладке — код не сработает.
Рекомендация: Всегда проверяйте, для какого именно элемента формы (визуального объекта) вы назначаете обработчик. В 1С события привязываются к элементам управления, а не к самим данным (реквизитам), хотя они и именуются часто одинаково.
Подводя итог, если метод ПриИзменении не срабатывает, пройдите по следующему чек-листу:
&НаКлиенте, &Перед и т.д.) расставлены корректно.Помните, что аккуратность при именовании реквизитов и элементов формы — залог того, что вам не придется часами искать, почему «не срабатывает» очевидный код.