Как заполнить табличную часть документа с помощью СКД с пользовательскими отборами?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в учетных системах возникает задача заполнения табличной части документа списком элементов (например, контрагентов, номенклатуры или сотрудников) по произвольным условиям. При этом отборы не должны быть жестко зашиты в коде — пользователю необходимо предоставить удобный интерфейс для самостоятельного указания критериев отбора. Рассмотрим основные и наиболее эффективные способы реализации такой функциональности на управляемых формах 1С 8.3.

Способ 1. Встраивание настроек компоновщика СКД напрямую в форму документа

Разберем вариант, когда пользователь настраивает условия фильтрации прямо на форме документа без открытия дополнительных окон. Для этого используется механизм пользовательских настроек компоновщика СКД.

Выполним следующую последовательность шагов:

  1. Создадим схему компоновки данных (в макете документа или общего макета), где в качестве набора данных настроим запрос к необходимому справочнику или регистру. В выбранных полях укажем реквизиты, имена которых точно совпадают с именами колонок табличной части документа.
  2. В реквизиты управляемой формы документа добавим реквизит КомпоновщикНастроек с типом КомпоновщикНастроекКомпоновкиДанных.
  3. Перетащим на форму таблицу, связав ее путь к данным с КомпоновщикНастроек.Настройки.Отбор (или КомпоновщикНастроек.ПользовательскиеНастройки).

При открытии или инициализации формы необходимо инициализировать доступные настройки компоновщика:


&НаСервере
Процедура ИнициализироватьКомпоновщикНаСервере()
    
    СхемаСКД = Документы.НашДокумент.ПолучитьМакет("СхемаВыгрузки");
    ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД);
    
    КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
    КомпоновщикНастроек.ЗагрузитьНастройки(СхемаСКД.НастройкиПоУмолчанию);
    
КонецПроцедуры

Далее напишем процедуру заполнения табличной части, которая программно исполняет компоновку и выводит результат напрямую в табличную часть документа:


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

Способ 2. Вызов внешней формы/обработки подбора с возвратом результата через ОписаниеОповещения

Если интерфейс формы документа перегружать таблицами отборов нежелательно, вынесем настройку условий в отдельную обработку или форму отчета. Вызовем форму асинхронно, заблокируем окно документа, а после закрытия получим результат.

Посмотрим на пример клиентского кода вызова вспомогательной формы:


&НаКлиенте
Процедура КомандаЗаполнить(Команда)
    
    Оповещение = Новый ОписаниеОповещения("ОбработатьРезультатЗаполнения", ЭтотОбъект);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Организация", Объект.Организация);
    
    ОткрытьФорму(
        "Обработка.ПодборКонтрагентов.Форма.Форма",
        ПараметрыФормы,
        ЭтотОбъект,
        ,
        ,
        ,
        Оповещение,
        РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
    );
    
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьРезультатЗаполнения(Результат, ДополнительныеПараметры) Экспорт
    
    Если Результат = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Передаем полученную таблицу значений на сервер для загрузки
    ЗагрузитьДанныеВТабличнуюЧастьНаСервере(Результат);
    
КонецПроцедуры

В форме обработки подбора после применения настроек компоновщика формируется результат (например, таблица значений) и передается в метод закрытия формы:


&НаКлиенте
Процедура ВыполнитьПереносВДокумент(Команда)
    
    ТаблицаРезультата = СформироватьТаблицуНаСервере();
    Закрыть(ТаблицаРезультата);
    
КонецПроцедуры

На стороне документа в серверной процедуре загрузим полученную таблицу значений:


&НаСервере
Процедура ЗагрузитьДанныеВТабличнуюЧастьНаСервере(ТаблицаДанных)
    
    Объект.Контрагенты.Загрузить(ТаблицаДанных);
    
КонецПроцедуры

Важные нюансы реализации

  1. Соответствие имен колонок: чтобы методы ПроцессорВывода.Вывести() или Загрузить() корректно сопоставили данные, имена полей в схеме СКД должны в точности дублировать имена реквизитов табличной части документа.
  2. Контекст выполнения: все операции со СхемаКомпоновкиДанных, ПроцессорКомпоновкиДанных и ТаблицаЗначений допустимы только в контексте &НаСервере или в серверных модулях.
  3. Передача параметров: если в выборке должны учитываться реквизиты шапки текущего документа (например, организация или дата), их следует передавать в КомпоновщикНастроек.Настройки.ПараметрыДанных перед созданием макета компоновки.
← На главную