Всем привет!
Все описанные методы были разработаны и протестированы на 1С:Предприятие 8.3.18.1334, 1С:Комплексная автоматизация 2.4.14.164 с использованием расширений.
Исходная задача была следующей: необходимо было создать новую печатную форму "Расходного ордера на товары" с отображением веса-брутто товара и ячеек (основных и дополнительных) - см. рис. 1, при этом вес-брутто необходимо начать заводить через окно "Размещение номенклатуры по ячейкам (справочно)", открываемого из расходника - см. рис.2.

рис. 1.

рис. 2.
С точки зрения программирования, надо было реализовать чтение веса-брутто при создании печатной формы и при открытии окна размещения товаров, и записи веса-брутто через окно размещения товаров.
Вес-брутто товара задается в карточке упаковки - это справочник "УпаковкиЕдиницыИзмерения", вес-нетто - в карточке номенклатуры - это типовой механизм (!). Поэтому чтение веса-брутто организуем "из" упаковки, а запись - соответственно "в" упаковку.
На данном рабочем примере будут продемонстрированы методы работы с упаковками и единицами измерения: чтения, записи, просмотра журнала регистрации, запросы для консоли запросов. Представленные алгоритмы помогут вам разобраться с устройством типового механизма упаковок.
Для нашей задачи номенклатура делится на три категории:
1) номенклатура, у которой признак "ИспользоватьУпаковки" (тип Булево) не возведен (то есть =Ложь);
2) номенклатура, у которой признак ИспользоватьУпаковки = Истина, и с ней связан общий "набор упаковок",
3) номенклатура, у которой признак ИспользоватьУпаковки = Истина, и с ней связана индивидуальная упаковка (правильнее говорить "индивидуальный набор упаковок").
Алгоритмы, представленные в статье, не обладают универсальностью, поскольку при разработке были приняты определенные допущения и ограничения: к примеру, что индивидуальных упаковок или общих наборов упаковок для каждой номенклатуры будет только по одной штуке - то есть:
1) для категории 1 - нет упаковок (к примеру, все мерные товары - то есть не штучные, а метровые, килограммовые и др.),
2) для категории 2 - один набор упаковок,
3) для категории 3 - одна индивидуальная упаковка. Технически можно задавать несколько наборов и несколько инд. упаковок, но в базе есть определенные договоренности по ведению учета - вторых наборов или инд. упаковок пока не должно быть.
Для понимания, исторически изначально упаковки не использовались в базе - использовались только единицы измерения. Со временем началось внедрение адресного хранения, при котором "использование упаковок" обязательно. Для большинства номенклатур были созданы общие "наборы упаковок". Когда пришло время прописывать вес и габариты, поняли что "общего" в наборах упаковок нет ничего, кроме наименования - вес и размеры упаковок отличались у каждого поставщика - поэтому стали создавать индивидуальные упаковки (то есть инд. наборы упаковок).
Поскольку использование упаковок в организации происходило постепенно и последовательно, представленные алгоритмы обрастали проверками, условиями и доп. механизмами - о чем по мере необходимости будет дополнительно написано.
1. Чтение объекта
Чтение упаковки и получение веса
&НаСервере
Процедура ЗаполнитьПоДокументуПриемкиСервер()
...
//так не пойдет:
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоНаименованию("кг", Истина, , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
//вот так пойдет:
ЕИ_Кг = ПолучитьБазовуюЕдиницуИзмерения("166", "KGM", "кг");
Если Выборка.Номенклатура.НаборУпаковок = Справочники.НаборыУпаковок.ИндивидуальныйДляНоменклатуры Тогда
//получаем вес-брутто из упаковки
Упак = ПолучитьУпаковку(Выборка.Номенклатура);
Если ЗначениеЗаполнено(Упак) Тогда
НоваяСтрока.Вес = Упак.Вес;
КонецЕсли;
НоваяСтрока.ВесЕдиницаИзмерения = ЕИ_Кг;
ИначеЕсли ЗначениеЗаполнено(Выборка.Номенклатура.НаборУпаковок) Тогда
//то есть это общий набор упаковок
//значит вес пока не задан
//НоваяСтрока.Вес = Выборка.Номенклатура.ВесЧислитель;
НоваяСтрока.ВесЕдиницаИзмерения = ЕИ_Кг;
ИначеЕсли НЕ Выборка.Номенклатура.ИспользоватьУпаковки
И Выборка.Номенклатура.ЕдиницаИзмерения.ТипИзмеряемойВеличины <> Перечисления.ТипыИзмеряемыхВеличин.Вес Тогда
//то есть упаковки не используются, но вес указывать нужно
//вес берем из карточки номенклатуры
НоваяСтрока.Вес = Выборка.Номенклатура.ВесЧислитель;
НоваяСтрока.ВесЕдиницаИзмерения = ЕИ_Кг;
Иначе
//остальные случаи: товар продается в "кг" или еще не изученные - не рассматриваем
КонецЕсли;
...
КонецПроцедуры
&НаСервере
Функция ПолучитьУпаковку(Номенклатура)
Упаковка = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = Ложь
| И УпаковкиЕдиницыИзмерения.Владелец = &Владелец
| И УпаковкиЕдиницыИзмерения.ТипУпаковки = Значение(Перечисление.ТипыУпаковокНоменклатуры.Конечная)
| И УпаковкиЕдиницыИзмерения.ВесоГабаритнаяУпаковка = Истина";
Запрос.УстановитьПараметр("Владелец", Номенклатура);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Количество()>1 ИЛИ Выборка.Количество()=0 Тогда
Возврат Неопределено;
КонецЕсли;
Если Выборка.Следующий() Тогда
Упаковка = Выборка.Ссылка;
КонецЕсли;
Возврат Упаковка;
КонецФункции
&НаСервере
Функция ПолучитьБазовуюЕдиницуИзмерения(КодЕИ, МеждСокр, НаименованиеЕИ)
//примеры:
//166, KGM, кг
//778, NMP, упак
//796, PCE, шт
Рез = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = ЛОЖЬ
| И УпаковкиЕдиницыИзмерения.Владелец = ЗНАЧЕНИЕ(Справочник.НаборыУпаковок.БазовыеЕдиницыИзмерения)
| И УпаковкиЕдиницыИзмерения.Код = &КодЕИ
| И УпаковкиЕдиницыИзмерения.МеждународноеСокращение = &МеждСокр
| И УпаковкиЕдиницыИзмерения.Наименование = &НаименованиеЕИ";
Запрос.УстановитьПараметр("КодЕИ", КодЕИ);
Запрос.УстановитьПараметр("МеждСокр", МеждСокр);
Запрос.УстановитьПараметр("НаименованиеЕИ", НаименованиеЕИ);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Рез = Выборка.Ссылка;
КонецЕсли;
Возврат Рез;
КонецФункции
Поясню ряд моментов:
1) Получение базовой ед.изм. лучше вынести в отдельную процедуру - и получать по трем параметрам, поскольку технически в базе можно создать несколько баз. ед. изм. с одинаковым наименованием, сокр. названием или кодами. Поэтому для минимизации ошибок следует искать баз. ед.изм по трем параметрам.
2) Если по номенклатуре не используется упаковка, то вес-брутто будем записывать и читать в/из поля Вес карточки номенклатуры, которое предназначено для хранения веса-нетто согласно типовым механизмам.
3) Со временем в компании понадобилось создавать дополнительные инд. упаковки по номенклатуре для сайта и маркетплейсов. Чтобы разделить инд. упаковки, созданные для хранения веса-брутто в рамках представленного проекта, был добавлен признак в карточку упаковки "ВесоГабаритнаяУпаковка" = Истина. Отбор по этому полю вы будете встречать в запросах.

