В практической работе с конфигурациями 1С (например, 1С:Управление производственным предприятием) регулярно возникает задача изменения точности числовых реквизитов. Стандартная разрядность количества обычно составляет 3 знака после запятой, однако ранее она могла быть увеличена до 5 знаков. При попытке просто уменьшить точность реквизита в Конфигураторе платформа выполняет реструктуризацию и автоматически округляет значения по математическим правилам. Рассмотрим, почему так происходит и как правильно отрезать лишние знаки в хвосте числа без округления.
Проанализируем поведение платформы и СУБД. Когда мы изменяем точность числового поля в Конфигураторе с 5 до 3 знаков, запускается процедура реструктуризации таблиц базы данных. На уровне СУБД (MS SQL Server или PostgreSQL) происходит преобразование типов данных (например, из DECIMAL(15,5) в DECIMAL(15,3)). СУБД по умолчанию выполняет стандартное математическое округление. В результате число 1.12356 превратится в 1.124, а не в 1.125 или 1.123.
Для того чтобы получить именно 1.123 (усечь 2 знака в хвосте), необходимо предварительно обработать данные программно и только после этого менять структуру метаданных в Конфигураторе.
Разберем основные программные способы отбросить лишние знаки после запятой без математического округления.
Самый простой и популярный способ — умножение числа на 10 в степени N (где N — требуемое количество знаков), получение целой части и последующее деление на тот же коэффициент.
УсеченноеЗначение = Цел(ИсходноеЗначение * 1000) / 1000;
Рассмотрим пример: для числа 1.12567 операция Цел(1.12567 * 1000) вернет 1125, а деление на 1000 даст точно 1.125.
Усечение положительных чисел можно выполнить с помощью стандартной функции Окр, вычитая поправку перед округлением:
УсеченноеЗначение = Окр(ИсходноеЗначение - 0.0005, 3);
В общем виде для N знаков после запятой формула выглядит следующим образом:
УсеченноеЗначение = Окр(ИсходноеЗначение - 1 / (2 * Пов(10, N)), N);
Важно учитывать, что простые формулы с вычитанием поправки или вызовом Цел() могут давать погрешность на отрицательных числах. Проанализируем универсальный алгоритм, корректно работающий с любыми значениями:
Функция УсечьЧисло(Значение, Знаков = 3)
Множитель = Пов(10, Знаков);
МодульЧисла = Макс(Значение, -Значение);
РезультатМодуль = Цел(МодульЧисла * Множитель) / Множитель;
Возврат ?(Значение >= 0, РезультатМодуль, -РезультатМодуль);
КонецФункции
Если в базе скопились документы за несколько лет (например, «Отчет производства за смену», «Требование-накладная», «Перемещение товаров»), перепроводить их нельзя из-за риска изменения себестоимости и закрытых периодов. Посмотри на пошаговый план решения этой задачи:
Записать(РежимЗаписиДокумента.Проведение). Выполняем прямую запись набора записей регистра и объекта документа.При усечении количества в движениях документов необходимо учитывать партионный учет и РАУЗ. Если срезать только количество, не скорректировав суммы, на регистрах могут остаться зависшие копеечные суммовые остатки при нулевом количестве. Перед изменением разрядности обязательно проанализируйте остатки на тестовой копии базы данных.