Как отрезать знаки после запятой без округления в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

В практической работе с конфигурациями 1С (например, 1С:Управление производственным предприятием) регулярно возникает задача изменения точности числовых реквизитов. Стандартная разрядность количества обычно составляет 3 знака после запятой, однако ранее она могла быть увеличена до 5 знаков. При попытке просто уменьшить точность реквизита в Конфигураторе платформа выполняет реструктуризацию и автоматически округляет значения по математическим правилам. Рассмотрим, почему так происходит и как правильно отрезать лишние знаки в хвосте числа без округления.

Почему платформа 1С округляет числа при уменьшении разрядности

Проанализируем поведение платформы и СУБД. Когда мы изменяем точность числового поля в Конфигураторе с 5 до 3 знаков, запускается процедура реструктуризации таблиц базы данных. На уровне СУБД (MS SQL Server или PostgreSQL) происходит преобразование типов данных (например, из DECIMAL(15,5) в DECIMAL(15,3)). СУБД по умолчанию выполняет стандартное математическое округление. В результате число 1.12356 превратится в 1.124, а не в 1.125 или 1.123.

Для того чтобы получить именно 1.123 (усечь 2 знака в хвосте), необходимо предварительно обработать данные программно и только после этого менять структуру метаданных в Конфигураторе.

Алгоритмы усечения дробной части числа в коде 1С

Разберем основные программные способы отбросить лишние знаки после запятой без математического округления.

Способ 1. Использование функции Цел()

Самый простой и популярный способ — умножение числа на 10 в степени N (где N — требуемое количество знаков), получение целой части и последующее деление на тот же коэффициент.

УсеченноеЗначение = Цел(ИсходноеЗначение * 1000) / 1000;

Рассмотрим пример: для числа 1.12567 операция Цел(1.12567 * 1000) вернет 1125, а деление на 1000 даст точно 1.125.

Способ 2. Использование функции Окр() со сдвигом

Усечение положительных чисел можно выполнить с помощью стандартной функции Окр, вычитая поправку перед округлением:

УсеченноеЗначение = Окр(ИсходноеЗначение - 0.0005, 3);

В общем виде для N знаков после запятой формула выглядит следующим образом:

УсеченноеЗначение = Окр(ИсходноеЗначение - 1 / (2 * Пов(10, N)), N);

Способ 3. Универсальный алгоритм с учетом знака числа

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


Функция УсечьЧисло(Значение, Знаков = 3)
    Множитель = Пов(10, Знаков);
    МодульЧисла = Макс(Значение, -Значение);
    РезультатМодуль = Цел(МодульЧисла * Множитель) / Множитель;
    Возврат ?(Значение >= 0, РезультатМодуль, -РезультатМодуль);
КонецФункции

Порядок массовой обработки документов и регистров в базе данных

Если в базе скопились документы за несколько лет (например, «Отчет производства за смену», «Требование-накладная», «Перемещение товаров»), перепроводить их нельзя из-за риска изменения себестоимости и закрытых периодов. Посмотри на пошаговый план решения этой задачи:

  1. Создание внешней обработки: пишем обработку, которая выбирает документы и их движения по регистрам накопления за нужный период.
  2. Модификация реквизитов и движений: программно меняем значения реквизитов в табличных частях документов и в записях регистров накопления, используя созданный алгоритм усечения, без вызова метода Записать(РежимЗаписиДокумента.Проведение). Выполняем прямую запись набора записей регистра и объекта документа.
  3. Изменение точности в Конфигураторе: после того как во всех записях 4-й и 5-й знаки после запятой станут нулевыми, меняем точность реквизитов с 5 до 3 знаков в Конфигураторе и обновляем конфигурацию базы данных.

Важные особенности учета остатков

При усечении количества в движениях документов необходимо учитывать партионный учет и РАУЗ. Если срезать только количество, не скорректировав суммы, на регистрах могут остаться зависшие копеечные суммовые остатки при нулевом количестве. Перед изменением разрядности обязательно проанализируйте остатки на тестовой копии базы данных.

← На главную