Стандартный подбор в любой документ
2025-08-19
Конфигурация "Комплексная автоматизация".
Задача - добавить подбор товаров в документ списания, такой же как в приобретении товаров.
На самом деле странно, почему-бы не внедрить подбор во все документы где используется табличная часть с товарами? - это же очень удобно.
Получается есть обделенные документы, которые по задумке разработчиков не нуждаются в подборе, а заполняются исключительно другими способами.
Предлагаю добавить стандартный подбор не только в списание, но и в документ оприходования товаров. Конечно же задача будет решена через создание расширения конфигурации.
Для начала заметим, что подбор товаров - это отдельная обработка, а не какая-то общая форма, и есть несколько видов подборов, нас же будет устраивать подбор в документ закупки.
Логика работы такая - из документа открывается форма обработки с параметрами, затем в обработке идет подбор в таблицу, которая при нажатии на кнопку "перенести в документ", помещает таблицу в хранилище и вызывает обработчик "ОбработкаВыбора", который и заполняет табличную часть.
За основу будем брать код из документа приобретение товаров и услуг.
Первым делом - добавляем форму документа, в который собираемся добавить подбор, в расширение.
Добавляем команду "Подобрать товары", помещаем ее в группу и добавляем иконку для красоты.

Код самой команды можно взять как раз из документа приобретения, немножко его модифицируем(главное открыть форму подбора).

&НаКлиенте Процедура Подб_ПодборатьТоварыВместо(Команда) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Документ", Объект.Ссылка); ПараметрыФормы.Вставить("Склад", Объект.Склад); ПараметрыФормы.Вставить("Валюта", Объект.Валюта); ПараметрыФормы.Вставить("Дата", Объект.Дата); ПараметрыФормы.Вставить("РежимПодбораИспользоватьСкладыВТабличнойЧасти", Истина); ПараметрыФормы.Вставить("РежимПодбораИсключитьГруппыДоступныеВЗаказах", Истина); ПараметрыФормы.Вставить("ОтборПоТипуНоменклатуры", Ложь); ОткрытьФорму("Обработка.ПодборТоваровВДокументЗакупки.Форма", ПараметрыФормы, ЭтаФорма, УникальныйИдентификатор); КонецПроцедуры
После закрытия окна подбора, вызывается стандартное событие "обработка выбора". Такая процедура, стандартно, уже имеется. Поэтому добавляем ее в расширение, с аннотацией "Перед", и сразу же делаем процедуру на сервере:
&НаКлиенте Процедура Подб_ОбработкаВыбораПеред(ВыбранноеЗначение, ИсточникВыбора) Если ИсточникВыбора.ИмяФормы = "Обработка.ПодборТоваровВДокументЗакупки.Форма.Форма" Тогда ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение); КонецЕсли; КонецПроцедуры &НаСервере Процедура ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение) ТаблицаТоваров = ПолучитьИзВременногоХранилища(ВыбранноеЗначение.АдресТоваровВХранилище); Для каждого СтрокаТовара Из ТаблицаТоваров Цикл ТекущаяСтрока = Объект.Товары.Добавить(); ЗаполнитьЗначенияСвойств(ТекущаяСтрока, СтрокаТовара); //Дополнительные действия которые необязательны, взяты из ТоварыНоменклатураПриИзменении СтруктураДействий = Новый Структура; СтруктураДействий.Вставить("ПроверитьХарактеристикуПоВладельцу", ТекущаяСтрока.Характеристика); СтруктураДействий.Вставить("ЗаполнитьЦенуПродажи", Новый Структура("Дата, Валюта, ВидЦены", Объект.Дата, Объект.Валюта, Объект.ВидЦены)); СтруктураДействий.Вставить("ПересчитатьСумму", "Количество"); СтруктураДействий.Вставить("ЗаполнитьПризнакВедетсяУчетПоГТД", Новый Структура("Номенклатура", "ВедетсяУчетПоГТД")); СтруктураДействий.Вставить("ЗаполнитьСтрануПроисхожденияНоменклатуры", ОбработкаТабличнойЧастиКлиентСервер.ПараметрыЗаполненияСтраныПроисхождения()); СтруктураДействий.Вставить("ЗаполнитьПризнакАртикул", Новый Структура("Номенклатура", "Артикул")); СтруктураДействий.Вставить("ЗаполнитьПризнакТипНоменклатуры", Новый Структура("Номенклатура", "ТипНоменклатуры")); СтруктураДействий.Вставить("ПроверитьСериюРассчитатьСтатус", Новый Структура("Склад, ПараметрыУказанияСерий", Объект.Склад, ПараметрыУказанияСерий)); СтруктураДействий.Вставить("ПроверитьЗаполнитьНазначение"); СтруктураДействий.Вставить("НоменклатураПриИзмененииПереопределяемый", Новый Структура("ИмяФормы, ИмяТабличнойЧасти", ЭтаФорма.ИмяФормы, "Товары")); УчетПрослеживаемыхТоваровКлиентСерверЛокализация.ДополнитьОписаниеНастроекЗаполненияСлужебныхРеквизитовТабличнойЧасти(СтруктураДействий); ОбработкаТабличнойЧастиКлиентСерверЛокализация.ДополнитьСтруктуруДействийПриИзмененииЭлемента(ЭтотОбъект, "Номенклатура", СтруктураДействий); КэшированныеЗначения = ОбработкаТабличнойЧастиКлиентСервер.ПолучитьСтруктуруКэшируемыеЗначения(); ОбработкаТабличнойЧастиСервер.ОбработатьСтрокуТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения); КонецЦикла; КонецПроцедуры
Процедура ОбработкаВыбораПодборНаСервере это всего лишь модифицированная процедура ТоварыНоменклатураПриИзменении, которая выполняется для строки при изменении номенклатуры. В нашей же процедуре, строки обрабатываются в цикле.

