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