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

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

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

Базовый синтаксис умножения в запросах 1С

Самый простой способ умножить значения в запросе — использовать арифметическое выражение прямо в списке полей. Синтаксис интуитивно понятен:

ВЫБРАТЬ

Товары.Наименование КАК Товар,

Товары.Цена * Товары.Количество КАК Сумма

ИЗ

Справочник.Товары КАК Товары

Здесь поле Сумма будет содержать результат умножения цены на количество для каждого товара. Важно помнить два ключевых правила:

  • 🔢 Типы данных: оба операнда должны быть числовыми (или приводимы к числу). Умножение строки на число вызовет ошибку.
  • 📊 NULL-значения: если хотя бы одно из полей содержит NULL, результат тоже будет NULL. Это часто становится причиной неожиданных пустых результатов.

Для явного приведения типов используйте функцию ВЫРАЗИТЬ():

ВЫБРАТЬ

ВЫРАЗИТЬ(Документ.СуммаДокумента КАК ЧИСЛО(15, 2)) * 1.2 КАК СуммаСНДС

💡

Если в результате умножения получаете NULL, проверьте исходные данные на наличие пустых значений с помощью конструкции ЕСТЬNULL(Поле, 0).

Умножение с группировкой данных

Часто требуется умножить значения после группировки, например, посчитать общую сумму по группе товаров. В этом случае умножение выполняется в разделе ИТОГИ или с использованием агрегатных функций:

ВЫБРАТЬ

Товары.Категория КАК Категория,

СУММА(Товары.Цена * Товары.Количество) КАК ОбщаяСумма

ИЗ

Справочник.Товары КАК Товары

СГРУППИРОВАТЬ ПО

Товары.Категория

Обратите внимание на порядок операций: сначала выполняется умножение для каждой записи, а затем — суммирование по группам. Если требуется умножить уже сгруппированные данные, используйте вложенные запросы:

ВЫБРАТЬ

Группы.Категория,

Группы.ОбщаяСумма * 1.1 КАК СуммаСНаценкой

ИЗ

(

ВЫБРАТЬ

Товары.Категория КАК Категория,

СУММА(Товары.Цена * Товары.Количество) КАК ОбщаяСумма

ИЗ

Справочник.Товары КАК Товары

СГРУППИРОВАТЬ ПО

Товары.Категория

) КАК Группы

📊 Как часто вы используете умножение в запросах 1С?
Ежедневно
Несколько раз в неделю
Редко
Никогда

Умножение с условными операторами

В реальных задачах часто требуется умножать значения с учётом условий. Например, применить скидку только к определённой категории товаров. Для этого используйте конструкцию ВЫБОР КОГДА:

ВЫБРАТЬ

Товары.Наименование,

ВЫБОР

КОГДА Товары.Категория = &АкционныеТовары

ТОГДА Товары.Цена Товары.Количество 0.9

ИНАЧЕ Товары.Цена * Товары.Количество

КОНЕЦ КАК СуммаСоСкидкой

Альтернативный вариант — использовать логические выражения прямо в арифметическом выражении:

ВЫБРАТЬ

Товары.Наименование,

Товары.Цена Товары.Количество (1 - (Товары.Скидка / 100)) КАК Сумма

⚠️ Внимание: При умножении на выражение в скобках (например, (1 - Скидка/100)) убедитесь, что поле Скидка не содержит NULL. Иначе всё выражение вернёт NULL, а не 1, как можно было бы ожидать.

Работа с виртуальными таблицами и временными таблицами

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

ВЫБРАТЬ

ОстаткиТоваров.Номенклатура КАК Товар,

ОстаткиТоваров.КоличествоОстатков * ОстаткиТоваров.Цена КАК СуммаОстатков

ИЗ

РегистрНакопления.ОстаткиТоваров.Остатки(&ДатаОтчета,) КАК ОстаткиТоваров

Для сложных вычислений удобно использовать временные таблицы:

// Создаём временную таблицу с промежуточными данными

ВЫБРАТЬ

Товары.Ссылка КАК Ссылка,

Товары.Цена * 1.2 КАК ЦенаСНДС

ПОМЕСТИТЬ ВТ_Цены

ИЗ

Справочник.Товары КАК Товары;

// Используем данные из временной таблицы

ВЫБРАТЬ

Остатки.Номенклатура КАК Товар,

Остатки.КоличествоОстатков * ВТ_Цены.ЦенаСНДС КАК Сумма

ИЗ

РегистрНакопления.ОстаткиТоваров.Остатки(&ДатаОтчета,) КАК Остатки

ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Цены КАК ВТ_Цены

ПО Остатки.Номенклатура = ВТ_Цены.Ссылка

Убедиться, что оба операнда числовые|Проверить наличие NULL с помощью ЕСТЬNULL()|Учесть порядок операций при группировке|Протестировать запрос на небольшом наборе данных-->

Типичные ошибки и как их избежать

Даже опытные разработчики допускают ошибки при умножении в запросах. Рассмотрим наиболее распространённые:

Ошибка Причина Решение
Результат умножения — NULL Одно из полей содержит NULL Использовать ЕСТЬNULL(Поле, 0)
Ошибка типов Попытка умножить строку на число Привести типы с помощью ВЫРАЗИТЬ()
Некорректная сумма при группировке Умножение выполняется после агрегации Использовать вложенные запросы или выносить умножение в подзапрос
Переполнение числового типа Результат превышает максимальное значение типа Явно указать тип с достаточной точностью: ЧИСЛО(15, 2)

