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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При составлении отчетов и обработке данных разработчикам регулярно приходится получать не просто хранящиеся в базе реквизиты, а вычисляемые показатели. Типичный пример — необходимость рассчитать объем работ на основе общей суммы выработки и расценки за единицу прямо в теле запроса.

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

Базовый синтаксис: вычисление выражения в секции ВЫБРАТЬ

Язык запросов 1С поддерживает стандартные математические операции: сложение (+), вычитание (-), умножение (*) и деление (/). Чтобы рассчитать новое поле, достаточно прописать выражение непосредственно в списке выборки полей и назначить ему псевдоним с помощью ключевого слова КАК.

Посмотрим на пример из исходного запроса, где требуется заменить выбор поля ВТТехОперации.Количество на результат отношения выработки к расценке:


ВЫБРАТЬ
    ВТТехОперации.Значение КАК Сотрудник,
    ВТПродукция.Ссылка КАК Документ,
    ВТПродукция.Номенклатура КАК ВидПродукции,
    ВТПродукция.ХарактеристикаНоменклатуры,
    ВТПродукция.Количество КАК ОбъемПродукции,
    ВТПродукция.ЕдиницаИзмерения,
    ВТРаспределение.ТехнологическаяОперация КАК ВидРабот,
    ВТРаспределение.Сумма / ВТТехОперации.Расценка КАК ОбъемРабот,
    ВТТехОперации.Расценка,
    ВТРаспределение.Сумма КАК Выработка

Если разработка ведется в визуальном конструкторе запросов, перейдем на вкладку Поля. Нажмем на кнопку добавления произвольного выражения (пиктограмма с зеленым карандашом) и введем текст формулы ВТРаспределение.Сумма / ВТТехОперации.Расценка, указав в колонке псевдонима имя ОбъемРабот.

Защита от ошибки деления на ноль

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

Чтобы запрос выполнялся стабильно при любых исходных данных, операцию деления всегда необходимо обрамлять в условную конструкцию ВЫБОР ... КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ.

Разберем безопасный вариант вычисления:


ВЫБОР
    КОГДА ВТТехОперации.Расценка = 0 ТОГДА 0
    ИНАЧЕ ВТРаспределение.Сумма / ВТТехОперации.Расценка
КОНЕЦ КАК ОбъемРабот

Обработка значений NULL при соединениях таблиц

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

Выясним причину опасности: проверка Поле = 0 для значения NULL вернет Ложь. В результате условие перейдет в ветку ИНАЧЕ, что приведет к непредвиденному поведению или попытке деления на нечисловое значение. Кроме того, любая арифметическая операция с участием NULL дает NULL.

Для корректной работы применим функцию ЕСТЬNULL, подставляющую числовое значение по умолчанию:


ВЫБОР
    КОГДА ЕСТЬNULL(ВТТехОперации.Расценка, 0) = 0 ТОГДА 0
    ИНАЧЕ ЕСТЬNULL(ВТРаспределение.Сумма, 0) / ВТТехОперации.Расценка
КОНЕЦ КАК ОбъемРабот

Управление точностью и округление результата

В языке запросов 1С нет прямого аналога функции Окр(). При выполнении деления результат может содержать непредсказуемое число знаков после запятой или вызывать переполнение разрядности чисел в СУБД. Для явного ограничения точности и корректного округления используем конструкцию ВЫРАЗИТЬ(... КАК ЧИСЛО(Длина, Точность)).

Посмотрим на итоговый, полностью защищенный вариант выражения:


ВЫРАЗИТЬ(
    ВЫБОР
        КОГДА ЕСТЬNULL(ВТТехОперации.Расценка, 0) = 0 ТОГДА 0
        ИНАЧЕ ЕСТЬNULL(ВТРаспределение.Сумма, 0) / ВТТехОперации.Расценка
    КОНЕЦ 
    КАК ЧИСЛО(15, 3)
) КАК ОбъемРабот

Конструкция ВЫРАЗИТЬ приведет результат к типу Число разрядностью 15 знаков с 3 знаками после запятой, выполнив округление по правилам математики на уровне базы данных.

Альтернативные подходы к вычислениям

Рассмотрим, когда расчет не следует переносить непосредственно в текст запроса:

  1. Отчеты на Системе компоновки данных (СКД): Если отчет строится с группировками и итогами, вычислять коэффициент или частное в запросе не рекомендуется. Простое суммирование частных по строкам в итогах дает неверные математические показатели. В СКД правильнее выводить исходные поля (сумму и расценку), а итоговый расчет настраивать на вкладке Поля ресурса с формулой расчета итогов вида Сумма(Выработка) / Выбор Когда Сумма(Расценка) = 0 Тогда 1 Иначе Сумма(Расценка) Конец.
  2. Сложная логика округления в коде 1С: Если бизнесу требуется не классическое математическое, а специфическое финансовое округление или округление всегда в большую сторону, операцию вычисления лучше перенести в постобработку выборки запроса во встроенном языке с помощью функции Окр().
← На главную