Как во внешней печатной форме справочника «Сотрудники» получить дату и номер трудового договора в 1С:ЗУП 3.1?

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

Разработка внешних печатных форм (ВПФ) — одна из самых частых задач, с которыми сталкивается начинающий разработчик в среде «1С:Предприятие 8». Особенно много нюансов возникает при работе с конфигурацией «1С:Зарплата и управление персоналом 3.1» (ЗУП 3.1). В этой статье мы подробно разберем, как правильно спроектировать внешнюю печатную форму для справочника Сотрудники, извлечь номер и дату трудового договора, а также почему стандартные запросы к документам приема на работу могут привести к критическим ошибкам в работе программы.

В чем заключается основная проблема прямого запроса?

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ПриемНаРаботу.Дата КАК Дата,
    |    ПриемНаРаботу.Номер КАК Номер,
    |    ПриемНаРаботу.Сотрудник КАК Сотрудник,
    |    Сотрудники.ФизическоеЛицо.ФИО КАК ФИО
    |ИЗ
    |    Документ.ПриемНаРаботу КАК ПриемНаРаботу
    |    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
    |    ПО ПриемНаРаботу.Сотрудник.ФизическоеЛицо.ФИО = Сотрудники.ФизическоеЛицо.ФИО";

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

  1. Соединение по строковому полю (ФИО): Сравнение строк — крайне медленная операция для СУБД. Кроме того, в крупных организациях часто работают полные однофамильцы (тезки). Соединение по ФИО приведет к тому, что данные договоров перепутаются между сотрудниками с одинаковыми именами. Ссылочные типы всегда нужно связывать по уникальным идентификаторам (ссылкам), например: ПО ПриемНаРаботу.Сотрудник = Сотрудники.Ссылка.
  2. Отсутствие отборов: Запрос пытается прочитать абсолютно все документы приема на работу и всех сотрудников в базе. На реальной базе с тысячами сотрудников такой запрос вызовет зависание системы. Печатная форма должна обрабатывать только тех сотрудников, которых пользователь выделил в списке.
  3. Изменчивость кадровых данных: В ЗУП 3.1 реквизиты трудового договора могут регистрироваться не только документом ПриемНаРаботу. Сведения также могут храниться в регистре сведений КадроваяИсторияСотрудников, изменяться дополнительными соглашениями или кадровыми переводами. Прямой запрос к одному документу не гарантирует получение актуальных данных на текущую дату.

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

Для решения подобных задач в конфигурациях на базе Библиотеки стандартных подсистем (БСП) предусмотрены специальные экспортные методы. Наиболее стабильным, оптимизированным и безопасным способом получения кадровых данных в ЗУП 3.1 является использование встроенной функции КадровыйУчет.КадровыеДанныеСотрудников.

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

Рассмотрим по шагам, как устроена работа внешней печатной формы справочника Сотрудники.

Шаг 1. Точка входа во внешней печатной форме

Любая внешняя печатная форма, подключаемая через механизм «Дополнительные отчеты и обработки», должна содержать в модуле объекта стандартную экспортную процедуру Печать. В эту процедуру платформа передает список объектов, для которых запущена печать.


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    // Проверяем, нужно ли выводить нашу печатную форму
    УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "НашаВнешняяПечатнаяФорма");
    
    // Получаем табличный документ
    ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
    
    // Связываем объекты печати с результатом
    УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
        КоллекцияПечатныхФорм, 
        "НашаВнешняяПечатнаяФорма", 
        "Трудовой договор (внешний)", 
        ТабличныйДокумент
    );
    
КонецПроцедуры

Обратите внимание на параметр МассивОбъектов. Он содержит массив ссылок на выбранные элементы справочника Сотрудники. Ошибка «Переменная неопределенна» у начинающих разработчиков возникает именно потому, что они пытаются использовать единичную переменную Сотрудник, которой нет в контексте процедуры. Работать необходимо именно с переданным массивом.

Шаг 2. Получение кадровых данных без написания запросов

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


Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
    
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.КлючПараметровПечати = "ПараметрыПечати_ТрудовойДоговор";
    
    // Получаем макет печатной формы (должен быть создан в обработке)
    Макет = ПолучитьМакет("Макет");
    
    // Определяем список необходимых нам полей
    КадровыеДанные = "ТрудовойДоговорНомер, ТрудовойДоговорДата, ФИОПолные, Подразделение, Должность";
    
    // Указываем дату, на которую актуальны данные (обычно текущая дата сеанса)
    ДатаПолученияДанных = ТекущаяДатаСеанса();
    
    // Вызываем типовой метод ЗУП 3.1
    ТаблицаКадровыхДанных = КадровыйУчет.КадровыеДанныеСотрудников(
        Истина, 
        МассивОбъектов, 
        КадровыеДанные, 
        ДатаПолученияДанных
    );
    
    // Проанализируем полученную таблицу данных и выведем ее в макет
    Для Каждого СтрокаКадровыхДанных Из ТаблицаКадровыхДанных Цикл
        
        // Получаем область макета
        ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
        
        // Заполняем параметры области макета данными из полученной строки ТЗ
        ОбластьСтрока.Параметры.Заполнить(СтрокаКадровыхДанных);
        
        // Форматируем вывод даты трудового договора
        Если ЗначениеЗаполнено(СтрокаКадровыхДанных.ТрудовойДоговорДата) Тогда
            ОбластьСтрока.Параметры.ДоговорДата = Формат(
                СтрокаКадровыхДанных.ТрудовойДоговорДата, 
                "ДФ='дд ММММ гггг ""г.""'"
            );
        Иначе
            ОбластьСтрока.Параметры.ДоговорДата = "________ г.";
        EndIf;
        
        // Если номер договора не заполнен, выводим заглушку
        Если Не ЗначениеЗаполнено(СтрокаКадровыхДанных.ТрудовойДоговорНомер) Тогда
            ОбластьСтрока.Параметры.ТрудовойДоговорНомер = "б/н";
        КонецЕсли;
        
        // Фиксируем связь выводимой области с конкретным объектом справочника
        // Это необходимо для возможности расшифровки и навигации в табличном документе
        ОбъектыПечати.Добавить(СтрокаКадровыхДанных.Сотрудник, "УникальноеИмяОбласти");
        
        // Выводим заполненную область в итоговый печатный документ
        ТабличныйДокумент.Вывести(ОбластьСтрока);
        
    КонецЦикла;
    
    Возврат ТабличныйДокумент;
    
КонецФункции

Как работает метод КадровыеДанныеСотрудников?

Давайте подробно разберем параметры функции КадровыйУчет.КадровыеДанныеСотрудников, чтобы понимать логику ее работы:

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

Использование функции КадровыеДанныеСотрудников вместо прямого написания сложных SQL-подобных запросов к таблицам СУБД дает разработчику несколько важных преимуществ:

Таким образом, мы детально разобрали правильную архитектуру построения внешней печатной формы в 1С:ЗУП 3.1. Использование встроенных механизмов БСП позволяет создавать надежные и быстрые алгоритмы, которые будут стабильно работать даже на сильно измененных или крупных корпоративных базах данных.

← На главную