Вот так с помощью трех процедур можно легко добавить подбор в документ.
Теперь предлагаю добавить подбор в документ списания недостачь товаров. Действия не будут отличаться от предыдущих, поэтому просто приведу код процедур.
&НаКлиенте Процедура Подб_ПодобратьТоварыВместо(Команда) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Документ", Объект.Ссылка); ПараметрыФормы.Вставить("Склад", Объект.Склад); ПараметрыФормы.Вставить("Валюта", Объект.Валюта); ПараметрыФормы.Вставить("Дата", Объект.Дата); ПараметрыФормы.Вставить("РежимПодбораИспользоватьСкладыВТабличнойЧасти", Истина); ПараметрыФормы.Вставить("РежимПодбораИсключитьГруппыДоступныеВЗаказах", Истина); ПараметрыФормы.Вставить("ОтборПоТипуНоменклатуры", Ложь); ОткрытьФорму("Обработка.ПодборТоваровВДокументЗакупки.Форма", ПараметрыФормы, ЭтаФорма, УникальныйИдентификатор); КонецПроцедуры &НаКлиенте Процедура Подб_ОбработкаВыбораПеред(ВыбранноеЗначение, ИсточникВыбора) Если ИсточникВыбора.ИмяФормы = "Обработка.ПодборТоваровВДокументЗакупки.Форма.Форма" Тогда ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение); КонецЕсли; КонецПроцедуры &НаСервере Процедура ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение) ТаблицаТоваров = ПолучитьИзВременногоХранилища(ВыбранноеЗначение.АдресТоваровВХранилище); Для каждого СтрокаТовара Из ТаблицаТоваров Цикл ТекущаяСтрока = Объект.Товары.Добавить(); ЗаполнитьЗначенияСвойств(ТекущаяСтрока, СтрокаТовара); СтруктураДействий = Новый Структура; СтруктураДействий.Вставить("ПроверитьХарактеристикуПоВладельцу", ТекущаяСтрока.Характеристика); СтруктураДействий.Вставить("ЗаполнитьПризнакАртикул", Новый Структура("Номенклатура", "Артикул")); СтруктураДействий.Вставить("ПроверитьСериюРассчитатьСтатус", Новый Структура("Склад, ПараметрыУказанияСерий", Объект.Склад, ПараметрыУказанияСерий)); СтруктураДействий.Вставить("ЗаполнитьПризнакТипНоменклатуры", Новый Структура("Номенклатура", "ТипНоменклатуры")); СтруктураДействий.Вставить("НоменклатураПриИзмененииПереопределяемый", Новый Структура("ИмяФормы, ИмяТабличнойЧасти", ЭтаФорма.ИмяФормы, "Товары")); КэшированныеЗначения = ОбработкаТабличнойЧастиКлиентСервер.ПолучитьСтруктуруКэшируемыеЗначения(); ОбработкаТабличнойЧастиСервер.ОбработатьСтрокуТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения); КонецЦикла; КонецПроцедуры
Здесь код немного поменьше, потому что действий с измененной строкой необходимо сделать меньше чем в оприходовании.
