При разработке отчетов на Системе Компоновки Данных (СКД) часто возникает задача — предоставить пользователю возможность фильтровать данные по счетам, которые он сам создал в режиме «1С:Предприятие». Стандартный подход, когда разработчик задает все параметры в Конфигураторе, здесь не работает, так как в режиме разработки этих счетов еще не существует. Попытка настроить отчет в пользовательском режиме и перенести схему в конфигуратор может привести к потере ссылок и неработающему отчету. Давайте подробно разберем, как правильно решить эту задачу.
Проанализируем исходную ситуацию. У нас есть запрос к виртуальной таблице регистра бухгалтерии, где данные должны фильтроваться по списку счетов, переданному через параметр &МоиСчета.
ВЫБРАТЬ
ХозрасчетныйОстаткиИОбороты.Счет,
ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Справочник.Номенклатура),
ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Справочник.Склады),
СУММА(ХозрасчетныйОстаткиИОбороты.СуммаНачальныйОстатокДт),
...
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(,,,,, Счет В (&МоиСчета), ,) КАК ХозрасчетныйОстаткиИОбороты
Основная проблема в том, что в параметр &МоиСчета нужно передать ссылки на счета (например, забалансовый счет «020»), созданные пользователем. Рассмотрим несколько способов решения этой задачи, от самого простого до наиболее надежного.
Этот метод основан на визуальной настройке отчета. Идея проста: сделать всю работу в том режиме, где нужные данные (счета) доступны, а затем перенести результат в конфигурацию.
Разберем по шагам:
&МоиСчета.schema.xml).Возможные проблемы и их причина:
После загрузки схемы в конфигуратор вы можете столкнуться с тем, что значение параметра &МоиСчета превратилось в набор непонятных символов, похожих на c0b31f4c-346d-11ef-a8f6-3.... Это внутренние уникальные идентификаторы (GUID) выбранных вами счетов.
Причина в том, что Конфигуратор не имеет доступа к данным, созданным в режиме «Предприятие». Он «видит» только предопределенные объекты. Когда вы загружаете схему, конфигуратор не может сопоставить эти GUID с конкретными элементами плана счетов и «теряет» тип данных. В результате запрос выполняется с некорректным параметром и не возвращает данные.
Важный момент: на более современных версиях платформы 1С (например, 8.3.15 и выше) этот механизм был улучшен. Платформа стала лучше справляться с переносом таких настроек, и этот способ может сработать. Однако он остается не самым надежным, так как зависит от версии платформы и может приводить к трудно диагностируемым ошибкам.
Это самый надежный и гибкий способ, который не зависит от версии платформы и ручного переноса схем. Суть метода — программно найти нужные счета и установить их в качестве значения параметра перед формированием отчета.
Код для установки параметра лучше всего размещать в обработчике события ПриСозданииНаСервере формы отчета. Это гарантирует, что при открытии отчета пользователь сразу увидит предзаполненные значения.
Посмотрим на пример:
Предположим, нам нужно по умолчанию подставлять в параметр все счета, код которых начинается с «020».
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создаем массив для хранения счетов
МассивСчетов = Новый Массив;
// Ищем нужные счета с помощью запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Хозрасчетный.Ссылка
|ИЗ
| ПланСчетов.Хозрасчетный КАК Хозрасчетный
|ГДЕ
| Хозрасчетный.Код ПОДОБНО &КодСчета";
Запрос.УстановитьПараметр("КодСчета", "020%");
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
МассивСчетов.Добавить(Выборка.Ссылка);
КонецЦикла;
КонецЕсли;
// Если нашли нужные счета, установим их в параметр отчета
Если МассивСчетов.Количество() > 0 Тогда
// Получаем текущие настройки отчета
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Находим наш параметр в настройках
ЭлементПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МоиСчета"));
Если ЭлементПараметра <> Неопределено Тогда
// Устанавливаем значение и включаем использование параметра
ЭлементПараметра.Значение = Новый СписокЗначений;
ЭлементПараметра.Значение.ЗагрузитьЗначения(МассивСчетов);
ЭлементПараметра.Использование = Истина;
// Загружаем измененные настройки обратно в компоновщик
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Что делает этот код:
МассивСчетов.Хозрасчетный для поиска всех счетов, код которых начинается с «020».КомпоновщикНастроек.СписокЗначений, созданный из нашего массива. Важно: для условия В (&ИмяПараметра) значением параметра должен быть СписокЗначений или Массив.Использование = Истина).Этот подход полностью решает проблему, так как вся логика выполняется на сервере в момент работы с отчетом, где есть доступ ко всем данным. При необходимости упростить написание такого кода можно использовать модуль-обёртку над объектной моделью СКД.
Этот способ похож на предыдущий, но код выполняется на самом последнем этапе — непосредственно перед тем, как СКД начнет формировать результат. Это полезно, когда значение параметра зависит от других настроек, которые пользователь мог изменить перед нажатием кнопки «Сформировать».
В модуле отчета нужно создать процедуру-обработчик этого события.
&НаСервере
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Берем управление на себя
// Здесь можно разместить код для поиска счетов и установки параметра,
// аналогичный тому, что в способе 2.
// Единственное отличие - мы работаем с объектом НастройкиКомпоновкиДанных,
// который передается в этот обработчик.
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// ... (код поиска счетов и заполнения массива/списка) ...
ЭлементПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МоиСчета"));
Если ЭлементПараметра <> Неопределено Тогда
ЭлементПараметра.Значение = МойСписокСчетов; // Заполненный ранее список
ЭлементПараметра.Использование = Истина;
КонецЕсли;
// Выполняем компоновку с измененными настройками
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,, ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Этот метод более сложен, так как требует ручного вызова всего процесса компоновки макета и вывода результата. Он является мощным инструментом для сложных случаев, но для простой установки параметра обычно достаточно способа №2.
Подводя итог, для работы с пользовательскими данными в параметрах СКД:
ПриСозданииНаСервере. Это самый чистый, надежный и рекомендуемый подход. Он обеспечивает предсказуемое поведение отчета и легко поддерживается.ПриКомпоновкеРезультата.Выбрав программный способ, вы создадите отчет, который будет корректно работать вне зависимости от того, какие счета и когда создадут пользователи системы.