Особое внимание стоит уделить работе с NULL. Например, следующий запрос вернёт NULL для всех строк, где Скидка не заполнена:

ВЫБРАТЬ

Цена * (1 - Скидка/100) КАК ЦенаСоСкидкой

Правильный вариант:

ВЫБРАТЬ

Цена * (1 - ЕСТЬNULL(Скидка, 0)/100) КАК ЦенаСоСкидкой

Почему результат умножения может быть неточным?

В 1С:Предприятие числовые значения хранятся с ограниченной точностью. При умножении больших чисел или операциях с плавающей запятой возможны ошибки округления. Например, 1.1 * 3 может дать результат 3.3000000000000003 вместо ожидаемых 3.3. Для финансовых расчётов используйте тип ЧИСЛО(15, 2) и функцию ОКРУГЛ().)

Оптимизация запросов с умножением

Умножение в запросах может замедлять выполнение, особенно при работе с большими объёмами данных. Следующие рекомендации помогут оптимизировать производительность:

  • Выносите умножение в подзапросы, если оно не требуется на ранних этапах выполнения.
  • 📈 Используйте индексированные поля в выражениях для умножения (например, предварительно рассчитанные поля в регистрах).
  • 🔄 Избегайте умножения в циклах — лучше выполнить одно вычисление в запросе, чем пересчитывать значения для каждой строки в коде.

Пример оптимизированного запроса:

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

ВЫБРАТЬ

Товары.Наименование,

Товары.Цена Товары.Количество (1 + ЕСТЬNULL(Товары.НДС, 0)/100) КАК СуммаСНДС

ИЗ

Документ.РеализацияТоваров.Товары КАК Товары;

// Лучше: предварительно рассчитать коэффициент НДС

ВЫБРАТЬ

Товары.Наименование,

(Товары.Цена Товары.Количество) Коэффициенты.Коэффициент КАК СуммаСНДС

ИЗ

Документ.РеализацияТоваров.Товары КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ

(

ВЫБРАТЬ

1 КАК Коэффициент

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

1 + ЕСТЬNULL(Товары.НДС, 0)/100 КАК Коэффициент

ИЗ

Документ.РеализацияТоваров.Товары КАК Товары

) КАК Коэффициенты

⚠️ Внимание: При оптимизации запросов с умножением учитывайте, что некоторые преобразования (например, приведение типов) могут повлиять на план выполнения запроса. Всегда проверяйте производительность на реальных данных с помощью ПланЗапроса().

Практические примеры умножения в запросах

Рассмотрим несколько реальных сценариев, где требуется умножение в запросах:

1. Пересчёт цен в другую валюту

ВЫБРАТЬ

Товары.Наименование,

Товары.Цена * Курсы.Курс КАК ЦенаВДолларах

ИЗ

Справочник.Товары КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних(&Дата,) КАК Курсы

ПО Товары.ВалютаЦены = Курсы.Валюта

2. Расчёт процентов от суммы

ВЫБРАТЬ

Документы.Номер,

Документы.СуммаДокумента * (Документы.ПроцентАванса / 100) КАК СуммаАванса

ИЗ

Документ.ЗаказыПокупателей КАК Документы

3. Умножение с учётом нескольких условий

ВЫБРАТЬ

Товары.Наименование,

ВЫБОР

КОГДА Товары.Категория = &Категория1 И Товары.Сезонный = ИСТИНА

ТОГДА Товары.Цена 1.3 Товары.Количество

КОГДА Товары.Категория = &Категория2

ТОГДА Товары.Цена 0.8 Товары.Количество

ИНАЧЕ Товары.Цена * Товары.Количество

КОНЕЦ КАК Сумма

FAQ: Частые вопросы по умножению в запросах 1С

Как умножить поле на константу в запросе?

Используйте прямое умножение: ВЫБРАТЬ Поле * 1.2 КАК Результат. Для параметров запроса используйте конструкцию &Параметр:

ВЫБРАТЬ

Цена * &Коэффициент КАК НоваяЦена

Где &Коэффициент — параметр, передаваемый в запрос.

Почему при умножении двух чисел получаю ошибку "Типы не совместимы"?

Ошибка возникает, если одно из полей имеет нечисловой тип (например, строка или булево значение). Используйте ВЫРАЗИТЬ() для явного приведения:

ВЫБРАТЬ

ВЫРАЗИТЬ(Поле1 КАК ЧИСЛО(10, 2)) * ВЫРАЗИТЬ(Поле2 КАК ЧИСЛО(10, 2))

Можно ли умножать данные из разных таблиц в одном запросе?

Да, но для этого нужно использовать СОЕДИНЕНИЕ. Пример:

ВЫБРАТЬ

Заказы.Номер,

Заказы.Количество * Товары.Вес КАК ОбщийВес

ИЗ

Документ.ЗаказыПокупателей КАК Заказы

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары

ПО Заказы.Товар = Товары.Ссылка

Как округлить результат умножения?

Используйте функцию ОКРУГЛ():

ВЫБРАТЬ

ОКРУГЛ(Цена Количество 1.2, 2) КАК СуммаСНДС

Где 2 — количество знаков после запятой.

Что делать, если при умножении получаю переполнение?

Явно укажите тип данных с достаточной точностью:

ВЫБРАТЬ

ВЫРАЗИТЬ(БольшоеЧисло1 * БольшоеЧисло2 КАК ЧИСЛО(20, 0)) КАК Результат

Или разбейте вычисление на части:

ВЫБРАТЬ

(БольшоеЧисло1 / 1000) (БольшоеЧисло2 / 1000) 1000000 КАК Результат