Округление и усечение чисел в языке запросов 1С 8.3

· 9 мин

Содержание

В языке запросов 1С число округляют двумя функциями: ОКРУГЛ(Число, Разрядность) — до нужного количества знаков после запятой, и ЦЕЛОЕ(Число) — отбрасывает дробную часть целиком. Привычной функции ФОРМАТ, как во встроенном языке, в запросе нет — внешний вид числа (разделители, знак валюты) задают уже на выводе результата.

Ниже — синтаксис обеих функций, чем заменить ФОРМАТ прямо в запросе, как ведёт себя округление на границе .5, и готовые примеры: округление НДС, усечение до рублей и округление крупных сумм до тысяч.

Функция ОКРУГЛ: до копеек, рублей и любого разряда

Синтаксис одинаков в консоли запросов, в СКД и в запросе внутри кода:

ОКРУГЛ(<Число>, <Разрядность>)
  • <Число> — поле или выражение числового типа;
  • <Разрядность> — сколько знаков оставить после запятой. 2 — до копеек, 0 — до целых рублей.

Округление идёт по правилу «половину — от нуля»: ровно .5 округляется в большую по модулю сторону. То есть 2.5 даёт 3, а -2.5 даёт -3. Это обычное арифметическое округление, никакого отдельного параметра режима в запросе нет.

ВыражениеРезультат
ОКРУГЛ(123.456, 2)123.46
ОКРУГЛ(123.456, 1)123.5
ОКРУГЛ(123.456, 0)123
ОКРУГЛ(2.5, 0)3
ОКРУГЛ(2.345, 2)2.35

Типичный блок — привести сумму строки к копейкам прямо в выборке:

ВЫБРАТЬ
    Товары.Номенклатура КАК Номенклатура,
    ОКРУГЛ(Товары.Количество * Товары.Цена, 2) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары

Округляйте там, где считаете итог, а не отдельно в каждой вложенной формуле. Чем меньше промежуточных округлений, тем меньше расхождений в копейках на больших таблицах.

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

ОКРУГЛ(Остатки.Сумма / 1000, 0) * 1000

Для суммы 1 234 567 это даёт 1 235 000: 1234567 / 1000 = 1234.567, округление до целого — 1235, обратно в тысячи — 1 235 000.

Функция ЦЕЛОЕ: отбросить дробную часть

ЦЕЛОЕ(<Число>) возвращает целую часть и просто отсекает всё после запятой — без округления вверх:

ВыражениеРезультат
ЦЕЛОЕ(123.456)123
ЦЕЛОЕ(123.99)123
ЦЕЛОЕ(-123.99)-123

Главное отличие от ОКРУГЛ(Число, 0): ОКРУГЛ смотрит на дробную часть и может увеличить целое, а ЦЕЛОЕ всегда отбрасывает её.

  • ОКРУГЛ(123.99, 0) → 124
  • ЦЕЛОЕ(123.99) → 123

Для отрицательных чисел ЦЕЛОЕ усекает к нулю, а не вниз. ЦЕЛОЕ(-123.99) — это -123, а не -124. Если по логике отчёта вам нужно именно «пол» (floor) или «потолок» (ceiling), в запросе их отдельных функций нет — собирайте через ЦЕЛОЕ и проверку знака либо округляйте на выводе в коде.

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

Чем заменить ФОРМАТ прямо в запросе

Частый вопрос — «как применить ФОРМАТ в запросе». Короткий ответ: напрямую никак. ФОРМАТ — функция встроенного языка и языка выражений отчётов, в тексте запроса её нет. Запрос возвращает число, а его внешний вид (разделители разрядов, число знаков, валюта, скобки для минуса) задаётся позже.

Где именно задаётся формат вывода:

  • 📊 В отчёте на СКД — в настройке поля, свойство «Формат». Там же пишется строка вроде ЧДЦ=2; ЧРД=' ' — два знака после запятой и пробел как разделитель разрядов.
  • 🖥 В коде — функцией Формат(Выборка.Сумма, "ЧДЦ=2") уже после получения результата запроса.
  • 🧮 В макете печатной формы — формат ячейки, если выводите значение в табличный документ.

Если же вам нужно не «нарисовать» число, а реально изменить его точность внутри запроса, применяйте приведение типа:

ВЫРАЗИТЬ(Товары.Сумма КАК ЧИСЛО(15, 2))

