Округление и усечение чисел в языке запросов 1С 8.3
Содержание
В языке запросов 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” |
Разница принципиальная: ОКРУГЛ, ЦЕЛОЕ и ВЫРАЗИТЬ возвращают число, с которым дальше можно считать. Формат возвращает строку для показа человеку — складывать и умножать её уже нельзя.
Режимы округления и точность чисел
Во встроенном языке у функции Окр есть третий параметр — режим, который решает судьбу ровной половины:
РежимОкругления.Окр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)) к колонкам во всех частях объединения, чтобы типы совпали и значения округлились одинаково.