Разработка в системе 1С:Предприятие 8 (особенно на управляемых формах) требует понимания не только синтаксиса встроенного языка, но и механизмов связи программного кода с пользовательским интерфейсом. Довольно часто начинающие разработчики сталкиваются с ситуацией, когда код написан абсолютно верно, но программа на него никак не реагирует. Разберем эту ситуацию подробно на примере типовой задачи: автоматического расчета цены продажи при изменении цены покупки в справочнике Номенклатура.
Рассмотрим исходную ситуацию. У нас есть процедура, которая должна рассчитывать цену продажи как цену покупки, увеличенную на 20%. Код выглядит следующим образом:
&НаКлиенте
Процедура ЦенаПокупкиПриИзменении(Элемент)
Объект.ЦенаПродажи = Объект.ЦенаПокупки * 1.2;
КонецПроцедуры
Несмотря на кажущуюся простоту и корректность, код может не выполняться. Основная причина здесь кроется не в ошибках алгоритма, а в отсутствии связи (обработчика) между элементом формы и этой процедурой. В управляемом приложении 1С текст в модуле формы — это просто текст, пока платформа не получит четкое указание, при каком именно действии пользователя этот текст нужно превратить в исполняемую команду.
Проанализируем процесс создания обработчика события. Чтобы процедура ЦенаПокупкиПриИзменении начала работать, нам необходимо выполнить следующие действия в конфигураторе:
ЦенаПокупки.ПриИзменении.Важный момент: Если вы просто скопировали код из интернета или от коллеги и вставили его в модуль, связь не установится автоматически. Платформа «видит» обработчик только тогда, когда он прописан в метаданных самой формы через окно свойств.
В процессе обсуждения часто возникает вопрос: можно ли заменить Процедура на Функция? Выясним причину, по которой это может «случайно» сработать. С точки зрения архитектуры 1С, обработчик события интерфейса обязательно должен быть процедурой. Функция предназначена для возврата значения, что в контексте срабатывания интерфейсного события не имеет смысла.
Почему же у некоторых пользователей код «оживает» после смены типа на функцию? Скорее всего, при изменении типа заголовка разработчик заново выбирал обработчик в свойствах элемента формы, что и восстановило разорванную связь. Помните: всегда используйте конструкцию Процедура для обработки нажатий кнопок, изменений полей ввода и других действий пользователя.
Проанализируем контекст выполнения нашего кода. Обработчик события ПриИзменении должен выполняться на стороне клиента, так как это реакция на интерактивное действие пользователя. Именно поэтому перед объявлением процедуры обязательно должна стоять директива &НаКлиенте.
Если нам потребуется выполнить сложный расчет с обращением к базе данных (например, получить актуальный курс валют), мы должны будем вызвать серверную процедуру из нашей клиентской:
&НаКлиенте
Процедура ЦенаПокупкиПриИзменении(Элемент)
// Клиентская логика
РассчитатьЦенуНаСервере();
КонецПроцедуры
&НаСервере
Процедура РассчитатьЦенуНаСервере()
// Обращение к базе данных или сложный расчет
Объект.ЦенаПродажи = Объект.ЦенаПокупки * 1.2;
КонецПроцедуры
Рассмотрим несколько профессиональных советов, которые помогут избежать ошибок при расчете цен:
ЦенаПокупки, программа попытается умножить 0 на 1.2. Это не вызовет ошибку, но в поле ЦенаПродажи запишется ноль. Стоит подумать, нужно ли такое поведение.Окр() для приведения цены к денежному стандарту:
Объект.ЦенаПродажи = Окр(Объект.ЦенаПокупки * 1.2, 2);ОбработкаЗаполнения в модуле объекта или ПриСозданииНаСервере в модуле формы.Подведем итог нашему разбору. Если ваш код в 1С «не работает» и «даже не ругается», первым делом проверьте вкладку «События» в свойствах элемента формы. В 99% случаев проблема заключается в том, что платформа просто не знает о существовании вашей процедуры как обработчика конкретного поля. Работа в 1С — это всегда комбинация визуального конструирования и программного кодинга. Только их правильное соединение гарантирует стабильную работу системы.