Разработка и Конфигурация · 10 мин
Как отбросить дробную часть в запросе 1С
Как отбросить дробную часть в запросе 1С: функция Цел(), приведение типов через ВЫРАЗИТЬ, отличия от округления, типичные ошибки и примеры кода.
В языке запросов 1С нет отдельной функции «усечь число», поэтому задача отбросить дробную часть решается двумя рабочими способами: встроенной функцией Цел() и приведением типа через ВЫРАЗИТЬ к целочисленному формату. Оба варианта дают целую часть числа, но ведут себя по-разному с типом результата, отрицательными значениями и полями смешанного состава.
Важно сразу разделить три операции, которые часто путают: отбрасывание дробной части (усечение), округление по математическим правилам и округление вверх или вниз. В запросах 1С для округления используется функция Окр(), а усечение выполняется именно через Цел() или приведение типа. Если в отчёте нужно «2,9 превратить в 2» — это усечение; если «2,9 превратить в 3» — это уже округление, и функцию нужно выбирать соответствующую.
Ниже разобраны синтаксис обоих способов, поведение на отрицательных числах и значениях NULL, готовые примеры запросов, а также ситуации, когда усечение лучше выполнить не в запросе, а в коде модуля после получения результата.
Функция Цел() — основной способ усечения
Функция Цел() доступна в языке запросов 1С начиная с версии платформы 8.3 и возвращает целую часть переданного числа. Синтаксис простой: Цел(Выражение), где выражением может быть поле таблицы, параметр, литерал или результат арифметической операции.
Типичный пример — расчёт количества целых упаковок товара без учёта неполных:
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура,
Товары.Количество КАК КоличествоШтук,
Цел(Товары.Количество / &ШтукВУпаковке) КАК ЦелыхУпаковок
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК Товары
Функция корректно работает с вложенными выражениями: Цел(Сумма / Курс), Цел(Количество * Коэффициент). Если аргумент уже целый, функция вернёт его без изменений. Это безопасный вариант по умолчанию, когда требуется именно отбросить дробную часть, а не округлить значение.
Ограничение: Цел() принимает только числовые выражения. Если поле имеет составной тип (например, «Число или Строка»), запрос может завершиться ошибкой на строках с нечисловым значением — такие поля предварительно приводят через ВЫРАЗИТЬ или фильтруют.
ВЫБРАТЬ
Цел(123.99) КАК Результат // вернёт 123
ИЗ
(ВЫБРАТЬ 1 КАК Поле) КАК ТУсечение через ВЫРАЗИТЬ к целочисленному типу
Второй способ — приведение значения к числу с нулевой точностью: ВЫРАЗИТЬ(Число КАК ЧИСЛО(15, 0)). Формально это не усечение, а округление: платформа приводит значение к указанной разрядности по правилам округления. На практике это означает, что ВЫРАЗИТЬ(2,7 КАК ЧИСЛО(10, 0)) даст 3, а не 2.
Поэтому ВЫРАЗИТЬ подходит, когда цель — получить целое число с округлением, а не строго отбросить дробную часть. Если требуется именно усечение, а под рукой только приведение типа, используют приём с вычитанием: ВЫРАЗИТЬ(Число - 0.5 КАК ЧИСЛО(15, 0)) для положительных значений. Такой приём хрупок и плохо читается, поэтому в новых разработках лучше применять Цел().
Пример с округлением через приведение типа:
ВЫБРАТЬ
Продажи.Номенклатура КАК Номенклатура,
ВЫРАЗИТЬ(Продажи.СуммаОборот / Продажи.КоличествоОборот КАК ЧИСЛО(15, 0)) КАК СредняяЦенаОкругленная
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
Сравнение способов
Строгое усечение дробной части. Подходит для расчёта целых упаковок, полных дней, целой части суммы. Не округляет вверх.
Округляет по правилам платформы при приведении к нулевой точности. Подходит, когда нужно целое число с округлением, а не усечением.
Явное округление до целых. Используется, когда бизнес-логика требует именно округления, а не отбрасывания дробной части.
Поведение на отрицательных числах и NULL
Для положительных чисел Цел() работает очевидно: 7,9 превращается в 7. С отрицательными значениями поведение соответствует усечению по модулю: Цел(-7.9) вернёт -7, а не -8. Это отличается от математической функции «пол» (floor), которая округляет в меньшую сторону. Если логика требует именно -8, придётся добавлять корректировку через ВЫБОР.
Значения NULL обрабатываются предсказуемо: Цел(NULL) возвращает NULL. Если поле может быть NULL (например, при левом соединении), и в результате нужен ноль вместо NULL, оберните выражение в ЕСТЬNULL: Цел(ЕСТЬNULL(Таблица.Количество, 0)).
Проверить поведение на граничных значениях удобно через консоль запросов в режиме предприятия, подав тестовый набор: положительное дробное, отрицательное дробное, целое, ноль и NULL. Это занимает минуту и снимает вопросы до того, как запрос попадёт в отчёт.
Как проверить результат
Результат 2
Результат 3 — используется округление, а не усечение
Результат -2
Результат -3 — ожидалась функция floor, а не Цел
NULL или 0 при обёртке в ЕСТЬNULL
Ошибка выполнения запроса — проверьте тип поля
Округлённое значение по правилам платформы
Ожидалось строгое усечение — замените на Цел()
Типичные сценарии применения
Целые упаковки и комплекты
Самая частая задача — посчитать, сколько полных упаковок можно собрать из остатка. Деление количества на размер упаковки даёт дробное число, а Цел() отбрасывает неполную часть: Цел(Остаток / ВУпаковке). Остаток сверх упаковок при необходимости считают отдельно: Остаток - Цел(Остаток / ВУпаковке) * ВУпаковке.
Целая часть суммы и копейки
Иногда нужно разделить сумму на рубли и копейки, например для печатных форм. Рубли: Цел(Сумма). Копейки: ВЫРАЗИТЬ((Сумма - Цел(Сумма)) * 100 КАК ЧИСЛО(3, 0)). Здесь усечение и приведение типа работают в связке: сначала отбрасывается дробная часть, затем остаток преобразуется в целое число копеек.
Целое количество дней между датами
Разность дат в запросах 1С вычисляется через РАЗНОСТЬДАТ, которая уже возвращает целое число. Но если длительность считается в часах и её нужно перевести в полные дни, применяют Цел(Часы / 24) — дробная часть суток отбрасывается.
Когда усечение лучше делать не в запросе
Не всякую обработку чисел стоит переносить в текст запроса. Если результат запроса всё равно обходится в цикле и значение дополнительно форматируется (например, выводится с разделителями разрядов или подставляется в строку), усечение проще и читабельнее выполнить в коде: Цел(Строка.Сумма) во встроенном языке работает так же, как и в запросе.
Ещё один случай — сложная логика с отрицательными числами, где нужен floor, а не усечение по модулю. В запросе это потребует громоздкой конструкции ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ, тогда как в коде условие записывается в одну строку и легче тестируется.
Правило простое: если усечённое значение участвует в группировке, соединении или итогах — делайте его в запросе. Если это финальное форматирование перед выводом — допустимо выполнить его в модуле.
Типичные ошибки и ограничения
Самая распространённая ошибка — ожидать от ВЫРАЗИТЬ(... КАК ЧИСЛО(N, 0)) усечения, тогда как приведение типа округляет. В результате 2,7 становится 3, и расчёт количества упаковок или целых дней «завышается» на единицу на половине значений. Проверяйте поведение на числе с дробной частью больше 0,5.
Вторая ошибка — применять Цел() к полю составного типа. Если в регистре поле допускает строки или NULL нестандартным образом, запрос падает с ошибкой приведения типа. Лечится предварительным ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 3)) или фильтрацией ГДЕ ТИПЗНАЧЕНИЯ(Поле) = ТИП(ЧИСЛО) там, где это применимо.
Третья группа проблем — потеря точности при промежуточных вычислениях. Если сначала разделить два целых числа, результат в языке запросов остаётся дробным, но при дальнейших операциях с приведением типов промежуточное округление может накапливаться. Выполняйте усечение на последнем шаге выражения, а не на промежуточных.
Как выбрать подход
FAQ
Чем Цел() отличается от Окр() в запросе 1С?
Цел() отбрасывает дробную часть без округления: 2,9 станет 2. Окр() округляет по математическим правилам: 2,9 станет 3, а 2,4 — 2. Выбор зависит от бизнес-логики: для подсчёта полных упаковок нужен Цел(), для округления цены — Окр().
Почему ВЫРАЗИТЬ(2.7 КАК ЧИСЛО(10, 0)) даёт 3, а не 2?
Приведение к числу с нулевой точностью выполняется с округлением, а не усечением. Это особенность приведения типов в платформе. Для строгого отбрасывания дробной части используйте Цел().
Как отбросить дробную часть у отрицательного числа в меньшую сторону?
Цел(-7.9) возвращает -7, то есть усекает по модулю. Если нужен результат -8 (функция floor), добавьте конструкцию ВЫБОР: когда число отрицательное и не равно своей целой части, вычитайте единицу из результата Цел().
Что вернёт Цел(NULL) и как получить вместо этого ноль?
Цел(NULL) возвращает NULL. Чтобы получить ноль, оберните поле в ЕСТЬNULL: Цел(ЕСТЬNULL(Поле, 0)). Порядок важен: ЕСТЬNULL должен быть внутри, иначе NULL уже попадёт в Цел().
Можно ли отбросить дробную часть уже в СКД, а не в запросе?
Да. В вычисляемых полях СКД доступны функции встроенного языка, включая Цел(). Это удобно, когда усечение нужно только для отображения, а в итогах и группировках должно участвовать исходное дробное значение.
Как получить только дробную часть числа в запросе?
Вычтите из числа его целую часть: Число - Цел(Число). Например, для 12,75 результат будет 0,75. Учтите, что для отрицательных чисел дробная часть тоже получится отрицательной из-за усечения по модулю.
Что важно запомнить
Для отбрасывания дробной части в запросе 1С используйте Цел() — это строгое усечение без округления. ВЫРАЗИТЬ к ЧИСЛО(N, 0) округляет, а не усекает. Проверяйте поведение на отрицательных числах и NULL, а усечение выполняйте на последнем шаге вычислений.