Как сформировать печатную форму Т-1 из документа Продление контракта в 1С

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

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

Разберем по шагам, как правильно настроить внешнюю печатную форму, переопределить массив объектов и избежать распространенных ошибок, таких как «Табличный документ не сформирован».

Шаг 1. Настройка сведений о внешней обработке

Для того чтобы система «понимала», в каком документе должна появиться кнопка печати, нам необходимо правильно заполнить функцию СведенияОВнешнейОбработке. Проанализируем, что нужно изменить. В массиве Назначение должен быть указан именно тот документ, из которого мы планируем запускать печать.

Рассмотрим пример кода регистрации:


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

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

Важный момент: если вы просто скопируете код из типовой формы Т-1, она не заработает, так как будет ожидать на входе ссылку на ПриемНаРаботу, а получит ПродлениеКонтрактаДоговора.

Шаг 2. Переопределение массива объектов в процедуре Печать

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

Выясним причину, по которой поиск только по физическому лицу может быть ошибочным. У сотрудника может быть несколько приемов (например, по основному месту и по внутреннему совместительству). Поэтому искать документ-основание нужно строго по связке Сотрудник + ФизическоеЛицо.

Проанализируем правильный подход к запросу:


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

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

    // Проверка на наличие данных
    Если МассивОбъектовПрием.Количество() = 0 Тогда
        Сообщить("Не найдены документы приема на работу для выбранных сотрудников!");
        Возврат;
    КонецЕсли;

    // 3. Формируем табличный документ
    ТабличныйДокумент = СформироватьПечатнуюФормуТ1(МассивОбъектовПрием, ОбъектыПечати);

    // 4. Выводим результат в коллекцию
    УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
        КоллекцияПечатныхФорм, 
        "ФормаТ1", 
        "Приказ о приеме (Т-1)", 
        ТабличныйДокумент
    );

КонецПроцедуры

Шаг 3. Использование типовых функций ЗУП

Для формирования самой печатной формы Т-1 крайне не рекомендуется «рисовать» макет вручную или писать свои запросы к данным сотрудника. В ЗУП 3.1 реализован мощный механизм программного интерфейса (API). Посмотрим на пример вызова типового метода формирования данных.

Рассмотрим функцию СформироватьПечатнуюФормуТ1. Вместо того чтобы изобретать велосипед, мы можем обратиться к менеджеру документа ПриемНаРаботу или использовать общие модули кадрового учета.


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

КонецФункции

Шаг 4. Устранение ошибки «Табличный документ не сформирован»

Эта ошибка — самая частая при разработке внешних печатных форм (ВПФ). Разберем причины её возникновения:

  1. Несовпадение имен идентификаторов: В процедуре СведенияОВнешнейОбработке вы указали идентификатор "ФормаТ1", а при выводе в коллекцию написали "Форма Т1" (с пробелом). БСП не сможет сопоставить эти данные и выдаст ошибку.
  2. Пустой массив объектов: Если ваш запрос к базе данных не нашел ни одного документа ПриемНаРаботу, табличный документ останется пустым. БСП интерпретирует пустой ТабличныйДокумент как ошибку формирования.
  3. Ошибки в ОбъектыПечати: Если вы вручную заполняете ОбъектыПечати, убедитесь, что в них передаются ссылки из исходного МассивОбъектов, иначе механизм предварительного просмотра не будет знать, к какому документу относится страница.

Шаг 5. Работа с циклом и оптимизация

Проанализируем ситуацию, описанную автором темы. В его коде внутри цикла по МассивОбъектовПрием вызывалась функция печати, в которую передавался весь массив целиком. Это классическая логическая ошибка.

Как было: В цикле 5 раз вызывается печать 5-ти документов. Итог: 25 страниц в печатной форме.

Как надо: Либо мы передаем весь массив в типовую функцию один раз (если она поддерживает массовую печать), либо в цикле формируем табличный документ по одной ссылке и используем метод Вывести().

Рассмотрим правильный пример формирования общего документа:


БольшойТабДок = Новый ТабличныйДокумент;
Для Каждого ТекущийПрием Из МассивОбъектовПрием Цикл
    // Создаем временный массив из одного элемента для типовой функции
    ОдиночныйМассив = Новый Массив;
    ОдиночныйМассив.Добавить(ТекущийПрием);
    
    // Получаем форму на одного сотрудника
    МаленькийТабДок = Документы.ПриемНаРаботу.СформироватьПечатныеФормыПриказаОПриеме(ОдиночныйМассив, ОбъектыПечати, "ФормаТ1");
    
    // Добавляем страницу к общему документу
    Если БольшойТабДок.ВысотаТаблицы > 0 Тогда
        БольшойТабДок.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЕсли;
    БольшойТабДок.Вывести(МаленькийТабДок);
КонецЦикла;

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

Резюме

Подводя итог, отметим: для реализации «хитрой» печати из другого документа не нужно переписывать всю логику формирования Т-1. Достаточно подменить ссылки в массиве объектов в самом начале работы процедуры Печать. Главное — использовать корректные связи через регистры сведений (КадроваяИсторияСотрудников) и соблюдать идентичность имен в метаданных обработки.

Теперь мы знаем, как программно связать Продление контракта с Приемом на работу и вывести стандартную форму Т-1 без лишних трудозатрат.

← На главную