К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как в 1С определить, что число дробное

Как во встроенном языке 1С проверить, является ли число дробным: функции Цел(), Окр(), остаток от деления, готовые примеры кода и типичные ошибки.

Во встроенном языке 1С нет отдельной функции вида «ЭтоДробноеЧисло», поэтому проверку приходится собирать из стандартных математических операций. Число считается дробным, если оно не равно собственной целой части, — именно на этом факте строятся все рабочие приёмы.

Задача возникает чаще, чем кажется: при валидации введённых пользователем значений, при контроле количества в документах (нельзя отгрузить 2,5 штуки, если единица измерения штучная), при разборе данных из файлов обмена и при расчётах, где дробный результат сигнализирует об ошибке в исходных данных.

Ниже разобраны основные способы проверки: через функцию Цел(), через остаток от деления, через округление, а также подводные камни, связанные с точностью представления чисел и типом «Строка».

Проверка через функцию Цел() — основной способ

Функция Цел() возвращает целую часть числа, отбрасывая дробную (без округления). Если исходное число не равно своей целой части, значит, дробная часть присутствует.

Функция ЭтоДробноеЧисло(Число)

Возврат Число <> Цел(Число);

КонецФункции

// Использование:

Если ЭтоДробноеЧисло(Количество) Тогда

Сообщить("Количество должно быть целым числом!");

КонецЕсли;

Приём работает и с положительными, и с отрицательными числами: Цел(-3,7) вернёт -4 (функция округляет в меньшую сторону), поэтому сравнение -3,7 <> -4 корректно покажет дробность. Это важно учитывать: Цел() — не «отсечение», а округление вниз, но для задачи определения дробности это не мешает.

Если нужно наоборот — убедиться, что число целое, условие инвертируется: Число = Цел(Число). Такая проверка типична для контроля количества в табличных частях документов перед записью.

bsl
Если Число <> Цел(Число) Тогда
	Сообщить("Число дробное");
Иначе
	Сообщить("Число целое");
КонецЕсли;

Проверка через остаток от деления

Второй распространённый приём — оператор остатка от деления %. Если остаток от деления числа на 1 не равен нулю, число дробное.

Если Число % 1 <> 0 Тогда

// есть дробная часть

КонецЕсли;

Результат операции Число % 1 — это сама дробная часть числа. Её можно не только проверить, но и использовать дальше, например чтобы отделить копейки от рублей: Копейки = (Сумма % 1) * 100.

Оба способа — через Цел() и через % — функционально эквивалентны для задачи определения дробности. Выбор обычно делают по читаемости кода: сравнение с Цел() понятнее новичкам, остаток от деления компактнее.

Округление и функция Окр() — когда нужна не проверка, а приведение

Иногда задача ставится иначе: не определить дробность, а избавиться от неё. Здесь работает функция Окр(Число, Разрядность, РежимОкругления). Например, Окр(Число, 0) округлит значение до целого по правилам арифметического округления.

Комбинируя Окр() со сравнением, можно строить проверки с допуском: число считается «условно целым», если после округления до нужного знака оно совпадает с исходным. Это полезно при расчётах с весом или объёмом, где технологически допустимы сотые доли, но не тысячные.

// Допускаем не более 2 знаков после запятой

Если Окр(Значение, 2) <> Значение Тогда

Сообщить("Точность больше двух знаков не поддерживается");

КонецЕсли;

Особенности точности: почему «целое» число вдруг дробное

Главный подводный камень — представление чисел с плавающей точкой при вычислениях. Результат деления вроде 0,1 + 0,2 может храниться с хвостом в дальних разрядах, и строгое сравнение Число = Цел(Число) неожиданно покажет дробность там, где логически число целое.

Практическое решение — сравнение с погрешностью. Вместо точного равенства проверяют, что модуль разности меньше малого порога:

Погрешность = 0.0000001;

Если Макс(Число, Цел(Число)) - Мин(Число, Цел(Число)) > Погрешность Тогда

// число действительно дробное

КонецЕсли;

Другой вариант — заранее округлить результат расчёта функцией Окр() до разумной разрядности, и только потом проверять. В типовых конфигурациях денежные и количественные значения обычно хранятся с фиксированной точностью (например, 2–3 знака), что частично снимает проблему.

Типичные ошибки
01
Сравнение результатов деления на строгое равенство без учёта погрешности — получаете ложное срабатывание проверки
02
Использование Цел() для округления к ближайшему целому — функция округляет вниз, а не по арифметическим правилам
03
Проверка строки вместо числа: значение из формы может быть строкой, и сравнение даст неожиданный результат или ошибку
04
Попытка определить дробность анализом строки с разделителем — ломается при смене региональных настроек (точка или запятая)

