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