Работа с числовыми данными в системе 1С:Предприятие требует от разработчика и пользователя предельной внимательности, особенно когда речь заходит о преобразовании типов и манипуляциях с десятичными знаками. Часто возникает задача, когда необходимо игнорировать дробную часть числа, оставляя только целое значение, но при этом не применяя стандартное математическое округление. Это критически важно при расчете зарплат, формировании складских остатков или подготовке данных для выгрузки в сторонние системы, где требования к точности могут отличаться.

В отличие от многих других языков программирования, где функция усечения является базовой операцией, в 1С существует несколько подходов к решению этой задачи, каждый из которых имеет свои нюансы поведения с отрицательными числами и влияет на производительность запросов. Неправильный выбор метода может привести к расхождениям в отчетах на копейки или даже рубли, что недопустимо в бухгалтерском учете.

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

Функция Цел: прямое усечение дробной части

Самым очевидным и часто используемым инструментом для решения поставленной задачи является встроенная функция Цел. Она возвращает целую часть числа, просто отбрасывая все знаки после десятичной точки, независимо от их значения. Важно понимать, что поведение этой функции с отрицательными числами отличается от привычной математической логики округления «до ближайшего целого».

Если вы передадите в функцию число 3.9, результат будет 3. Однако, если аргументом станет -3.9, функция вернет -3, а не -4, как могло бы показаться при движении по числовой оси влево. Это происходит потому, что Цел работает именно как усечение (truncation), а не как математическое округление вниз (floor).

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

⚠️ Внимание: Функция Цел возвращает значение типа «Число», но без дробной части. Если вы планируете использовать результат в дальнейших вычислениях с высокой точностью, убедитесь, что потеря дробной части не исказит итоговый баланс.

💡

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

Функция Округл: гибкая настройка направления

Более мощным инструментом, предоставляющим полный контроль над процессом, является функция Округл. Она позволяет не только отбросить дробную часть, но и явно указать направление округления, что делает код более читаемым и предсказуемым для других разработчиков. Синтаксис функции требует указания числа и направления округления.

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

Пример использования в коде выглядит следующим образом:

ЧислоИсходное = 15.87;

ЧислоРезультат = Округл(ЧислоИсходное, НаправлениеОкругления.Вниз);

// Результат: 15

Преимуществом подхода с использованием Округл является явное намерение разработчика. Когда другой программист видит этот код, он сразу понимает, что происходит манипуляция с точностью, а не просто получение целой части. Это снижает вероятность ошибок при рефакторинге кода в будущем.

📊 Какой метод вы используете чаще всего?
Функция Цел
Функция Округл
Математические операции
Форматирование строки

Работа с числами в запросах 1С

Когда обработка данных происходит на уровне запроса к базе данных, использование функций языка 1С внутри выборки невозможно или неэффективно. В этом случае разработчики прибегают к функциям языка запросов, которые могут работать медленнее или иметь ограничения в зависимости от используемой СУБД (MSSQL, PostgreSQL, Oracle).

В языке запросов 1С для отбрасывания дробной части обычно используется функция ЦЕЛ (аналог функции языка). Она работает схожим образом, отбрасывая дробную часть числа. Однако стоит учитывать, что выполнение таких вычислений в запросе может помешать использованию индексов, если условие выборки зависит от результата вычисления.

Рассмотрим пример запроса, где необходимо вывести количество целых коробок товара:

ВЫБРАТЬ

Товары.Номенклатура,

Товары.Остаток,

ЦЕЛ(Товары.Остаток / Товары.Вместимость) КАК ЦелыеКоробки

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК Товары

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

Метод Контекст использования Производительность Читаемость
Функция Цел Встроенный язык, код Высокая Средняя
Функция Округл Встроенный язык, код Высокая Высокая
Функция ЦЕЛ (запрос) Язык запросов Зависит от СУБД Высокая
Математика (MOD) Встроенный язык Средняя Низкая

⚠️ Внимание: Избегайте вычисления функций усечения в условиях соединения (JOIN) запросов. Это может привести к полному сканированию таблиц вместо использования индексов, что критически замедлит работу системы при больших объемах данных.

