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