В типовой конфигурации 1С:Предприятие 7.7 «Торговля и склад» часто возникает задача по оптимизации ввода данных. Одна из типичных проблем — необходимость быстро изменить единицы измерения (например, с «кг» на «упаковки») сразу для всех позиций, уже подобранных в документ «Поступление ТМЦ» или «Реализация ТМЦ». По умолчанию система подставляет основную единицу, и ручная правка каждой строки отнимает много времени. Рассмотрим, как программно реализовать механизм массовой замены единиц измерения с корректным пересчетом цен и сумм.
Прежде чем приступать к кодингу, проанализируем важную техническую особенность платформы 7.7. В отличие от более современных версий, здесь единица измерения в табличной части документа — это не просто ссылка на общероссийский классификатор (ОКЕИ). Это ссылка на элемент справочника Единицы, который является подчиненным справочнику Номенклатура. Это означает, что у каждого товара есть свой набор записей в справочнике Единицы, каждая из которых имеет свой коэффициент пересчета относительно базовой единицы.
Для реализации нашей задачи нам потребуется:
Разберем логику, которую необходимо заложить в обработчик нажатия кнопки. Мы не можем просто присвоить всем строкам одну и ту же единицу измерения, так как для «Товара А» единица «Упаковка» — это один элемент справочника, а для «Товара Б» — совсем другой.
Рассмотрим пошагово процесс обработки:
ВыгрузитьТабличнуюЧасть. Работа с объектом ТаблицаЗначений в памяти происходит значительно быстрее, чем прямой перебор строк документа.Единицы ту запись, у которой реквизит ОКЕИ совпадает с выбранным пользователем значением.Одной из главных сложностей является автоматическое обновление цен. Если мы просто заменим единицу, сумма документа станет некорректной. Выясним причину: цена товара в 1С 7.7 часто привязана к конкретной единице измерения. Посмотрим на пример кода, который позволяет пересчитать цены во всем документе после смены единиц:
// В коде формы документа создадим процедуру
Процедура ИзменитьЕдиницыИзмерения()
// Предполагаем, что ВыбОКЕИ - это выбранная единица из классификатора на форме
Если ВыбраннаяЕдиницаОКЕИ.Выбран() = 0 Тогда
Предупреждение("Выберите единицу измерения для замены!");
Возврат;
КонецЕсли;
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Ищем единицу измерения у текущей номенклатуры по классификатору
СпрЕд = СоздатьОбъект("Справочник.Единицы");
СпрЕд.ИспользоватьВладельца(Номенклатура);
Если СпрЕд.НайтиПоРеквизиту("ОКЕИ", ВыбраннаяЕдиницаОКЕИ, 0) = 1 Тогда
// Если нашли - меняем единицу в строке
Единица = СпрЕд.ТекущийЭлемент();
Коэффициент = Единица.Коэффициент;
// Получаем новую цену для этой единицы измерения
Цена = глПолучитьЦену(Номенклатура, ТипЦен, ДатаДок, Единица, Валюта, Курс, Кратность);
Иначе
Сообщить("Для товара " + СокрЛП(Номенклатура.Наименование) + " не найдена единица " + ВыбраннаяЕдиницаОКЕИ);
КонецЕсли;
КонецЦикла;
// После цикла вызываем глобальную процедуру пересчета всех итогов (налоги, суммы)
глПересчитатьСтрокиДокумента(Контекст, Валюта, Курс);
КонецПроцедуры
Проанализируем ситуацию с точки зрения бизнес-логики. Существует два подхода к пересчету количества при смене единицы:
НовоеКоличество = (СтароеКоличество * СтарыйКоэффициент) / НовыйКоэффициент.Внимание: В типовых решениях «Торговли и склада» чаще всего используется первый вариант. Однако будьте осторожны с округлением. В 1С 7.7 точность количества ограничена 3 знаками после запятой. При делении на коэффициент могут возникнуть «хвосты», которые приведут к расхождениям в остатках на складе, так как регистры остатков в 7.7 обычно ведутся в базовых единицах измерения.
Также стоит помнить о налогах. После программного изменения цен и количеств обязательно вызывайте процедуру глПересчитатьНалоги(Контекст). Это гарантирует, что НДС и НП в подвале документа обновятся корректно. Если этого не сделать, визуально суммы могут остаться прежними до тех пор, пока пользователь не зайдет в строку вручную.
Рассмотрим основные ограничения, которые следует внедрить в код:
глПолучитьЦену может вернуть значение, отличное от текущего, и перезатереть ручные скидки.Если Коэффициент = 0 Тогда перед делением, чтобы избежать критической ошибки завершения работы программы.Таким образом, мы разобрали, что задача массовой смены единиц измерения в 1С 7.7 вполне решаема. Главное — учитывать подчиненную структуру справочника Единицы и не забывать про вызов стандартных глобальных функций пересчета сумм и налогов для сохранения целостности данных документа.