Как правильно передать временную таблицу кадровых данных в отчет на СКД в 1С:КА 2 и ЗУП 3?

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

При разработке отчетов в конфигурациях «1С:Комплексная автоматизация 2», «1С:ERP Управление предприятием 2» или «1С:Зарплата и управление персоналом 3» программисты часто сталкиваются с необходимостью получения кадровых данных сотрудников. Для этих целей в системе предусмотрен мощный программный интерфейс — функция КадровыйУчет.СоздатьВТСотрудникиОрганизации(). Однако при попытке вывести полученные результаты в отчет на СКД (Системе компоновки данных) возникает закономерный вопрос: как правильно передать сформированную временную таблицу в схему компоновки?

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

Подход №1. Промежуточная выгрузка данных в Таблицу Значений (ТЗ)

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

Рассмотрим подробнее, как этот подход реализуется на практике по шагам:

  1. В схеме компоновки данных создается набор данных - объект (например, с именем НаборДанныхТЗ).
  2. В модуле отчета программно вызывается метод создания временной таблицы кадровых данных.
  3. Данные из созданной временной таблицы выбираются обычным запросом и выгружаются в ТаблицаЗначений.
  4. Таблица значений передается в процессор компоновки через структуру внешних наборов данных.

Посмотрим на пример программного кода, реализующего эту схему:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем менеджер временных таблиц и запрос
    МВТ = Новый МенеджерВременныхТаблиц;
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = МВТ;
    
    // Задаем параметры для получения кадровых данных
    ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций();
    ПараметрыПолученияСотрудников.Период = ТекущаяДата();
    ПараметрыПолученияСотрудников.КадровыеДанные = "Сотрудник, Подразделение, Должность, Оклад";
    
    // Заполняем временную таблицу кадровыми данными через программный интерфейс
    КадровыйУчет.СоздатьВТСотрудникиОрганизации(МВТ, Истина, ПараметрыПолученияСотрудников);
    
    // Извлекаем данные из ВТ в обычную Таблицу Значений
    Запрос.Текст = "ВЫБРАТЬ * ИЗ ВТСотрудникиОрганизации";
    ТаблицаКадровыхДанных = Запрос.Выполнить().Выгрузить();
    
    // Передаем ТЗ в СКД
    ВнешниеНаборыДанных = Новый Структура;
    ВнешниеНаборыДанных.Вставить("НаборДанныхТЗ", ТаблицаКадровыхДанных);
    
    // Стандартный вывод отчета через процессор компоновки
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
КонецПроцедуры

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

Минусы данного метода: крайне низкая производительность на больших базах данных. Если в организации работают десятки тысяч сотрудников, выгрузка всей этой массы данных в оперативную память в виде ТаблицаЗначений создает колоссальную избыточную нагрузку на сервер «1С:Предприятие». Происходит двойное копирование данных: сначала из СУБД во временную таблицу, затем из временной таблицы в ТЗ на сервере приложений, а затем из ТЗ обратно в процессор компоновки СКД.

Подход №2. Прямая передача Менеджера Временных Таблиц (МВТ) в СКД

Выясним причину, почему участники форума посчитали, что СКД не умеет работать с временными таблицами напрямую. На самом деле СКД обладает возможностью принимать внешние временные таблицы. Для этого используется недокументированный 6-й параметр метода Инициализировать() процессора компоновки данных.

Этот метод позволяет полностью отказаться от выгрузки данных в промежуточные структуры (ТЗ) на сервере приложений. СКД обратится к СУБД напрямую и прочитает временную таблицу в рамках того же сеанса.

Разберем по шагам, как настроить этот механизм:

  1. Конструирование запроса в СКД: В схеме компоновки данных (набор данных - запрос) мы пишем обычный запрос, который обращается к еще не существующей временной таблице кадрового учета. Например:
    
    ВЫБРАТЬ
        ВТ.Сотрудник КАК Сотрудник,
        ВТ.Подразделение КАК Подразделение,
        ВТ.Должность КАК Должность
    ИЗ
        ВТСотрудникиОрганизации КАК ВТ
    
    Важное примечание: Чтобы конструктор запроса СКД в конфигураторе не выдавал ошибку отсутствия таблицы и корректно определял типы полей, рекомендуется явно типизировать поля при помощи функций ВЫРАЗИТЬ или использовать предопределенные пустые значения.
  2. Программный код в модуле отчета: В предопределенной процедуре ПриКомпоновкеРезультата мы инициализируем менеджер временных таблиц, передаем его в кадровый программный интерфейс, а затем отдаем заполненный МВТ в процессор компоновки.

Давайте проанализируем пример реализации данного метода:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // 1. Создаем менеджер временных таблиц
    МВТ = Новый МенеджерВременныхТаблиц;
    
    // 2. Заполняем параметры для кадрового интерфейса
    ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций();
    ПараметрыПолученияСотрудников.Период = ТекущаяДата();
    ПараметрыПолученияСотрудников.КадровыеДанные = "Сотрудник, Подразделение, Должность";
    
    // 3. Вызываем программный интерфейс, который запишет данные прямо в наш МВТ под именем "ВТСотрудникиОрганизации"
    КадровыйУчет.СоздатьВТСотрудникиОрганизации(МВТ, Истина, ПараметрыПолученияСотрудников);
    
    // 4. Инициализируем стандартный процесс компоновки
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    
    // ВНИМАНИЕ: Передаем МВТ 6-м параметром в метод Инициализировать
    ПроцессорКомпоновкиДанных.Инициализировать(
        МакетКомпоновки, 
        , // Внешние наборы данных не нужны
        ДанныеРасшифровки, 
        Истина, 
        , 
        МВТ // Передаем наш заполненный Менеджер Временных Таблиц!
    );
    
    // 5. Выводим результат в итоговый табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
КонецПроцедуры

Преимущества прямого использования МВТ: Высокая скорость работы и минимальное потребление памяти. Данные физически остаются на сервере СУБД в виде временной таблицы, СКД просто соединяет их со своими внутренними запросами непосредственно в процессе выполнения СУБД-запроса. Идеально подходит для сложных нестандартных алгоритмов, когда состав полей или логика выборки формируются динамически кодом перед формированием отчета.

Подход №3. Механизм «Представлений» (Штатный декларативный метод 1С)

Рассмотрим наиболее современный, надежный и архитектурно правильный способ интеграции кадрового программного интерфейса с СКД. Специалисты фирмы «1С» разработали специализированную подсистему «Представления» для конфигураций ЗУП 3, Комплексная автоматизация 2 и ERP 2. При этом подходе разработчику отчета вообще не нужно вручную создавать временные таблицы в коде!

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

Давайте разберем по шагам, как устроен этот механизм:

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

Как это работает «под капотом» системы? При формировании отчета процедура ЗаполнитьОбщиеИсточникиДанныхОтчета перехватывает управление, анализирует текст запроса СКД и находит в нем ключевое слово Представления_КадровыеДанныеСотрудников. Система автоматически понимает, какие именно кадровые данные затребовал разработчик (в нашем примере это Подразделение, Должность, Оклад), сама обращается к внутренним механизмам кадрового учета (с учетом прав доступа RLS!), генерирует необходимый сложный SQL-запрос и подменяет исходный шаблон-представление реальным оптимальным запросом к физическим таблицам базы данных.

Преимущества использования механизма Представлений:

Резюме и рекомендации

Мы проанализировали три метода интеграции кадрового учета и СКД. Каждый из них имеет право на существование, но использовать их нужно в правильном контексте:

← На главную