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