При переходе на современные версии конфигураций, такие как 1С:Управление торговлей 11.5, 1С:ERP 2.5 или Комплексная автоматизация 2.5, разработчики часто сталкиваются с новой логикой контроля количества. Типичная ситуация: заказы успешно загружаются с сайта через API или используется массовое оформление продаж по выгрузкам Excel/CSV, но при попытке проведения документа система выдает критическую ошибку: «После округления количество товара будет равно X шт, при этом погрешность округления составит Y, что превышает максимальную погрешность».
Конечно, в экстренных ситуациях может потребоваться проведение документов без контроля остатков и прочих строгих проверок, но игнорировать ошибки математического округления нельзя. Давайте подробно разберем, почему это происходит и как правильно адаптировать программный код для решения этой проблемы.
Проанализируем архитектурные изменения в последних версиях платформы. Основная причина кроется в появлении концепции «Мерных единиц измерения». В отличие от обычных штук, мерные единицы (например, когда учитываются вес и объём в документах, метры или даже штуки, настроенные особым образом) требуют строгого соответствия между реквизитами Количество и КоличествоУпаковок в табличной части Товары — для этого есть учет весовых и объемных характеристик в 1С.
Рассмотрим ситуацию глубже. Когда пользователь работает в интерфейсе и выбирает номенклатуру или меняет количество, 1С автоматически запускает обработчики событий (например, ПриИзменении), которые вызывают типовые процедуры пересчета. Однако при автоматизированном управлении заказами и их загрузке извне эти обработчики не срабатывают автоматически, если разработчик просто присваивает значения полям. В итоге возникает микроскопическая разница (на уровне 10–15 знака после запятой) из-за особенностей вычислений с плавающей точкой, что и блокирует проведение документа.
Прежде чем вносить изменения в код, проверим, как именно выглядят данные в базе сразу после загрузки. Рекомендуем выполнить следующий запрос в консоли для проблемного заказа:
ВЫБРАТЬ
ЗаказКлиентаТовары.Ссылка КАК Ссылка,
ЗаказКлиентаТовары.Номенклатура КАК Номенклатура,
ЗаказКлиентаТовары.Упаковка КАК Упаковка,
ЗаказКлиентаТовары.КоличествоУпаковок КАК КоличествоУпаковок,
ЗаказКлиентаТовары.Количество КАК Количество,
ЗаказКлиентаТовары.КодСтроки КАК КодСтроки
ИЗ
Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
ЗаказКлиентаТовары.Ссылка = &Ссылка
Проанализируем результат. Обратите внимание на значения в колонках Количество и КоличествоУпаковок. Если упаковка не используется, они должны быть строго идентичны. Если же вы видите даже незначительное отклонение в невидимой части дробного числа, это и есть источник ошибки. Попробуйте вручную перевыбрать единицу измерения в документе — если ошибка исчезает, значит, проблема точно в отсутствии вызова типовых алгоритмов пересчета при загрузке.
Для корректного заполнения табличной части недостаточно просто заполнить поля Количество. Необходимо использовать методы, которые предоставляет сама конфигурация. Это правило универсально: работаете ли вы с заказами клиентов или выполняется загрузка данных в складские документы (такие как перемещения или оприходования). Рассмотрим наиболее надежный способ — вызов процедур из серверных модулей НоменклатураКлиентСервер или ОбработкаТабличнойЧастиТоварыСервер.
В коде загрузки, после того как вы добавили строку в таблицу товаров, необходимо вызвать расчет количества. Посмотрим на пример:
// Предположим, ТекущаяСтрока — это строка табличной части Заказа Клиента
СтруктураПересчета = НоменклатураКлиентСервер.ПараметрыПересчетаКоличества(ТекущаяСтрока);
НоменклатураКлиентСервер.РассчитатьКоличествоУпаковок(ТекущаяСтрока, СтруктураПересчета);
Этот метод гарантирует, что 1С правильно заполнит все скрытые служебные реквизиты, связанные с упаковками и кратностью мерных единиц. Если вы используете специфические упаковки, убедитесь, что в коде заполнены Числитель и Знаменатель для единицы измерения номенклатуры.
Выясним еще один нюанс: данные, приходящие с сайта (например, в формате JSON или XML (есть массовая загрузка документов из внешних файлов)), могут содержать лишние знаки после запятой, которые не предусмотрены настройками единицы измерения в 1С. Чтобы избежать конфликтов, рекомендуем явно применять функцию Окр().
Разберем пример обработки входящего количества:
// Устанавливаем точность в соответствии с настройками единицы хранения в базе
ТочностьЕдиницы = 3; // Для весового товара или 0 для штучного
НоваяСтрока.Количество = Окр(ВходящееЗначениеССайта, ТочностьЕдиницы);
НоваяСтрока.КоличествоУпаковок = НоваяСтрока.Количество;
Важный момент: если в настройках справочника «Упаковки и единицы измерения» для единицы «шт» указано, что она мерная, а точность установлена в 0, то любое значение типа 10.0000001 приведет к ошибке «максимальная погрешность — 0».
Если программные методы не помогают, проанализируем настройки самой программы в интерфейсе. Посмотрим на следующие пункты:
Подводя итоги, отметим, что ошибка округления в УТ 11.5 — это не программный сбой, а работа механизма контроля целостности данных. Для ее устранения при программной разработке следуйте правилам:
НоменклатураКлиентСервер.РассчитатьКоличествоУпаковок() после заполнения количества.Количество и КоличествоУпаковок (умноженное на коэффициент) всегда совпадали до последнего знака.Соблюдение этих шагов позволит избежать ошибок проведения и обеспечит стабильную работу обмена данными между вашим сайтом и 1С.