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