При оформлении документов реализации нередко возникает необходимость массово скорректировать данные в табличной части товаров. В типовых конфигурациях для этого предусмотрена встроенная обработка (кнопка Изменить над таблицей товаров). В выпадающем списке команд «Что сделать?» присутствуют стандартные варианты, например «Изменить цены на процент» или «Округлить цены до». Однако штатного действия для увеличения цен каждой строки на определенную сумму нет. Разберем по шагам, как добавить такой функционал, почему при простой модификации цены может некорректно вести себя сумма и как правильно организовать пересчет реквизитов строки.
Проанализируем распространенную ошибку разработчиков при доработке этой формы. При добавлении собственного действия программист часто пишет цикл обхода строк табличной части, рассчитывая только цену:
Для каждого СтрокаТабличнойЧасти Из Объект.Товары Цикл
Если СтрокаТабличнойЧасти.Пометка Тогда
СтрокаТабличнойЧасти.Цена = СтрокаТабличнойЧасти.Цена + СуммаРаспределения;
// пересчитаем связанные реквизиты
РассчитатьСуммыСтрокиТабличнойЧасти(СтрокаТабличнойЧасти, ПоказыватьСуммуНДС, ДокументСуммаВключаетНДС);
КонецЕсли;
КонецЦикла;
На практике после такого кода пользователи сталкиваются с тем, что на форме или после переноса в документ изменяется итоговая сумма, а цена остается прежней либо пересчитывается не так, как ожидалось. Выясним причину такого поведения:
РассчитатьСуммыСтрокиТабличнойЧасти или аналогичных методов платформенной библиотеки в зависимости от переданных флагов приоритетом может обладать исходная сумма документа. Если реквизиты согласованы не полностью, алгоритм пересчитывает цену по формуле Сумма / Количество, тем самым затирая новое значение цены.Рассмотрим, как корректно организовать увеличение цены на фиксированную величину (наценку на единицу товара). Разберем по шагам:
СуммаРаспределения или отдельного поля наценки).Цена.Сумма с обязательным округлением до двух знаков: Окр(Строка.Цена * Строка.Количество, 2).Посмотрим на пример корректного кода для изменения цены на фиксированную сумму:
Для каждого СтрокаТабличнойЧасти Из Объект.Товары Цикл
Если СтрокаТабличнойЧасти.Пометка Тогда
СтрокаТабличнойЧасти.Цена = СтрокаТабличнойЧасти.Цена + СуммаРаспределения;
СтрокаТабличнойЧасти.Сумма = Окр(СтрокаТабличнойЧасти.Цена * СтрокаТабличнойЧасти.Количество, 2);
// Вызываем штатный пересчет зависимых сумм (НДС, Всего)
РассчитатьСуммыСтрокиТабличнойЧасти(СтрокаТабличнойЧасти, ПоказыватьСуммуНДС, ДокументСуммаВключаетНДС);
КонецЕсли;
КонецЦикла;
Если требуется не просто увеличить цену за единицу, а распределить общую фиксированную сумму по строкам документа, подход меняется: сначала рассчитывается дельта суммы для каждой строки (пропорционально стоимости или количеству), затем вычисляется новая цена как НоваяСумма / Количество, а копейки погрешности округления относятся на позицию с наибольшей суммой.
Рассмотрим способы внедрения нового функционала без изменения типового кода поставщика, чтобы не усложнять последующие обновления программы:
&Вместо или &После. В таком случае основная конфигурация остается на полной поддержке.Таким образом, для стабильной работы алгоритма необходимо соблюдать баланс между ценой и суммой, ориентироваться на типовые процедуры пересчета (такие как в действиях «Изменить цены на процент») и контролировать выполнение сопутствующего кода через отладчик платформы 1С.