Разработка и Конфигурация · 11 мин
Как отделить дробную часть от целой в 1С
Как отделить дробную часть от целой в 1С: функции Цел(), Окр(), Int(), готовые примеры кода, отличия для запросов и типичные ошибки разработчиков.
Задача отделить дробную часть числа от целой возникает в 1С постоянно: при расчёте копеек в сумме прописью, при разложении количества на упаковки и остаток, при проверке делимости, при округлении цен. Встроенный язык 1С не содержит отдельной функции «ДробнаяЧасть», поэтому результат получают комбинацией стандартных функций — Цел() и вычитания либо через Окр().
Ключевой момент, который нужно понять сразу: дробная часть вычисляется как разность между исходным числом и его целой частью. Формула выглядит так: ДробнаяЧасть = Число - Цел(Число). Для положительных чисел всё просто, для отрицательных есть нюанс, связанный с тем, как Цел() обрабатывает знак.
Ниже разобраны рабочие варианты кода для встроенного языка 1С, способ получить дробную часть в запросе, поведение функций с отрицательными числами и типичные ошибки, из-за которых копейки «теряются» или округление даёт неожиданный результат.
Какие функции 1С применяются для работы с целой и дробной частью
Во встроенном языке 1С за выделение целой части отвечает функция Цел() (в английском синтаксисе — Int()). Она отсекает дробную часть без округления: Цел(12.75) вернёт 12, Цел(12.25) — тоже 12. Это принципиально отличается от округления.
Функция Окр() (англ. Round()) выполняет именно округление до указанной разрядности: Окр(12.75, 0) даст 13, а Окр(12.25, 0) — 12. Если перепутать эти функции, итоговые суммы в документах начнут расходиться с ожидаемыми значениями.
Дробная часть не имеет собственной функции, поэтому её получают вычитанием: ДробнаяЧасть = Число - Цел(Число). Для 12.75 выражение вернёт 0.75. Чтобы получить дробную часть как целое число (например, копейки из суммы), результат дополнительно умножают на 100 и округляют: Копейки = Окр((Сумма - Цел(Сумма)) * 100, 0).
Базовый способ: выделение целой и дробной части через Цел()
Самый простой и надёжный вариант — вычесть из числа его целую часть. Код выглядит так:
Число = 123.456;
ЦелаяЧасть = Цел(Число); // 123
ДробнаяЧасть = Число - ЦелаяЧасть; // 0.456
Сообщить("Целая: " + ЦелаяЧасть);
Сообщить("Дробная: " + ДробнаяЧасть);
Такой подход подходит для любых положительных чисел и не зависит от разрядности. Если нужно получить дробную часть в виде целого числа с фиксированным количеством знаков, добавьте умножение и округление:
Сумма = 1234.56;
Рубли = Цел(Сумма); // 1234
Копейки = Окр((Сумма - Рубли) * 100, 0); // 56
Обратите внимание на Окр() в последней строке. Без округления из-за особенностей двоичного представления дробных чисел можно получить 55.999999 вместо 56 — это приведёт к потере копейки при дальнейшем приведении к целому.
- 1Сохраните исходное число в переменную, не перезаписывая его промежуточными результатами
- 2Получите целую часть: ЦелаяЧасть = Цел(Число)
- 3Вычислите дробную часть: ДробнаяЧасть = Число - ЦелаяЧасть
- 4Если нужна дробная часть как целое (копейки, знаки), умножьте на 10/100/1000 и примените Окр()
- 5Проверьте результат на граничных значениях: 0, отрицательное число, число с нулевой дробной частью
Отличие Цел() от Окр(): когда что использовать
Частая ошибка начинающих разработчиков — использовать Окр(Число, 0) для получения целой части. Это некорректно: Окр(12.7, 0) вернёт 13, тогда как целая часть числа 12.7 — это 12. Разница в одну единицу на каждой строке документа способна дать заметное расхождение в итогах.
| Выражение | Цел() | Окр(…, 0) |
|---|---|---|
| 12.4 | 12 | 12 |
| 12.5 | 12 | 13 |
| 12.9 | 12 | 13 |
| -12.4 | -12 | -12 |
| -12.6 | -12 | -13 |
Правило выбора простое: если нужно именно отсечь дробную часть (разложить сумму на рубли и копейки, количество на упаковки) — используйте Цел(). Если нужно математическое округление до ближайшего целого или заданной разрядности — Окр().
Особенности работы с отрицательными числами
Функция Цел() в 1С отсекает дробную часть в сторону нуля: Цел(-12.75) вернёт -12. Соответственно, выражение Число - Цел(Число) для -12.75 даст -0.75 — дробная часть получится отрицательной.
Если по логике задачи дробная часть должна быть всегда положительной (например, вы раскладываете модуль суммы), применяйте модуль числа перед разложением:
Число = -12.75;
МодульЧисла = ?(Число < 0, -Число, Число);
ЦелаяЧасть = Цел(МодульЧисла); // 12
ДробнаяЧасть = МодульЧисла - ЦелаяЧасть; // 0.75
В расчётах задолженности и возвратов знак обычно обрабатывают отдельно: сначала определяют направление (долг/переплата), затем раскладывают модуль суммы. Это защищает от ситуаций, когда отрицательные копейки «съедают» рубль при формировании печатной формы.
Дробная часть в запросах 1С
В языке запросов 1С нет прямого аналога Цел() для произвольного числа, но есть несколько обходных путей. Наиболее практичный — использование функции ВЫРАЗИТЬ с приведением к числу меньшей разрядности либо вычисление через вычитание с округлением.
Для задач вида «получить копейки от суммы» в запросе часто применяют такую конструкцию:
ВЫБРАТЬ
Продажи.Сумма КАК Сумма,
Продажи.Сумма - ВЫРАЗИТЬ(Продажи.Сумма КАК ЧИСЛО(15, 0)) КАК ДробнаяЧасть
ИЗ
Документ.РеализацияТоваровУслуг КАК Продажи
Приведение ВЫРАЗИТЬ(Сумма КАК ЧИСЛО(15, 0)) отсекает дробную часть на уровне СУБД, и разность даёт дробный остаток. Учтите, что поведение приведения типов может зависеть от используемой СУБД (MS SQL, PostgreSQL, файловый вариант), поэтому результат стоит проверить на тестовых данных именно в вашей среде.
Если дробная часть нужна только для отбора (например, найти документы с неровными суммами), достаточно условия вида ГДЕ Сумма <> ВЫРАЗИТЬ(Сумма КАК ЧИСЛО(15, 0)) — оно вернёт все записи, где есть копейки.
Перед использованием ВЫРАЗИТЬ в запросе проверьте поведение на своей СУБД: в некоторых ситуациях приведение ЧИСЛО(15,0) округляет, а не отсекает. Быстрый тест — выполнить запрос с суммой 100.75 и посмотреть, вернётся ли 0.75 или отрицательное значение.
Практические сценарии применения
Разложение суммы на рубли и копейки
Классическая задача для печатных форм и суммы прописью. Готовый фрагмент:
Функция РазложитьСумму(Сумма)
Результат = Новый Структура;
МодульСуммы = ?(Сумма < 0, -Сумма, Сумма);
Результат.Вставить("Рубли", Цел(МодульСуммы));
Результат.Вставить("Копейки", Окр((МодульСуммы - Цел(МодульСуммы)) * 100, 0));
Возврат Результат;
КонецФункции
Если копейки после округления оказались равны 100 (пограничный случай из-за представления дробных чисел), добавьте перенос: увеличьте рубли на 1 и обнулите копейки.
Разложение количества на упаковки и остаток
При работе с фасовкой: Цел(Количество / ВУпаковке) даёт число полных упаковок, а Количество % ВУпаковке (оператор остатка от деления) — остаток штук. Для 25 штук по 6 в упаковке получится 4 упаковки и 1 штука.
Проверка, является ли число целым
Условие Число = Цел(Число) возвращает Истина только для целых чисел. Это удобно для контроля ввода: если пользователь ввёл количество 2.5 там, где допустимы только целые значения, проверка сразу это покажет.
Как выбрать действие
Типичные ошибки и как их избежать
Первая и самая распространённая ошибка — отсутствие округления после вычитания. Из-за двоичного представления дробных чисел выражение (0.56) * 100 может дать 55.9999999999, и последующее Цел() вернёт 55 вместо 56. Всегда завершайте вычисление копеек функцией Окр().
Вторая ошибка — использование строковых функций для разложения числа: поиск точки через Найти() и разбор Лев()/Прав(). Такой код ломается при смене региональных настроек (разделитель может быть запятой), при экспоненциальном представлении больших чисел и при выводе в другом формате. Числовые операции надёжнее и быстрее.
Третья ошибка — забыть про отрицательные значения. Код, отлично работающий на положительных суммах, на возвратах и сторно начинает выдавать отрицательные копейки и неверные печатные формы. Проверяйте разложение на отрицательных тестовых данных.
Проверка результата
После внедрения кода проверьте его на контрольном наборе значений: целое число (100), число с одним знаком (12.5), число с копейками (1234.56), ноль, отрицательное значение (-99.99) и граничный случай с девятками (0.999). Сумма целой и дробной части должна точно сходиться с исходным числом.
Для финансовых расчётов полезен дополнительный контроль: разложите сумму на рубли и копейки, затем соберите обратно (Рубли + Копейки / 100) и сравните с исходным значением. Расхождение больше 0.005 сигнализирует об ошибке в логике округления.
Как проверить результат
Целая + Дробная = исходное число
Расхождение даже на 0.01
Рубли = 1234, Копейки = 56
Копейки = 55 или 57
Модуль разложен на 12 и 0.75
Отрицательные копейки в печатной форме
Дробная часть = 0
Дробная часть отлична от нуля
Частые вопросы
Есть ли в 1С готовая функция «ДробнаяЧасть»?
Нет, отдельной функции нет. Дробную часть получают выражением Число - Цел(Число). Для копеек добавляют умножение на 100 и Окр().
Чем Цел() отличается от Окр()?
Цел() отсекает дробную часть без округления: Цел(12.9) = 12. Окр() округляет до ближайшего значения: Окр(12.9, 0) = 13. Для разложения сумм нужен Цел(), для округления — Окр().
Почему копейки получаются на единицу меньше?
Причина — двоичное представление дробных чисел: 0.56 100 может дать 55.9999..., и Цел() отсечёт до 55. Решение — применять Окр((Сумма - Цел(Сумма)) 100, 0).
Как получить дробную часть в запросе?
Используйте приведение типа: Сумма - ВЫРАЗИТЬ(Сумма КАК ЧИСЛО(15, 0)). Предварительно проверьте на тестовых данных, отсекает ли приведение дробную часть в вашей СУБД или округляет.
Как узнать, является ли число целым?
Сравните число с его целой частью: условие Число = Цел(Число) истинно только для целых значений. Это удобно для контроля ввода и проверки делимости.
Как работает Цел() с отрицательными числами?
Цел() отсекает дробную часть в сторону нуля: Цел(-12.75) = -12. Если нужна положительная дробная часть, раскладывайте модуль числа, а знак обрабатывайте отдельно.
Что важно запомнить
Дробная часть в 1С вычисляется как Число - Цел(Число). Цел() отсекает, Окр() округляет — не путайте их в финансовых расчётах. Копейки получайте через Окр((Сумма - Цел(Сумма)) * 100, 0), отрицательные суммы раскладывайте по модулю, а в запросах используйте ВЫРАЗИТЬ с проверкой поведения на своей СУБД.