ЧИСЛО(15, 2) — всего 15 знаков, из них 2 после запятой. Приведение к меньшему числу дробных знаков округляет значение по тому же правилу «половину — от нуля», что и ОКРУГЛ. Это удобно, когда важно и ограничить длину поля, и округлить его одним выражением — например, при объединении запросов через ОБЪЕДИНИТЬ, где типы колонок должны совпадать.

ВЫРАЗИТЬ меняет и точность хранения, и значение. Если указать разрядность меньше, чем есть в данных, «лишние» копейки будут отброшены округлением — проверяйте, что это именно то, что вам нужно.

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

Сравнение способов обработки чисел

Когда непонятно, что выбрать, держите в голове короткую таблицу. Первые два столбца работают в запросе, последние два — уже на результате.

СпособЧто делаетГде доступен123.456 →
ОКРУГЛ(x, 2)округляет до 2 знаковзапрос, СКД, код123.46
ЦЕЛОЕ(x)отсекает дробную частьзапрос, СКД, код123
ВЫРАЗИТЬ(x КАК ЧИСЛО(15,2))приводит тип и округляетзапрос, СКД123.46
Формат(x, "ЧДЦ=2")форматирует вид (строка)только код/отчёт“123,46”

Разница принципиальная: ОКРУГЛ, ЦЕЛОЕ и ВЫРАЗИТЬ возвращают число, с которым дальше можно считать. Формат возвращает строку для показа человеку — складывать и умножать её уже нельзя.

Проверьте себя
Что вернёт `ЦЕЛОЕ(-7.8)` в запросе 1С?
Какое выражение округлит сумму до целых тысяч?
Чем заменить `ФОРМАТ` для показа числа с разделителями?

Режимы округления и точность чисел

Во встроенном языке у функции Окр есть третий параметр — режим, который решает судьбу ровной половины:

  • РежимОкругления.Окр15как20 — 1.15 округляется до 1.2 (половина уходит от нуля). Это поведение по умолчанию и то же, что даёт ОКРУГЛ в запросе.
  • РежимОкругления.Окр15как10 — 1.15 округляется до 1.1 (половина отбрасывается вниз).
Результат = Окр(1.15, 1, РежимОкругления.Окр15как10); // 1.1

В языке запросов выбора режима нет — доступен только вариант «половину от нуля». Если нужен другой режим, получите значение запросом и доокруглите в коде либо соберите формулу вручную.

Про так называемое банковское округление (половину — к ближайшему чётному: 2.5 → 2, 3.5 → 4, 4.5 → 4) важно знать главное: встроенного режима банковского округления в 1С нет. Ни ОКРУГЛ в запросе, ни Окр в коде его не дают. Если методика расчёта требует именно его, реализуйте логику отдельно в коде, а не ищите готовый параметр.

Хорошая новость про точность: число в 1С — десятичный тип с фиксированной разрядностью, а не двоичное с плавающей точкой. Привычных «сюрпризов» вроде 0.1 + 0.2 = 0.30000000000000004 здесь не будет, результат округления предсказуем. Но следите за разрядностью реквизитов: если у реквизита «Сумма» в конфигурации задано 2 знака, то и хранится он с двумя знаками — округлять сверх этого нечего.

Практические примеры: НДС, средние и копейки

Выделить НДС 20% из суммы с налогом. Сумма с НДС — 1180. Налог — Сумма / 120 * 20, округляем до копеек:

ОКРУГЛ(Продажи.СуммаСНДС / 120 * 20, 2)

Для 1180: 1180 / 120 = 9.8333…, умножаем на 20 — 196.6666…, округление до 2 знаков — 196.67.

Начислить НДС 20% на сумму без налога. Сумма без НДС — 1000:

ОКРУГЛ(Продажи.СуммаБезНДС * 20 / 100, 2)

Результат — 200.00.

Округляйте НДС по строкам и по документу одинаково — как требует ваша учётная методика. Если округлить налог в каждой строке, а потом сложить, итог может на копейку отличаться от налога, посчитанного от общей суммы. Выберите один порядок и применяйте его везде.

Средняя сумма по контрагенту. Агрегатную функцию оборачиваем в ОКРУГЛ:

ВЫБРАТЬ
    Продажи.Контрагент КАК Контрагент,
    ОКРУГЛ(СРЕДНЕЕ(Продажи.Сумма), 2) КАК СредняяСумма
