Как вывести результат согласования конкретного сотрудника или роли в шаблон 1С:Документооборот

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

При работе в 1С:Документооборот часто возникает задача настройки автозаполняемых шаблонов (файлов Word или PDF). Стандартный механизм вывода листа согласования выгружает список всех участников процесса. Однако в бизнес-практике часто требуется, чтобы в определенных местах документа (например, в таблице подписей в конце договора) отображалась виза только конкретного должностного лица — например, главного бухгалтера или юриста — в то время как в процессе согласования могут участвовать десятки человек.

В данной статье мы разберем, как с помощью встроенного языка 1С программно извлечь нужную визу из справочника ВизыСогласования и корректно отобразить ее в шаблоне документа, избежав дублирования и лишних данных.

Анализ структуры данных виз согласования

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

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


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

Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
РезультатЗапроса = Запрос.Выполнить();

Этот код выводит всех участников. Наша задача — модифицировать его так, чтобы выделить "избранных".

Решение 1: Фильтрация по конкретному пользователю

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


Выборка = РезультатЗапроса.Выбрать();
РезультатСогласования = "";

Пока Выборка.Следующий() Цикл
    // Проверяем, совпадает ли исполнитель с нужным нам сотрудником
    Если Выборка.Исполнитель = Справочники.Пользователи.НайтиПоНаименованию("Иванов Иван Иванович") Тогда
        РезультатСогласования = Строка(Выборка.Исполнитель) + " (" + Формат(Выборка.ДатаИсполнения, "ДФ=dd.MM.yyyy") + ") " + Выборка.РезультатСогласования;
    КонецЕсли;
КонецЦикла;

РезультатОбработки = РезультатСогласования;

Важный нюанс: использование поиска по наименованию НайтиПоНаименованию является не самым надежным методом, так как при переименовании пользователя код перестанет работать. Однако для быстрой настройки это решение вполне допустимо.

Решение 2: Использование ролей исполнителей

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВизыСогласования.Исполнитель КАК Исполнитель,
    |   ВизыСогласования.ДатаИсполнения КАК ДатаИсполнения,
    |   ВизыСогласования.РезультатСогласования КАК РезультатСогласования,
    |   ВизыСогласования.РольИсполнителя КАК РольИсполнителя
    |ИЗ
    |   Справочник.ВизыСогласования КАК ВизыСогласования
    |ГДЕ
    |   ВизыСогласования.Документ = &Документ";

Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();

НужнаяРоль = Справочники.РолиИсполнителей.НайтиПоНаименованию("ГлавныйПоТарелочкам");

Пока Выборка.Следующий() Цикл
    Если Выборка.РольИсполнителя = НужнаяРоль Тогда
        РезультатОбработки = "Согласовано: " + Выборка.Исполнитель + ", дата: " + Формат(Выборка.ДатаИсполнения, "ДФ=dd.MM.yyyy");
        Прервать; // Выходим, если нашли нужную визу
    КонецЕсли;
КонецЦикла;

Обратите внимание, что мы используем Справочники.РолиИсполнителей для получения ссылки на объект роли. Если в шаблоне нужно вывести "пусто", если виза еще не поставлена, переменная РезультатОбработки останется пустой строкой.

Решение 3: Оптимизация запроса (условие на уровне БД)

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |   ВизыСогласования.РезультатСогласования,
    |   ВизыСогласования.ДатаИсполнения,
    |   ВизыСогласования.Исполнитель
    |ИЗ
    |   Справочник.ВизыСогласования КАК ВизыСогласования
    |ГДЕ
    |   ВизыСогласования.Документ = &Документ
    |   И ВизыСогласования.РольИсполнителя = &Роль
    |   И ВизыСогласования.РезультатСогласования = ЗНАЧЕНИЕ(Перечисление.РезультатыСогласования.Согласовано)
    |УПОРЯДОЧИТЬ ПО
    |   ВизыСогласования.ДатаИсполнения УБЫВ";

Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
Запрос.УстановитьПараметр("Роль", Справочники.РолиИсполнителей.НайтиПоНаименованию("Юрист"));

Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    РезультатОбработки = "Юрист подтвердил: " + Выборка.Исполнитель;
Иначе
    РезультатОбработки = "Виза отсутствует";
КонецЕсли;

В данном примере мы добавили конструкцию ВЫБРАТЬ ПЕРВЫЕ 1 и сортировку по дате УБЫВ. Это позволяет получить самую свежую визу, если документ проходил несколько кругов согласования.

Типичные ошибки при написании скриптов автозаполнения

Разберем основные грабли, на которые наступают разработчики при настройке шаблонов в 1С:ДО:

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

Альтернативный подход: Рабочие группы

Рассмотрим совет опытных администраторов: если привязка к ролям кажется слишком жесткой, можно создать Рабочую группу (например, "Подписанты шаблона договора"). В скрипте мы будем проверять, входит ли текущий согласователь в эту группу:


// Пример проверки вхождения пользователя в группу
Если РегистрыСведений.СоставРабочихГрупп.Содержит(НужнаяГруппа, Выборка.Исполнитель) Тогда
    // Выводим данные в шаблон
КонецЕсли;

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

Подводя итог, можно сказать, что механизм автозаполнения в 1С:Документооборот предоставляет практически неограниченные возможности по кастомизации документов. Главное — четко определить критерии выбора данных: по конкретной ссылке на пользователя, по его роли в процессе или по принадлежности к определенной группе доступа.

← На главную