☑️ Оптимизация запроса с усечением

Выполнено: 0 / 4

Альтернативные математические способы

Иногда стандартные функции могут не подходить из-за специфических требований к логике работы с отрицательными числами или из-за необходимости совместимости со старыми версиями конфигураций. В таких случаях разработчики используют классические математические операции, такие как вычисление остатка от деления.

Суть метода заключается в вычитании дробной части из исходного числа. Дробную часть можно получить, найдя остаток от деления числа на 1. Формула выглядит так: Число - (Число % 1). Однако оператор % (остаток от деления) в 1С имеет свои особенности работы с отрицательными числами, знак результата зависит от знака делимого.

Для положительных чисел этот метод работает безупречно и часто оказывается быстрее вызова встроенных функций, так как является элементарной арифметической операцией процессора. Но для отрицательных чисел результат может быть неожиданным: -3.9 % 1 даст -0.9, и вычитание этого значения приведет к -3, что совпадает с поведением Цел.

Если вам требуется поведение математического пола (floor), то есть округление всегда в сторону минус бесконечности (чтобы -3.1 превратилось в -4), то простая арифметика не подойдет без дополнительных условий. В таких случаях лучше использовать комбинацию функций или явные проверки знака числа.

Почему остаток от деления ведет себя странно?

В 1С знак остатка от деления совпадает со знаком делимого. Это отличается от поведения в некоторых других языках, где знак совпадает с делителем или всегда положителен.

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

Существует еще один, менее очевидный способ отбрасывания дробной части — преобразование числа в строку с определенным форматом и обратное преобразование. Этот метод часто используется при формировании печатных форм или выгрузке в текстовые файлы, но может быть применен и для логики программы.

Используя функцию Формат, можно задать строку формата, которая обрежет лишние знаки. Например, формат "ЧЦ=15; ЧД=0" укажет системе отображать число с нулем знаков после запятой. Однако

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

Такой подход считается «тяжелым» с точки зрения производительности, так как требует выделения памяти под строковые объекты и парсинг. Используйте его только в тех случаях, когда результат сразу готовится для вывода пользователю или в отчет, а не для промежуточных вычислений.

⚠️ Внимание: Преобразование «Число -> Строка -> Число» приводит к потере точности и значительным затратам ресурсов процессора. Никогда не используйте этот метод внутри циклов, обрабатывающих тысячи строк табличной части документа.

Сравнение производительности и выбор метода

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

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

Если вы работаете в thick-клиенте или серверном коде, разница может быть незаметна. Но в тонком клиенте или при выполнении сложных запросов с вычислениями на стороне СУБД, выбор неправильной функции может привести к тому, что запрос будет выполнен полностью на стороне сервера 1С, а не передан базе данных, что резко снизит скорость.

💡

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

Часто задаваемые вопросы (FAQ)

В чем разница между функциями Цел и Округл с направлением Вниз?

Функция Цел всегда просто отбрасывает дробную часть (усекает к нулю). Функция Округл с направлением Вниз округляет в сторону минус бесконечности. Для положительных чисел результат одинаков, но для отрицательных (например, -3.9) Цел вернет -3, а Округл(.., Вниз) вернет -4.

Можно ли отбросить дробную часть в макете табличного документа?

Да, в макетах табличного документа можно использовать функцию Цел() прямо в выражениях ячеек. Также можно настроить формат ячейки, указав количество знаков после запятой равным 0, но это повлияет только на отображение, а не на само значение в ячейке.

Как отбросить дробную часть, оставив 2 знака, но без округления?

Для этого число нужно умножить на 100, применить функцию Цел, а затем разделить результат на 100. Пример: Цел(Число * 100) / 100. Это позволит усечь все знаки после второго, не округляя третий знак.

Влияет ли тип числа (ПланВидовХарактеристик и т.д.) на работу функции?

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

Почему в запросе функция ЦЕЛ работает медленнее, чем в коде?

В запросах функция ЦЕЛ выполняется на стороне базы данных или эмулируется платформой перед передачей в СУБД. В некоторых случаях это препятствует использованию индексов или требует дополнительных вычислительных ресурсов СУБД для обработки каждой строки результата.