При работе в 1С:Документооборот часто возникает задача настройки автозаполняемых шаблонов (файлов Word или PDF). Стандартный механизм вывода листа согласования выгружает список всех участников процесса. Однако в бизнес-практике часто требуется, чтобы в определенных местах документа (например, в таблице подписей в конце договора) отображалась виза только конкретного должностного лица — например, главного бухгалтера или юриста — в то время как в процессе согласования могут участвовать десятки человек.
В данной статье мы разберем, как с помощью встроенного языка 1С программно извлечь нужную визу из справочника ВизыСогласования и корректно отобразить ее в шаблоне документа, избежав дублирования и лишних данных.
Для начала проанализируем, где именно хранятся данные. В версии 1С:Документооборот 2.1 (на примере которой строится большинство решений) информация о результатах согласования находится в справочнике ВизыСогласования. Каждый элемент этого справочника связан с владельцем — документом, и содержит такие реквизиты, как Исполнитель, РезультатСогласования, ДатаИсполнения и РольИсполнителя.
Рассмотрим базовый запрос, который получает список всех согласующих для текущего документа:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВизыСогласования.Исполнитель,
| ВизыСогласования.ДатаИсполнения,
| ВизыСогласования.РезультатСогласования
|ИЗ
| Справочник.ВизыСогласования КАК ВизыСогласования
|ГДЕ
| ВизыСогласования.Документ = &Документ
| И ВизыСогласования.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Этот код выводит всех участников. Наша задача — модифицировать его так, чтобы выделить "избранных".
Самый простой способ — это проверка конкретного пользователя. Рассмотрим ситуацию, когда нам нужно вывести результат согласования определенного человека. Разберем по шагам, как это реализовать в цикле обхода результата запроса.
Выборка = РезультатЗапроса.Выбрать();
РезультатСогласования = "";
Пока Выборка.Следующий() Цикл
// Проверяем, совпадает ли исполнитель с нужным нам сотрудником
Если Выборка.Исполнитель = Справочники.Пользователи.НайтиПоНаименованию("Иванов Иван Иванович") Тогда
РезультатСогласования = Строка(Выборка.Исполнитель) + " (" + Формат(Выборка.ДатаИсполнения, "ДФ=dd.MM.yyyy") + ") " + Выборка.РезультатСогласования;
КонецЕсли;
КонецЦикла;
РезультатОбработки = РезультатСогласования;
Важный нюанс: использование поиска по наименованию НайтиПоНаименованию является не самым надежным методом, так как при переименовании пользователя код перестанет работать. Однако для быстрой настройки это решение вполне допустимо.
Более грамотным и гибким подходом является привязка к Роли исполнителя. Например, если в процессе согласования есть роль "Главный бухгалтер", то в шаблон попадет тот, кто исполнил задачу в рамках этой роли, независимо от того, кто именно занимает эту должность сейчас. Проанализируем, как обратиться к роли:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВизыСогласования.Исполнитель КАК Исполнитель,
| ВизыСогласования.ДатаИсполнения КАК ДатаИсполнения,
| ВизыСогласования.РезультатСогласования КАК РезультатСогласования,
| ВизыСогласования.РольИсполнителя КАК РольИсполнителя
|ИЗ
| Справочник.ВизыСогласования КАК ВизыСогласования
|ГДЕ
| ВизыСогласования.Документ = &Документ";
Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
НужнаяРоль = Справочники.РолиИсполнителей.НайтиПоНаименованию("ГлавныйПоТарелочкам");
Пока Выборка.Следующий() Цикл
Если Выборка.РольИсполнителя = НужнаяРоль Тогда
РезультатОбработки = "Согласовано: " + Выборка.Исполнитель + ", дата: " + Формат(Выборка.ДатаИсполнения, "ДФ=dd.MM.yyyy");
Прервать; // Выходим, если нашли нужную визу
КонецЕсли;
КонецЦикла;
Обратите внимание, что мы используем Справочники.РолиИсполнителей для получения ссылки на объект роли. Если в шаблоне нужно вывести "пусто", если виза еще не поставлена, переменная РезультатОбработки останется пустой строкой.
Чтобы не перебирать все визы документа в памяти (их может быть много, включая старые итерации), выясним, как перенести фильтрацию непосредственно в текст запроса. Это правильнее с точки зрения производительности 1С.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ВизыСогласования.РезультатСогласования,
| ВизыСогласования.ДатаИсполнения,
| ВизыСогласования.Исполнитель
|ИЗ
| Справочник.ВизыСогласования КАК ВизыСогласования
|ГДЕ
| ВизыСогласования.Документ = &Документ
| И ВизыСогласования.РольИсполнителя = &Роль
| И ВизыСогласования.РезультатСогласования = ЗНАЧЕНИЕ(Перечисление.РезультатыСогласования.Согласовано)
|УПОРЯДОЧИТЬ ПО
| ВизыСогласования.ДатаИсполнения УБЫВ";
Запрос.УстановитьПараметр("Документ", Файл.ВладелецФайла.Ссылка);
Запрос.УстановитьПараметр("Роль", Справочники.РолиИсполнителей.НайтиПоНаименованию("Юрист"));
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
РезультатОбработки = "Юрист подтвердил: " + Выборка.Исполнитель;
Иначе
РезультатОбработки = "Виза отсутствует";
КонецЕсли;
В данном примере мы добавили конструкцию ВЫБРАТЬ ПЕРВЫЕ 1 и сортировку по дате УБЫВ. Это позволяет получить самую свежую визу, если документ проходил несколько кругов согласования.
Разберем основные грабли, на которые наступают разработчики при настройке шаблонов в 1С:ДО:
Справочник.Роли... в единственном числе. В системе 1С коллекция называется Справочники (множественное число).РольИсполнителя в справочнике виз может быть не заполнен у некоторых записей. В этом случае стоит проверять принадлежность Исполнителя к определенной рабочей группе.Рассмотрим совет опытных администраторов: если привязка к ролям кажется слишком жесткой, можно создать Рабочую группу (например, "Подписанты шаблона договора"). В скрипте мы будем проверять, входит ли текущий согласователь в эту группу:
// Пример проверки вхождения пользователя в группу
Если РегистрыСведений.СоставРабочихГрупп.Содержит(НужнаяГруппа, Выборка.Исполнитель) Тогда
// Выводим данные в шаблон
КонецЕсли;
Это позволяет бизнес-пользователям самостоятельно управлять списком лиц, чьи визы должны попадать в печатную форму, не прибегая к помощи программиста для изменения кода скрипта.
Подводя итог, можно сказать, что механизм автозаполнения в 1С:Документооборот предоставляет практически неограниченные возможности по кастомизации документов. Главное — четко определить критерии выбора данных: по конкретной ссылке на пользователя, по его роли в процессе или по принадлежности к определенной группе доступа.