В процессе разработки отчетов по разузлованию спецификаций продукции, особенно в таких отраслях как фармацевтика или химическое производство, часто возникает критическая проблема: при многократном пересчете вложенных полуфабрикатов значения становятся ничтожно малыми, и итоговая сумма либо обнуляется, либо теряет значимую точность. Давайте разберем, почему это происходит и как с этим бороться.
Основная причина заключается в том, что 1С:Предприятие работает с типом данных Decimal (числа с фиксированной точкой). Когда вы выполняете математические операции (особенно деление) в запросе, система автоматически вычисляет разрядность результата. Если результат операции превышает возможности выбранного типа данных или настройки промежуточной временной таблицы, происходит отсечение разрядов.
Важно помнить, что временные таблицы в 1С при создании через конструкцию ПОМЕСТИТЬ могут автоматически ограничивать точность своих полей, если она не задана явно. Это приводит к тому, что на каждом уровне вложенности спецификаций ошибка накапливается, превращаясь к концу цепочки в статистическую погрешность.
Один из самых эффективных и надежных способов — это использование коэффициентов масштабирования. Вместо того чтобы пытаться сохранить высокую точность для дробных чисел, таких как 0,00000015, мы переводим их в целые числа.
Данный подход позволяет избежать работы с плавающей точкой в промежуточных вычислениях и сохраняет целостность данных на всех уровнях иерархии.
Если вы все же работаете с дробными величинами, необходимо принудительно задавать точность для всех промежуточных вычислений. Однако, будьте осторожны: конструкция ВЫРАЗИТЬ(... КАК ЧИСЛО(p, s)) не является панацеей. Если значение не влезает в заданный масштаб, данные будут обрезаны.
При использовании ВЫРАЗИТЬ следуйте правилам:
ВЫРАЗИТЬ к каждому операнду в арифметических операциях, если результат сложен.Если спецификации продукции очень глубокие и их пересчет «на лету» в одном запросе критически замедляет систему или вызывает ошибки точности, проанализируем архитектурное решение:
Рассмотрим вариант создания периодического РегистраСведений, в котором будет храниться уже развернутая структура материалов нижнего уровня.
// Пример логики обновления регистра:
// 1. При изменении спецификации запускается процедура пересчета.
// 2. Рекурсивным обходом обходим все уровни.
// 3. Записываем в регистр только «листья» (базовое сырье).
// 4. В отчете используем готовую таблицу регистра, что в разы быстрее.
Это не является «гомеопатией», как иногда ошибочно полагают, а представляет собой стандартный подход в промышленной автоматизации (использование денормализованных данных для ускорения и обеспечения точности расчетов).
Для решения текущей задачи по расчету потребности в сырье выполним следующие шаги:
ВЫРАЗИТЬ.Decimal.Помните, что точность Decimal в 1С ограничена 38 знаками в сумме (целая и дробная части вместе). Учитывая это, проектируйте свои запросы так, чтобы минимизировать количество преобразований типов, приводящих к потере значимых цифр.