При разработке отчетов в конфигурациях «1С:Комплексная автоматизация 2», «1С:ERP Управление предприятием 2» или «1С:Зарплата и управление персоналом 3» программисты часто сталкиваются с необходимостью получения кадровых данных сотрудников. Для этих целей в системе предусмотрен мощный программный интерфейс — функция КадровыйУчет.СоздатьВТСотрудникиОрганизации(). Однако при попытке вывести полученные результаты в отчет на СКД (Системе компоновки данных) возникает закономерный вопрос: как правильно передать сформированную временную таблицу в схему компоновки?
В этой статье мы подробно разберем три различных подхода к решению этой задачи. Мы начнем с простого обходного пути, предложенного разработчиками на форуме (выгрузка в таблицу значений), а затем перейдем к двум более профессиональным, быстрым и производительным методам, которые активно используются в типовых конфигурациях самой фирмой «1С».
Давайте сначала проанализируем решение, к которому пришли участники обсуждения на форуме. Суть его заключается в том, что СКД напрямую якобы «не умеет» работать с временными таблицами, находящимися в менеджере временных таблиц (МВТ), поэтому данные необходимо сначала извлечь в оперативную память сервера приложений в виде таблицы значений, а затем передать эту ТЗ в качестве внешнего набора данных в СКД.
Рассмотрим подробнее, как этот подход реализуется на практике по шагам:
НаборДанныхТЗ).ТаблицаЗначений.Посмотрим на пример программного кода, реализующего эту схему:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Инициализируем менеджер временных таблиц и запрос
МВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МВТ;
// Задаем параметры для получения кадровых данных
ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций();
ПараметрыПолученияСотрудников.Период = ТекущаяДата();
ПараметрыПолученияСотрудников.КадровыеДанные = "Сотрудник, Подразделение, Должность, Оклад";
// Заполняем временную таблицу кадровыми данными через программный интерфейс
КадровыйУчет.СоздатьВТСотрудникиОрганизации(МВТ, Истина, ПараметрыПолученияСотрудников);
// Извлекаем данные из ВТ в обычную Таблицу Значений
Запрос.Текст = "ВЫБРАТЬ * ИЗ ВТСотрудникиОрганизации";
ТаблицаКадровыхДанных = Запрос.Выполнить().Выгрузить();
// Передаем ТЗ в СКД
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("НаборДанныхТЗ", ТаблицаКадровыхДанных);
// Стандартный вывод отчета через процессор компоновки
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры
Плюсы данного метода: простота отладки. Разработчик всегда может посмотреть содержимое таблицы значений на сервере в режиме отладки. Нет жесткой привязки к структуре внутренних механизмов работы процессора компоновки.
Минусы данного метода: крайне низкая производительность на больших базах данных. Если в организации работают десятки тысяч сотрудников, выгрузка всей этой массы данных в оперативную память в виде ТаблицаЗначений создает колоссальную избыточную нагрузку на сервер «1С:Предприятие». Происходит двойное копирование данных: сначала из СУБД во временную таблицу, затем из временной таблицы в ТЗ на сервере приложений, а затем из ТЗ обратно в процессор компоновки СКД.
Выясним причину, почему участники форума посчитали, что СКД не умеет работать с временными таблицами напрямую. На самом деле СКД обладает возможностью принимать внешние временные таблицы. Для этого используется недокументированный 6-й параметр метода Инициализировать() процессора компоновки данных.
Этот метод позволяет полностью отказаться от выгрузки данных в промежуточные структуры (ТЗ) на сервере приложений. СКД обратится к СУБД напрямую и прочитает временную таблицу в рамках того же сеанса.
Разберем по шагам, как настроить этот механизм:
ВЫБРАТЬ
ВТ.Сотрудник КАК Сотрудник,
ВТ.Подразделение КАК Подразделение,
ВТ.Должность КАК Должность
ИЗ
ВТСотрудникиОрганизации КАК ВТ
ВЫРАЗИТЬ или использовать предопределенные пустые значения.ПриКомпоновкеРезультата мы инициализируем менеджер временных таблиц, передаем его в кадровый программный интерфейс, а затем отдаем заполненный МВТ в процессор компоновки.Давайте проанализируем пример реализации данного метода:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// 1. Создаем менеджер временных таблиц
МВТ = Новый МенеджерВременныхТаблиц;
// 2. Заполняем параметры для кадрового интерфейса
ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций();
ПараметрыПолученияСотрудников.Период = ТекущаяДата();
ПараметрыПолученияСотрудников.КадровыеДанные = "Сотрудник, Подразделение, Должность";
// 3. Вызываем программный интерфейс, который запишет данные прямо в наш МВТ под именем "ВТСотрудникиОрганизации"
КадровыйУчет.СоздатьВТСотрудникиОрганизации(МВТ, Истина, ПараметрыПолученияСотрудников);
// 4. Инициализируем стандартный процесс компоновки
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
// ВНИМАНИЕ: Передаем МВТ 6-м параметром в метод Инициализировать
ПроцессорКомпоновкиДанных.Инициализировать(
МакетКомпоновки,
, // Внешние наборы данных не нужны
ДанныеРасшифровки,
Истина,
,
МВТ // Передаем наш заполненный Менеджер Временных Таблиц!
);
// 5. Выводим результат в итоговый табличный документ
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры
Преимущества прямого использования МВТ: Высокая скорость работы и минимальное потребление памяти. Данные физически остаются на сервере СУБД в виде временной таблицы, СКД просто соединяет их со своими внутренними запросами непосредственно в процессе выполнения СУБД-запроса. Идеально подходит для сложных нестандартных алгоритмов, когда состав полей или логика выборки формируются динамически кодом перед формированием отчета.
Рассмотрим наиболее современный, надежный и архитектурно правильный способ интеграции кадрового программного интерфейса с СКД. Специалисты фирмы «1С» разработали специализированную подсистему «Представления» для конфигураций ЗУП 3, Комплексная автоматизация 2 и ERP 2. При этом подходе разработчику отчета вообще не нужно вручную создавать временные таблицы в коде!
Этот метод убирает необходимость ручного управления жизненным циклом временных таблиц и делает отчет устойчивым к обновлениям метаданных платформы.
Давайте разберем по шагам, как устроен этот механизм:
ПриКомпоновкеРезультата мы пишем всего одну ключевую строку кода:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);
КонецПроцедуры
Представления_КадровыеДанныеСотрудников:
ВЫБРАТЬ
Сотрудники.Ссылка КАК Сотрудник,
&Период КАК Период
ПОМЕСТИТЬ ВТСотрудники
ИЗ
Справочник.Сотрудники КАК Сотрудники
ГДЕ
НЕ Сотрудники.ВАрхиве
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
КадровыеДанные.Сотрудник КАК Сотрудник,
КадровыеДанные.Подразделение КАК Подразделение,
КадровыеДанные.Должность КАК Должность,
КадровыеДанные.Оклад КАК Оклад
ИЗ
ВТСотрудники КАК Сотрудники
// Делаем левое соединение со специальным шаблоном-представлением
ЛЕВОЕ СОЕДИНЕНИЕ Представления_КадровыеДанныеСотрудников КАК КадровыеДанные
ПО Сотрудники.Сотрудник = КадровыеДанные.Сотрудник
И Сотрудники.Период = КадровыеДанные.Период
Как это работает «под капотом» системы? При формировании отчета процедура ЗаполнитьОбщиеИсточникиДанныхОтчета перехватывает управление, анализирует текст запроса СКД и находит в нем ключевое слово Представления_КадровыеДанныеСотрудников. Система автоматически понимает, какие именно кадровые данные затребовал разработчик (в нашем примере это Подразделение, Должность, Оклад), сама обращается к внутренним механизмам кадрового учета (с учетом прав доступа RLS!), генерирует необходимый сложный SQL-запрос и подменяет исходный шаблон-представление реальным оптимальным запросом к физическим таблицам базы данных.
Преимущества использования механизма Представлений:
Мы проанализировали три метода интеграции кадрового учета и СКД. Каждый из них имеет право на существование, но использовать их нужно в правильном контексте: