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