В процессе разработки в среде 1С:Предприятие часто возникает задача автоматического пересчета одного поля при изменении других. Типичный пример — расчет итоговой суммы на основе введенного курса и количества валюты. Рассмотрим подробно, как правильно реализовать этот механизм, разберем типичные ошибки новичков и выясним, почему важно различать типы форм и данных.
Проанализируем ситуацию: пользователь пытается использовать код Тб=ЭлементыФормы.ТБКасса.ТекущиеДанные; для обычных полей ввода, которые не являются частью табличной части. Это распространенное заблуждение. Свойство ТекущиеДанные предназначено исключительно для работы с коллекциями (табличными частями, динамическими списками), чтобы получить доступ к строке, на которой в данный момент стоит курсор.
Если ваши поля — это просто реквизиты объекта (например, документа или обработки), расположенные на форме, обращаться к ним нужно напрямую через данные, а не через элементы управления. В 1С все манипуляции с логикой должны происходить на уровне реквизитов (данных), а ЭлементыФормы (в обычных формах) или Элементы (в управляемых формах) нужны в основном для изменения визуальных свойств: доступности, видимости или цвета.
Если вы работаете в старой конфигурации (например, УПП 1.3 или самописная база на обычных формах), расчет выполняется максимально просто. Нам необходимо привязать код к событию ПриИзменении для каждого из влияющих полей: и для курса, и для основной суммы в манатах.
Рассмотрим пошагово, как это сделать:
Курс.ПриИзменении и нажмите на лупу, чтобы создать обработчик в модуле.Манат.В модуле формы код будет выглядеть следующим образом:
Процедура КурсПриИзменении(Элемент)
РассчитатьСумму();
КонецПроцедуры
Процедура МанатПриИзменении(Элемент)
РассчитатьСумму();
КонецПроцедуры
Процедура РассчитатьСумму()
// В обычных формах мы можем обращаться к реквизитам напрямую по имени
Сумма = Курс * Манат;
КонецПроцедуры
В современных конфигурациях (БП 3.0, УТ 11, ERP) подход несколько меняется. Здесь данные формы отделены от элементов управления и обычно упакованы в основной реквизит Объект. Рассмотрим, как прописать расчет в этом случае. Помните, что код должен выполняться в контексте &НаКлиенте, так как расчет должен происходить мгновенно при вводе данных пользователем.
&НаКлиенте
Процедура КурсПриИзменении(Элемент)
РассчитатьСуммуНаФорме();
КонецПроцедуры
&НаКлиенте
Процедура МанатПриИзменении(Элемент)
РассчитатьСуммуНаФорме();
КонецПроцедуры
&НаКлиенте
Процедура РассчитатьСуммуНаФорме()
// Обращаемся через структуру "Объект"
Объект.Сумма = Объект.Курс * Объект.Манат;
КонецПроцедуры
Простое умножение в программировании может привести к появлению невидимых "хвостов" в дробной части из-за специфики хранения чисел с плавающей точкой. В финансовом учете это недопустимо. Поэтому всегда используем функцию Окр().
Проанализируем улучшенный вариант кода с учетом точности до двух знаков после запятой:
Объект.Сумма = Окр(Объект.Курс * Объект.Манат, 2);
Также стоит учитывать возможность пустых значений. Если пользователь очистит поле курса, система может попытаться умножить число на Неопределено или 0. Хотя 1С достаточно гибко обрабатывает пустые числовые значения, в сложных формулах (например, при делении) проверка обязательна, чтобы избежать ошибки "Деление на 0".
Интересной особенностью платформы 1С:Предприятие является полная поддержка англоязычного синтаксиса. Это особенно актуально для разработчиков, которые привыкли к западным языкам программирования или работают в региональных локализациях (например, в Азербайджане), где синтакс-помощник может быть частично на английском.
Вы можете написать тот же расчет следующим образом, и платформа его поймет:
Object.Sum = Round(Object.Rate * Object.Manat, 2);
Это абсолютно эквивалентно русскому написанию. Вы даже можете смешивать языки в одном модуле, хотя это и считается плохим тоном в среде разработчиков.
Профессиональный подход к интерфейсам подразумевает, что если пользователь вручную изменит итоговую сумму, система должна предложить пересчитать либо курс, либо количество манат. Рассмотрим пример, когда при изменении суммы пересчитывается количество манат при фиксированном курсе:
&НаКлиенте
Процедура СуммаПриИзменении(Элемент)
Если Объект.Курс <> 0 Тогда
Объект.Манат = Окр(Объект.Сумма / Объект.Курс, 2);
КонецЕсли;
КонецПроцедуры
Подведем итоги: для корректного расчета суммы в форме 1С всегда работайте напрямую с данными (реквизитами), используйте событие ПриИзменении для всех зависимых полей и не забывайте про округление финансовых показателей. Это обеспечит стабильную работу вашего кода и отсутствие ошибок в учете.