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