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