ИЗ
    РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
    Продажи.Контрагент

Число полных упаковок. Сколько целых коробок по 12 штук выходит из остатка — тут нужно именно усечение, а не округление:

ЦЕЛОЕ(Остатки.КоличествоОстаток / 12)

Для остатка 100: 100 / 12 = 8.33…, ЦЕЛОЕ даёт 8 полных коробок.

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

ОКРУГЛ(Продажи.СуммаВыручки, 0)

1250.49 превратится в 1250, а 1250.50 — в 1251.

Доля в процентах с двумя знаками. Доля строки в обороте контрагента — делим и округляем результат умножения на 100:

ОКРУГЛ(Продажи.Сумма / Продажи.СуммаИтого * 100, 2)

Для суммы 745 при итоге 3200: 745 / 3200 = 0.2328…, умножаем на 100 — 23.28…, округление до 2 знаков даёт 23.28 процента. Проценты по строкам после округления не обязаны дать ровно 100 — расхождение в сотые доли нормально и его не «подгоняют» вручную.

Округление в полях СКД и ресурсах отчёта

Те же функции ОКРУГЛ, ЦЕЛОЕ и ВЫРАЗИТЬ доступны не только в тексте запроса, но и в выражениях системы компоновки данных — в вычисляемых полях и в ресурсах. Это удобно, когда исходный запрос трогать не хочется, а округлить вывод нужно.

Важный момент — где стоит округление в отчёте, влияет на итог:

  • 🔹 Округлили в детальных записях, а в ресурсе стоит обычная сумма — итог получится как сумма уже округлённых строк.
  • 🔹 Округлили само выражение ресурса, например ОКРУГЛ(Сумма(СуммаВыручки), 2) — сначала суммируется точное значение, потом округляется один раз.

Эти два пути дают разный итог на копейку-другую. Для отчётов по НДС и выручке заранее решите, какой вариант соответствует вашей методике, и применяйте его по всему отчёту единообразно.

Формат поля (ЧДЦ, разделитель разрядов) в СКД настраивается отдельно от округления и на само значение не влияет — он лишь задаёт, как число выглядит на экране и в печати.

Типичные ошибки при округлении в запросе

  • ❌ Ждут ФОРМАТ в тексте запроса. В запросе его нет — форматируйте результат в коде или в настройке поля отчёта.
  • ❌ Путают ЦЕЛОЕ и ОКРУГЛ(x, 0). ЦЕЛОЕ(0.99) = 0, а ОКРУГЛ(0.99, 0) = 1. Для «отбросить копейки» нужно ЦЕЛОЕ, для «округлить до рубля» — ОКРУГЛ.
  • ❌ Складывают строковый результат Формат. После Формат() получается текст, арифметика по нему не идёт и в агрегатах он не суммируется.
  • ❌ Округляют каждый множитель отдельно. Накопленная ошибка округления растёт на больших выборках. Округляйте финальный результат выражения.
  • ❌ Забывают про знак у ЦЕЛОЕ. Для отрицательных значений усечение идёт к нулю: ЦЕЛОЕ(-5.9) = -5. Если ждали -6, результат будет неверным.

Частые вопросы

Можно ли округлить до десятков или сотен прямо в запросе?
Надёжнее через деление и умножение: ОКРУГЛ(Сумма / 100, 0) * 100 округлит до сотен. Так результат предсказуем в любой версии платформы.
В чём разница между ОКРУГЛ(x, 0) и ЦЕЛОЕ(x)?
ОКРУГЛ(x, 0) округляет по правилам (0.99 → 1), а ЦЕЛОЕ(x) просто отбрасывает дробную часть (0.99 → 0). Для усечения нужен ЦЕЛОЕ.
Почему в отчёте сумма показывается с точкой, а не с запятой?
Это вопрос формата вывода, а не округления. Задайте формат поля в СКД (ЧДЦ=2, разделитель разрядов) или примените Формат() в коде — число от этого не меняется.
Поддерживает ли запрос банковское округление?
Нет. И в запросе, и во встроенном языке округление идёт «половину от нуля». Банковское округление при необходимости реализуют отдельно в коде.
Как ограничить число знаков у поля при ОБЪЕДИНИТЬ?
Примените ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 2)) к колонкам во всех частях объединения, чтобы типы совпали и значения округлились одинаково.