Как реализовать автоматический расчет суммы по курсу в форме 1С?

Программист 1С v8.3 (Обычные формы)
← На главную

В процессе разработки в среде 1С:Предприятие часто возникает задача автоматического пересчета одного поля при изменении других. Типичный пример — расчет итоговой суммы на основе введенного курса и количества валюты. Рассмотрим подробно, как правильно реализовать этот механизм, разберем типичные ошибки новичков и выясним, почему важно различать типы форм и данных.

Разбор типичной ошибки: Реквизиты против Элементов формы

Проанализируем ситуацию: пользователь пытается использовать код Тб=ЭлементыФормы.ТБКасса.ТекущиеДанные; для обычных полей ввода, которые не являются частью табличной части. Это распространенное заблуждение. Свойство ТекущиеДанные предназначено исключительно для работы с коллекциями (табличными частями, динамическими списками), чтобы получить доступ к строке, на которой в данный момент стоит курсор.

Если ваши поля — это просто реквизиты объекта (например, документа или обработки), расположенные на форме, обращаться к ним нужно напрямую через данные, а не через элементы управления. В 1С все манипуляции с логикой должны происходить на уровне реквизитов (данных), а ЭлементыФормы (в обычных формах) или Элементы (в управляемых формах) нужны в основном для изменения визуальных свойств: доступности, видимости или цвета.

Реализация расчета в Обычных формах

Если вы работаете в старой конфигурации (например, УПП 1.3 или самописная база на обычных формах), расчет выполняется максимально просто. Нам необходимо привязать код к событию ПриИзменении для каждого из влияющих полей: и для курса, и для основной суммы в манатах.

Рассмотрим пошагово, как это сделать:

  1. Откройте форму в конфигураторе.
  2. Выберите элемент управления (поле ввода), например, Курс.
  3. В палитре свойств найдите событие ПриИзменении и нажмите на лупу, чтобы создать обработчик в модуле.
  4. Повторите то же самое для поля Манат.

В модуле формы код будет выглядеть следующим образом:


Процедура КурсПриИзменении(Элемент)
    РассчитатьСумму();
КонецПроцедуры

Процедура МанатПриИзменении(Элемент)
    РассчитатьСумму();
КонецПроцедуры

Процедура РассчитатьСумму()
    // В обычных формах мы можем обращаться к реквизитам напрямую по имени
    Сумма = Курс * Манат;
КонецПроцедуры

Особенности Управляемых форм (современные конфигурации)

В современных конфигурациях (БП 3.0, УТ 11, ERP) подход несколько меняется. Здесь данные формы отделены от элементов управления и обычно упакованы в основной реквизит Объект. Рассмотрим, как прописать расчет в этом случае. Помните, что код должен выполняться в контексте &НаКлиенте, так как расчет должен происходить мгновенно при вводе данных пользователем.


&НаКлиенте
Процедура КурсПриИзменении(Элемент)
    РассчитатьСуммуНаФорме();
КонецПроцедуры

&НаКлиенте
Процедура МанатПриИзменении(Элемент)
    РассчитатьСуммуНаФорме();
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСуммуНаФорме()
    // Обращаемся через структуру "Объект"
    Объект.Сумма = Объект.Курс * Объект.Манат;
КонецПроцедуры

Важность округления и проверки типов

Простое умножение в программировании может привести к появлению невидимых "хвостов" в дробной части из-за специфики хранения чисел с плавающей точкой. В финансовом учете это недопустимо. Поэтому всегда используем функцию Окр().

Проанализируем улучшенный вариант кода с учетом точности до двух знаков после запятой:

Объект.Сумма = Окр(Объект.Курс * Объект.Манат, 2);

Также стоит учитывать возможность пустых значений. Если пользователь очистит поле курса, система может попытаться умножить число на Неопределено или 0. Хотя 1С достаточно гибко обрабатывает пустые числовые значения, в сложных формулах (например, при делении) проверка обязательна, чтобы избежать ошибки "Деление на 0".

Использование англоязычного синтаксиса

Интересной особенностью платформы 1С:Предприятие является полная поддержка англоязычного синтаксиса. Это особенно актуально для разработчиков, которые привыкли к западным языкам программирования или работают в региональных локализациях (например, в Азербайджане), где синтакс-помощник может быть частично на английском.

Вы можете написать тот же расчет следующим образом, и платформа его поймет:

Object.Sum = Round(Object.Rate * Object.Manat, 2);

Это абсолютно эквивалентно русскому написанию. Вы даже можете смешивать языки в одном модуле, хотя это и считается плохим тоном в среде разработчиков.

Двусторонний расчет (обратная связь)

Профессиональный подход к интерфейсам подразумевает, что если пользователь вручную изменит итоговую сумму, система должна предложить пересчитать либо курс, либо количество манат. Рассмотрим пример, когда при изменении суммы пересчитывается количество манат при фиксированном курсе:


&НаКлиенте
Процедура СуммаПриИзменении(Элемент)
    Если Объект.Курс <> 0 Тогда
        Объект.Манат = Окр(Объект.Сумма / Объект.Курс, 2);
    КонецЕсли;
КонецПроцедуры

Подведем итоги: для корректного расчета суммы в форме 1С всегда работайте напрямую с данными (реквизитами), используйте событие ПриИзменении для всех зависимых полей и не забывайте про округление финансовых показателей. Это обеспечит стабильную работу вашего кода и отсутствие ошибок в учете.

← На главную