В процессе работы в конфигурациях 1С, таких как УПП, УТ или КА, пользователи часто сталкиваются с неприятной ситуацией. Менеджер в документе "Заказ покупателя" вручную устанавливает итоговую сумму по товарной позиции, и система корректно пересчитывает процент ручной скидки, как и задано в настройках пользователя ("при изменении суммы пересчитывать скидку, а не цену"). Однако при создании документа "Реализация товаров и услуг" на основании этого заказа, итоговая сумма в новом документе оказывается другой. Давайте разберемся, почему так происходит и как с этим бороться.
Проблема кроется в типовой методологии 1С. Система стремится сохранить логическую целостность данных по формуле: (Цена × Количество) - Скидка = Сумма. Когда вы в заказе меняете сумму, система вычисляет процент скидки. Часто этот процент оказывается бесконечной дробью (например, 16,666...%). Система округляет его и сохраняет в таком виде. При создании документа "на основании" 1С не просто копирует итоговую сумму, а выполняет перерасчет, используя ключевые параметры: цену, количество и тот самый округленный процент скидки. Из-за этой погрешности в округлении и возникает разница в итоговых суммах.
Это не ошибка, а особенность стандартного механизма ("фича"), которая обеспечивает согласованность данных. Однако для бизнес-процессов, где важна именно итоговая сумма (например, при расчете бонусов менеджеров), это становится серьезной проблемой.
Рассмотрим несколько способов решения: от простого организационного до полноценной программной доработки.
Это самый быстрый способ, не требующий вмешательства в код конфигурации. Его суть — отказаться от использования проблемной настройки.
Отключите настройку. В настройках пользователя измените параметр на "При изменении суммы пересчитывать цену, а не скидку".
Объясните пользователям. Проведите инструктаж для менеджеров, объяснив, что система не позволяет точно работать с итоговой суммой таким образом. Им придется оперировать процентом скидки или ценой.
Плюсы: быстро, не требует программирования, не ломает типовой механизм.
Минусы: это "плохое решение", как его назвали на форуме. Оно не решает бизнес-задачу, а заставляет пользователей подстраиваться под ограничения системы. Если бизнес-процесс жестко завязан на установку конечной суммы, этот вариант не подойдет.
Если организационное решение неприемлемо, необходимо доработать конфигурацию. Цель доработки — заставить систему при вводе на основании не пересчитывать сумму, а переносить ее напрямую из документа-основания или связанных с ним данных. Рассмотрим несколько технических подходов.
Этот подход предполагает точечное изменение логики заполнения только одного документа, что является наиболее безопасным.
Шаги:
Откройте в конфигураторе модуль объекта документа "РеализацияТоваровУслуг".
Найдите процедуру ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка). Эта процедура выполняется при создании документа на основании.
Внутри этой процедуры, после выполнения стандартного заполнения, необходимо добавить код, который скорректирует суммы в табличной части "Товары". Логика должна быть следующей: для каждой строки созданной реализации найти соответствующую строку в заказе-основании и принудительно установить сумму из заказа.
Сложности и как их решать:
ЗаказыПокупателей.Остатки. Это гарантирует, что вы получите конечную, согласованную сумму.
На форуме было предложено вмешаться в общий модуль ОбработкаТабличныхЧастей и его процедуру РассчитатьСуммуТабЧасти(). Этот модуль используется многими документами, поэтому изменения в нем требуют особой осторожности.
Идея:
Внутри процедуры РассчитатьСуммуТабЧасти() добавить отдельную ветку кода. В ней нужно проверять условия: если документ создается на основании заказа покупателя, и у пользователя включена нужная нам настройка, то не выполнять стандартный пересчет, а брать сумму напрямую.
Риски:
Изменение общего модуля может повлечь за собой непредвиденные последствия в других частях системы. Этот способ рекомендуется только опытным разработчикам, которые могут полностью проанализировать влияние своих изменений.
Это элегантный и достаточно безопасный способ, который позволяет избежать правки сложной логики типовых механизмов.
Шаги:
Добавьте в табличную часть "Товары" документов "Заказ покупателя" и "Реализация товаров и услуг" новый реквизит, например, СуммаСтрокиДляПереноса (тип Число).
В модуле "Заказа покупателя" при проведении документа (или при изменении строки) заполняйте этот реквизит точным значением итоговой суммы по строке.
В процедуре ОбработкаЗаполнения документа "Реализация товаров и услуг" измените логику так, чтобы при создании на основании заказа, сумма для каждой строки бралась из этого нового реквизита СуммаСтрокиДляПереноса, а не пересчитывалась.
Этот метод позволяет явно и безопасно передать точное значение суммы между документами, минуя проблемный механизм пересчета через процент скидки.
В заключение, проблема с искажением суммы — это следствие архитектурных решений 1С. Для ее решения существует несколько путей: быстрый, но компромиссный организационный, и более правильные, но трудоемкие технические доработки. Выбор конкретного метода зависит от сложности ваших бизнес-процессов, требований к системе и квалификации разработчика.