Как передать параметр типа Список значений в СКД при использовании внешнего набора данных?

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

При разработке сложных отчетов на системе компоновки данных (СКД) часто возникают ситуации, когда стандартных запросов недостаточно. В таких случаях программисты прибегают к формированию внешнего набора данных (обычно это ТаблицаЗначений), который затем передается в СКД. Однако на этом этапе возникает важный вопрос: как получить значения параметров, которые пользователь указал на форме (например, СписокЗначений со ссылками на справочник), чтобы использовать их при формировании этой самой таблицы в программном коде? Разберем эту задачу подробно и по шагам.

Шаг 1. Настройка параметров в схеме СКД

Прежде чем пытаться получить значение параметра в коде, необходимо правильно подготовить саму схему компоновки. Рассмотрим основные настройки:

  1. Откроем закладку Параметры в конструкторе СКД.
  2. Добавим новый параметр (например, с именем Подразделения).
  3. В колонке Тип укажем нужный тип ссылки (например, СправочникСсылка.Подразделения).
  4. Критически важно: установим галочку в колонке Доступен список значений. Если этого не сделать, 1С будет ожидать одиночное значение, и попытка передать или получить список приведет к ошибкам или пустой ссылке.
  5. В колонке Ограничение доступности снимем галочку, чтобы пользователь мог видеть этот параметр.
  6. В настройках параметра нажмем на кнопку Свойства пользовательских настроек (значок с ключом) и установим флаг Включать в пользовательские настройки. Это позволит пользователю задавать список непосредственно на форме отчета.

Шаг 2. Почему стандартный поиск параметра может не работать?

Проанализируем типичную ситуацию, с которой сталкиваются разработчики. Часто при попытке получить значение через КомпоновщикНастроек.Настройки.ПараметрыДанных метод возвращает Неопределено или пустое значение, хотя на форме данные заполнены.

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

Шаг 3. Программное получение параметра в модуле отчета

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

Проанализируем следующий алгоритм работы:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Отключаем стандартный вывод, так как мы сами будем формировать процессор
    СтандартнаяОбработка = Ложь;
    
    // 2. Получаем актуальные настройки (совмещаем основные и пользовательские)
    // Это самый надежный способ получить значения параметров одной командой
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // 3. Ищем наш параметр по имени
    ПараметрОбъект = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Подразделения"));
    
    ВыбранныеПодразделения = Неопределено;
    Если ПараметрОбъект <> Неопределено И ПараметрОбъект.Использование Тогда
        ВыбранныеПодразделения = ПараметрОбъект.Значение; // Здесь будет наш СписокЗначений
    КонецЕсли;

    // Проверим, заполнено ли значение
    Если ЗначениеЗаполнено(ВыбранныеПодразделения) Тогда
        // Используем ВыбранныеПодразделения для фильтрации в запросе при формировании ТЗ
    КонецЕсли;
    
    // Далее следует логика формирования ТЗ и инициализация процессора компоновки...
    
КонецПроцедуры

Шаг 4. Альтернативный метод поиска в пользовательских настройках

Если по каким-то причинам метод ПолучитьНастройки() не подходит, мы можем перебрать коллекцию пользовательских настроек вручную. Это может быть полезно, если нужно найти значение не только параметра, но и конкретного отбора. Рассмотрим пример функции, предложенный участниками форума:


Функция ПолучитьЗначениеПараметраПоИмени(ПользовательскиеНастройки, ИмяПараметра) Экспорт
    
    ПолеПараметра = Новый ПараметрКомпоновкиДанных(ИмяПараметра);
    
    Для Каждого Элемент Из ПользовательскиеНастройки.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
            Если Элемент.Параметр = ПолеПараметра Тогда
                Возврат Элемент.Значение;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Неопределено;
    
КонецФункции

Важный нюанс: поиск по индексу (например, Элементы[0]), который упоминался в обсуждении, крайне не рекомендуется. При добавлении любого нового отбора или параметра на форму индексы сместятся, и ваш код начнет получать неверные данные.

Шаг 5. Формирование ТЗ и передача в СКД

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


// Предположим, ТЗ_Результат уже сформирована на основе ВыбранныеПодразделения

// Инициализируем макет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);

// Передаем ТЗ во внешний набор данных
// Ключ структуры "ВнешняяТЗ" должен совпадать с именем объекта в схеме СКД
ВнешниеДанные = Новый Структура("ВнешняяТЗ", ТЗ_Результат);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеДанные, ДанныеРасшифровки);

// Выводим результат в табличный документ
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Резюме и советы

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

Используя метод ПолучитьНастройки(), вы значительно упрощаете себе жизнь, так как 1С берет на себя всю работу по объединению настроек схемы и тех изменений, которые внес пользователь "на лету". Это позволяет сосредоточиться на логике формирования сложной таблицы значений, не отвлекаясь на низкоуровневый разбор коллекций компоновщика.

← На главную