2. Запись объекта
&НаСервере
Функция ЗаписатьВРегистрСервер()
...
//доработка+ запишем вес-брутто
Если Не ЕстьОшибки Тогда
МасНоменклатур = Новый Массив;
Для Каждого Стр Из Объект.ОсновныеЯчейки Цикл
Если Стр.Вес = 0 Тогда
Продолжить;
КонецЕсли;
Если МасНоменклатур.Найти(Стр.Номенклатура) <> Неопределено Тогда
//уже обработали
Продолжить;
КонецЕсли;
Если ЕстьОшибки Тогда
Возврат ЕстьОшибки;
КонецЕсли;
МасНоменклатур.Добавить(Стр.Номенклатура);
Если Стр.Номенклатура.НаборУпаковок = Справочники.НаборыУпаковок.ИндивидуальныйДляНоменклатуры Тогда
//по-умолчанию предполагаем, что вес указывается в "кг"
ЕстьОшибки = НайтиУпаковкуЗаписатьВес(Стр.Номенклатура, Стр.Вес);
ИначеЕсли ЗначениеЗаполнено(Стр.Номенклатура.НаборУпаковок) Тогда
//то есть имеется общий набор упаковок
ЕстьОшибки = СоздатьУпаковкуЗаписатьВес(Стр.Номенклатура, Стр.Вес);
ИначеЕсли НЕ Стр.Номенклатура.ИспользоватьУпаковки И Стр.Номенклатура.ЕдиницаИзмерения.ТипИзмеряемойВеличины <> Перечисления.ТипыИзмеряемыхВеличин.Вес Тогда
ЕстьОшибки = ЗаписатьВесВКарточкуНоменклатуры(Стр.Номенклатура, Стр.Вес);
Иначе
//ничего не записываем,
//поскольку или товар и так продается в "кг", или какая-то ошибка
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ЕстьОшибки;
КонецФункции
&НаСервере
Функция ПолучитьУпаковку(Номенклатура)
Упаковка = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = Ложь
| И УпаковкиЕдиницыИзмерения.Владелец = &Владелец
| И УпаковкиЕдиницыИзмерения.ТипУпаковки = Значение(Перечисление.ТипыУпаковокНоменклатуры.Конечная)
| И УпаковкиЕдиницыИзмерения.ВесоГабаритнаяУпаковка = Истина";
Запрос.УстановитьПараметр("Владелец", Номенклатура);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Количество()>1 ИЛИ Выборка.Количество()=0 Тогда
Возврат Неопределено;
КонецЕсли;
Если Выборка.Следующий() Тогда
Упаковка = Выборка.Ссылка;
КонецЕсли;
Возврат Упаковка;
КонецФункции
&НаСервере
Функция НайтиУпаковкуЗаписатьВес(Номенклатура, Вес)
ЕстьОшибки = Ложь; //возвращаемый параметр
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = Ложь
| И УпаковкиЕдиницыИзмерения.Владелец = &Владелец
| И УпаковкиЕдиницыИзмерения.ТипУпаковки = Значение(Перечисление.ТипыУпаковокНоменклатуры.Конечная)
| И УпаковкиЕдиницыИзмерения.ВесоГабаритнаяУпаковка = Истина";
Запрос.УстановитьПараметр("Владелец", Номенклатура);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Количество()>1 Тогда
//ничего не записываем
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ном-ра " + Номенклатура + " содержит несколько упаковок - непонятно для какой упаковки записывать вес-брутто");
КонецЕсли;
Если Выборка.Количество()=0 Тогда
//ничего не записываем
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ном-ра " + Номенклатура + " не содержит предустановленных упаковок");
КонецЕсли;
Если ЕстьОшибки Тогда
Возврат Истина;
КонецЕсли;
Если Выборка.Следующий() Тогда
Упаковка = Выборка.Ссылка.ПолучитьОбъект();
Упаковка.Вес = Вес;
//вес-брутто измеряем в "кг" - на всякий случай запишем
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоКоду("166");
ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоНаименованию("кг", Истина, , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
Упаковка.ВесЕдиницаИзмерения = ЕИ_Кг;
Упаковка.ВесоГабаритнаяУпаковка = Истина;
//не изменяем, не проверяем
//Упаковка.Наименование = Стр.Номенклатура.НаборУпаковок.Наименование;
//Упаковка.Числитель = 1;
//Упаковка.Знаменатель = 1;
//Упаковка.ТипИзмеряемойВеличины = Перечисления.ТипыИзмеряемыхВеличин.Упаковка;
//Упаковка.ТипУпаковки = Перечисления.ТипыУпаковокНоменклатуры.Конечная;
Попытка
//конструкцию ОбменДанными.Загрузка = Истина - не используем,
//поскольку ПередЗаписью происходит проверка реквизитов объекта
Упаковка.Записать();
Исключение
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("По ном-ре " + Номенклатура + " не удалось записать вес упаковки"
+ Символы.ПС + ИнформацияОбОшибке().Описание);
КонецПопытки;
КонецЕсли;
Возврат ЕстьОшибки;
КонецФункции
&НаСервере
Функция СоздатьУпаковкуЗаписатьВес(Номенклатура, Вес)
//создадим программно инд. упаковку только для той номенклатуры, у которой были заданы общие наборы упаковок
ЕстьОшибки = Ложь; //возвращаемый параметр
//Базовые единицы измерения
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоКоду("166");
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоНаименованию("кг", Истина, , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоРеквизиту("МеждународноеСокращение", "KGM", , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
//ЕИ_Упак = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоРеквизиту("МеждународноеСокращение", "NMP", , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
//ЕИ_Упак = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоКоду("778", Истина, , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
ЕИ_Кг = ПолучитьБазовуюЕдиницуИзмерения("166", "KGM", "кг");
ЕИ_Упак = ПолучитьБазовуюЕдиницуИзмерения("778", "NMP", "упак");
ЕИ_Шт = ПолучитьБазовуюЕдиницуИзмерения("796", "PCE", "шт");
//нужно получить коэффициент пересчета
УпаковкаОбщегоНабора = ПолучитьУпаковкуИзОбщегоНабора(Номенклатура.НаборУпаковок);
Если УпаковкаОбщегоНабора = Неопределено Тогда
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("По ном-ре " + Номенклатура + " не удалось создать индивидуальную упаковку из общего набора и записать вес-брутто");
Возврат ЕстьОшибки;
Иначе
Наименование = УпаковкаОбщегоНабора.Наименование;
Числитель = УпаковкаОбщегоНабора.Числитель;
КонецЕсли;
//общий набор упаковок не подходит для указания весо-габаритных характеристик,
// когда Владелец = Стр.Номенклатура.НаборУпаковок;
//создаем только индивидуальный набор упаковок
//вес-брутто измеряем в "кг" - на всякий случай запишем
//сначала воспользуемся наименованием общего набора упаковок (!) для создания упаковки
НоваяУпаковка = Справочники.УпаковкиЕдиницыИзмерения.СоздатьЭлемент();
НоваяУпаковка.Наименование = Наименование;
НоваяУпаковка.Владелец = Номенклатура;
НоваяУпаковка.ТипИзмеряемойВеличины = Перечисления.ТипыИзмеряемыхВеличин.Упаковка;
НоваяУпаковка.ТипУпаковки = Перечисления.ТипыУпаковокНоменклатуры.Конечная;
НоваяУпаковка.Вес = Вес;
НоваяУпаковка.ВесЕдиницаИзмерения = ЕИ_Кг;
НоваяУпаковка.ЕдиницаИзмерения = ?(Наименование = "шт", ЕИ_Шт, ЕИ_Упак);
НоваяУпаковка.Числитель = Числитель; //берем из упаковки общего набора
НоваяУпаковка.Знаменатель = 1;
НоваяУпаковка.ВесоГабаритнаяУпаковка = Истина;
НоменклатураОбъект = Номенклатура.ПолучитьОбъект();
НоменклатураОбъект.ИспользоватьУпаковки = Истина; //это нельзя изменять, иначе сломаем логику
НоменклатураОбъект.НаборУпаковок = Справочники.НаборыУпаковок.ИндивидуальныйДляНоменклатуры;
Попытка
НоменклатураОбъект.Записать();
НоваяУпаковка.Записать();
Исключение
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("По ном-ре " + Номенклатура + " не удалось записать вес-брутто и/или создать индивидуальную упаковку"
+ Символы.ПС + ИнформацияОбОшибке().Описание);
КонецПопытки;
Возврат ЕстьОшибки;
КонецФункции
&НаСервере
Функция ПолучитьБазовуюЕдиницуИзмерения(КодЕИ, МеждСокр, НаименованиеЕИ)
//примеры:
//166, KGM, кг
//778, NMP, упак
Рез = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = ЛОЖЬ
| И УпаковкиЕдиницыИзмерения.Владелец = ЗНАЧЕНИЕ(Справочник.НаборыУпаковок.БазовыеЕдиницыИзмерения)
| И УпаковкиЕдиницыИзмерения.Код = &КодЕИ
| И УпаковкиЕдиницыИзмерения.МеждународноеСокращение = &МеждСокр
| И УпаковкиЕдиницыИзмерения.Наименование = &НаименованиеЕИ";
Запрос.УстановитьПараметр("КодЕИ", КодЕИ);
Запрос.УстановитьПараметр("МеждСокр", МеждСокр);
Запрос.УстановитьПараметр("НаименованиеЕИ", НаименованиеЕИ);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Рез = Выборка.Ссылка;
КонецЕсли;
Возврат Рез;
КонецФункции
&НаСервере
Функция ПолучитьУпаковкуИзОбщегоНабора(ОбщийНабор)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка,
| УпаковкиЕдиницыИзмерения.Наименование КАК Наименование,
| УпаковкиЕдиницыИзмерения.Числитель КАК Числитель
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.Владелец = &ОбщийНабор
| И УпаковкиЕдиницыИзмерения.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("ОбщийНабор", ОбщийНабор);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Рез = Неопределено;
Если Выборка.Следующий() Тогда
Рез = Новый Структура("Наименование, Числитель");
Рез.Вставить("Наименование", Выборка.Наименование);
Рез.Вставить("Числитель", Выборка.Числитель);
КонецЕсли;
Возврат Рез;
КонецФункции
&НаСервере
Функция ЗаписатьВесВКарточкуНоменклатуры(Номенклатура, Вес)
ЕстьОшибки = Ложь; //возвращаемый параметр
//вес-брутто измеряем в "кг" - на всякий случай запишем
//ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоКоду("166");
ЕИ_Кг = Справочники.УпаковкиЕдиницыИзмерения.НайтиПоНаименованию("кг", Истина, , Справочники.НаборыУпаковок.БазовыеЕдиницыИзмерения);
//вес-нетто - используем не для всей номенклатуры, а только для той, по которым упаковки не используются
//(ни общие наборы, ни индивидуальные)
НоменклатураОбъект = Номенклатура.ПолучитьОбъект();
НоменклатураОбъект.ВесИспользовать = Истина;
НоменклатураОбъект.ВесЧислитель = Вес;
НоменклатураОбъект.ВесЗнаменатель = 1;
НоменклатураОбъект.ВесЕдиницаИзмерения = ЕИ_Кг; //Кг
Попытка
НоменклатураОбъект.Записать();
Исключение
ЕстьОшибки = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("По ном-ре " + Номенклатура + " не удалось записать вес в карточку товара"
+ Символы.ПС + ИнформацияОбОшибке().Описание);
КонецПопытки;
Возврат ЕстьОшибки;
КонецФункции
Комментарии есть в коде, дополнительно отвечу на вопросы в сообщениях к статье.
3. Разделение по упаковкам
При создании расходного ордера на товар вызывается метод разделения кол-ва товаров по упаковкам. Метод интересный и удобный в том плане, если у вас отгружается 300шт, и задана упаковка "упак(10шт)", то программа пересчитает кол-во упаковок = 30 упак(10шт).
Чем же плох метод: тем, что если у вас эксперименты с упаковками и что-то неправильно завели - коэффициент пересчета, базовую единицу измерения, или же завели несколько упаковок для разных сценариев работы, тогда все эти упаковки будут использованы для распределения и разделения исходного количества товара на разные строки с разными упаковками. К примеру менеджер оформил 310 штук товара (см. верхний абзац), тогда программа в расходнике соберет товар в двух строках - в первой будет =30 упак(10шт), во второй строке =10шт остаток. С таким алгоритмом всегда будет "хвостик" и с таким алгоритмом все ошибки и эксперименты учета всегда будут видны в расходном ордере.
Для нашей задачи я сначала отключил автораспределение через процедуру ОбработкаЗаполнения() модуля документа Расходного ордера - просто закомментировал этот участок кода.
Распределение кол-ва по упаковкам
Если Не СкладыСервер.ИспользоватьАдресноеХранение(Склад, Помещение, ДатаОтгрузки)
И ПолучитьФункциональнуюОпцию("ИспользоватьУпаковкиНоменклатуры") Тогда
Документы.РасходныйОрдерНаТовары.РазбитьПоУпаковкамСправочно(ЭтотОбъект);
КонецЕсли;
Автораспределение срабатывает, если у вас ведется учет упаковок и не используется АдресноеХранение (см. код). Замечу, что сначала мы внедряли именно адресное хранение и с этим поведением расходного ордера не сталкивались. Когда изменили план внедрения и перешли на внедрение справочного указания ячеек, механизм неожиданно для нас сработал автоматически.
Распределение по упаковкам можно также вызвать интерактивно в форме расходника в разделе команд "Заполнить" - по упаковкам (справочно) или по распоряжениям.
Когда мы стали добавлять новые упаковки для маркетплейсов, пришлось вернуть данный участок кода. Но тогда пришлось добавить отбор в процедуру РазбитьПоУпаковкамСправочно(Объект) модуля менеджера Расходного ордера - отбор по признаку ВесоГабаритнаяУпаковка (см. рис.3)

4. Просмотр журнала регистрации
Объект метаданных справочника упаковок имеет несколько форм выбора: для единицы измерения, для упаковок, для выбора из документа и т.д. (см. рис.4). Поэтому нельзя в журнале регистрации и в других нетиповых формах выбрать именно упаковку - всегда будет открываться по умолчанию форма выбора единиц измерения.

Для просмотра журнала регистрации по конкретной упаковке можно использовать программное открытие. Поиск упаковки я произвел по наличию "звездочки" в названии.
Программное открытие журнала регистрации по упаковке
&НаКлиенте
Процедура ОткрытьЖР(Команда)
Упаковка = ПолучитьУпаковкуИзОбщегоНабора();
// Отбор - Структура:
// Пользователь - Строка
// - СписокЗначений - имя или список пользователей информационной базы.
// СобытиеЖурналаРегистрации - Строка, Массив - идентификатор события.
// ДатаНачала - Дата - начало интервала отображаемых событий.
// ДатаОкончания - Дата - конец интервала отображаемых событий.
// Данные - Произвольный - данные любого типа.
// Сеанс - СписокЗначений - список выбираемых сеансов.
// Уровень - Строка, Массив - представление уровня важности события журнала регистрации.
// ИмяПриложения - Массив - массив идентификаторов приложения.
Отбор = Новый Структура("Данные");
Отбор.Вставить("Данные", Упаковка);
//Отбор.Пользователь = "Администратор";
//Отбор.ДатаНачала = НачалоДня(ТекущаяДата());
//Отбор.ДатаОкончания = КонецДня(ТекущаяДата());
//Отбор.Уровень = "Ошибка";
//Отбор.СобытиеЖурналаРегистрации = "Событие тестовое строкой1";
ЖурналРегистрацииКлиент.ОткрытьЖурналРегистрации(Отбор, ЭтаФорма);
КонецПроцедуры
&НаСервере
Функция ПолучитьУпаковкуИзОбщегоНабора()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка,
| УпаковкиЕдиницыИзмерения.Наименование КАК Наименование,
| УпаковкиЕдиницыИзмерения.Числитель КАК Числитель
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| УпаковкиЕдиницыИзмерения.ПометкаУдаления = ИСТИНА
| И УпаковкиЕдиницыИзмерения.Наименование ПОДОБНО ""*%""";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Рез = Неопределено;
Если Выборка.Следующий() Тогда
Рез = Выборка.Ссылка;
КонецЕсли;
Возврат Рез;
КонецФункции
5. Запросы в консоли
1) первый запрос я использовал для вывода общей информации по номенклатуре, единицам измерения, упаковкам.
Общий запрос по номенклатуре
ВЫБРАТЬ
Номенклатура.ИспользоватьУпаковки КАК Упак,
Номенклатура.ЕдиницаИзмерения.ТипИзмеряемойВеличины КАК ТипВеличины,
Номенклатура.ЕдиницаИзмерения.ТипУпаковки КАК ТипУпаковки,
Номенклатура.ЕдиницаИзмерения КАК ЕИ,
Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.ЕдиницаИзмерения.Вес КАК Вес,
Номенклатура.ЕдиницаИзмерения.ВесЕдиницаИзмерения КАК ЕИвес,
Номенклатура.НаборУпаковок КАК НаборУпаковок
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.ПометкаУдаления = ЛОЖЬ
И Номенклатура.ЭтоГруппа = ЛОЖЬ
И Номенклатура.Ссылка = &Ссылка
УПОРЯДОЧИТЬ ПО
Упак,
ТипВеличины,
ТипУпаковки,
ЕИ,
ВидНоменклатуры
ИТОГИ ПО
Упак,
ТипВеличины,
ТипУпаковки,
ЕИ
2) второй запрос - общий по справочнику единиц измерения - в одном списке намешано все: единицы измерения, упаковки, базовые единицы измерения.
Общий запрос по справочнику единиц измерения
ВЫБРАТЬ
УпаковкиЕдиницыИзмерения.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка,
УпаковкиЕдиницыИзмерения.Наименование КАК Наименование,
УпаковкиЕдиницыИзмерения.НаименованиеПолное КАК НаименованиеПолное,
УпаковкиЕдиницыИзмерения.МеждународноеСокращение КАК МеждународноеСокращение,
УпаковкиЕдиницыИзмерения.ТипИзмеряемойВеличины КАК ТипИзмеряемойВеличины,
УпаковкиЕдиницыИзмерения.ТипУпаковки КАК ТипУпаковки,
УпаковкиЕдиницыИзмерения.Числитель КАК Числитель,
УпаковкиЕдиницыИзмерения.Знаменатель КАК Знаменатель
ИЗ
Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
ГДЕ
УпаковкиЕдиницыИзмерения.ПометкаУдаления = ЛОЖЬ
УПОРЯДОЧИТЬ ПО
ЕдиницаИзмерения
ИТОГИ ПО
ЕдиницаИзмерения
3) третий запрос - общий по упаковкам общих наборов
Общий запрос по упаковкам "наборов упаковок"
ВЫБРАТЬ
УпаковкиЕдиницыИзмерения.Владелец КАК Владелец,
УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка,
УпаковкиЕдиницыИзмерения.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
УпаковкиЕдиницыИзмерения.Числитель КАК Числитель,
ВЫРАЗИТЬ(УпаковкиЕдиницыИзмерения.Владелец КАК Справочник.НаборыУпаковок).ЕдиницаИзмерения КАК ЕИНабора
ИЗ
Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
ГДЕ
УпаковкиЕдиницыИзмерения.Владелец ССЫЛКА Справочник.НаборыУпаковок
И УпаковкиЕдиницыИзмерения.ПометкаУдаления = ЛОЖЬ
И УпаковкиЕдиницыИзмерения.Владелец <> ЗНАЧЕНИЕ(Справочник.НаборыУпаковок.БазовыеЕдиницыИзмерения)
ИТОГИ ПО
ЕИНабора
4) четвертый запрос - по остаткам на складе по номенклатуре, связанной с наборами упаковок
Общий запрос по остаткам номенклатуры, связанных с наборами упаковок
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура.Ссылка КАК НоменклатураСсылка,
ТоварыНаСкладахОстатки.Номенклатура.НаборУпаковок КАК НоменклатураНаборУпаковок,
ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток,
ТоварыНаСкладахОстатки.Номенклатура.Код КАК НоменклатураКод,
ТоварыНаСкладахОстатки.Склад КАК Склад
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
ГДЕ
НЕ ТоварыНаСкладахОстатки.Номенклатура.НаборУпаковок.Предопределенный
И ТоварыНаСкладахОстатки.ВНаличииОстаток > 0
И ТоварыНаСкладахОстатки.Склад = &Склад
На этом все.
Всем добра! :)
С пользой для клиентов, RustIG