Проверка значения из формы или строки

Когда значение приходит из поля ввода, файла или веб-сервиса, оно часто имеет тип «Строка». Прежде чем проверять дробность, строку нужно привести к числу и убедиться, что приведение прошло успешно.

ОписаниеЧисла = Новый ОписаниеТипов("Число");

ЧисловоеЗначение = ОписаниеЧисла.ПривестиЗначение(СтрокаИзФайла);

Если ЧисловоеЗначение = 0 И СокрЛП(СтрокаИзФайла) <> "0" Тогда

Сообщить("Значение не является числом");

ИначеЕсли ЧисловоеЗначение <> Цел(ЧисловоеЗначение) Тогда

Сообщить("Число дробное");

КонецЕсли;

Учтите региональные настройки: в данных обмена разделителем дробной части может быть точка, а пользовательский ввод — с запятой. Перед приведением строку иногда нормализуют через СтрЗаменить(Строка, ",", "."), но делать это стоит только если формат входных данных известен и стабилен.

Маршрут решения

Как выбрать способ проверки

Значение уже имеет тип Число и получено без сложных вычисленийИспользуйте простое сравнение Число <> Цел(Число)
Число — результат деления или арифметики с дробямиСначала округлите через Окр() или сравнивайте с погрешностью
Значение пришло строкой из файла или формыПриведите к числу через ОписаниеТипов и проверьте успешность приведения
Нужно не проверить, а получить дробную частьИспользуйте выражение Число % 1

Практические сценарии применения

Контроль количества в документе

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

Для Каждого СтрокаТовара Из Товары Цикл

Если СтрокаТовара.Количество <> Цел(СтрокаТовара.Количество) Тогда

Сообщить("В строке " + СтрокаТовара.НомерСтроки + " дробное количество для штучного товара");

Отказ = Истина;

КонецЕсли;

КонецЦикла;

Проверка кратности упаковки

Похожая задача — проверить, что количество кратно размеру упаковки. Здесь дробность результата деления как раз и есть сигнал ошибки: Если (Количество / ВУпаковке) % 1 <> 0 Тогда — количество не кратно упаковке.

Валидация при загрузке из Excel или CSV

При разборе внешних файлов дробное значение там, где ожидается целое (артикул, код, счётчик), — признак съехавшей структуры файла. Проверка дробности в этом случае работает как детектор ошибок формата данных.

Контрольные точки

Как проверить результат

Тест с целым числом (например, 5)
Норма

Проверка сообщает, что число целое

Тревожный признак

Проверка ложно определяет дробность — ищите проблему с погрешностью

Тест с дробным числом (например, 2,5)
Норма

Проверка срабатывает

Тревожный признак

Дробное число проходит как целое — проверьте тип значения

Тест с отрицательным дробным (-3,7)
Норма

Корректно определяется как дробное

Тревожный признак

Ошибки из-за непонимания работы Цел() с отрицательными значениями

Тест со строкой "12,5" из файла
Норма

Значение приводится к числу и проверяется

Тревожный признак

Ошибка приведения типов или неверный разделитель

FAQ

Чем Цел() отличается от Окр(Число, 0)?

Цел() всегда округляет в меньшую сторону: Цел(3,9) = 3, Цел(-3,2) = -4. Окр(Число, 0) округляет по арифметическим правилам к ближайшему целому: Окр(3,9, 0) = 4. Для определения дробности подходят обе, для преобразования значения — выбирайте по нужной логике округления.

Как проверить, что число целое, в запросе 1С?

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

Почему сравнение Число = Цел(Число) даёт Ложь для результата деления 10/5?

Такое возможно при промежуточных вычислениях с плавающей точкой, когда в дальних разрядах остаётся «хвост». Решение — округлить результат через Окр() до рабочей разрядности или сравнивать разность с малой погрешностью вместо строгого равенства.

Как получить только дробную часть числа?

Выражение Число % 1 вернёт дробную часть (для 12,75 получится 0,75). Альтернатива: Число - Цел(Число), но для отрицательных чисел результаты двух способов отличаются, так как Цел() округляет вниз.

Можно ли проверить дробность у значения типа Строка без преобразования?

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

Что делать, если пользователь вводит число с запятой, а 1С ожидает точку?

Перед приведением нормализуйте строку: СтрЗаменить(Строка, ",", "."). Но применяйте замену только когда формат ввода известен — в универсальном коде лучше полагаться на штатное приведение типов, которое учитывает региональные настройки сеанса.

Итог

Что важно запомнить

Дробность числа в 1С определяется сравнением значения с его целой частью: Число <> Цел(Число), либо проверкой остатка Число % 1. Для результатов вычислений с плавающей точкой используйте округление или погрешность, а строковые значения сначала приводите к числу.