В типовых конфигурациях 1С:Предприятие, таких как 1С:ЗУП, часто возникает задача по предоставлению пользователям очень специфических прав доступа, которые не предусмотрены стандартным механизмом ролей. Классический пример — необходимость дать секретарю возможность изменять только номер и дату документа "Командировка", при этом не предоставляя полных прав на редактирование всего документа. Такая детализация прав требует доработки функционала. Мы рассмотрим несколько подходов к решению этой задачи, основываясь на рекомендациях сообщества разработчиков 1С и типовых механизмах платформы.
Основная сложность заключается в том, что обычное изменение доступности полей на форме не решает проблему: при попытке записать документ с ограниченными правами, платформа все равно выдаст ошибку отсутствия прав на запись объекта целиком. Поэтому ключевым элементом решения будет использование привилегированного режима для выполнения операций записи.
Использование расширений — это предпочтительный и наиболее современный способ доработки типовых конфигураций 1С. Он позволяет вносить изменения без снятия конфигурации с поддержки, что значительно упрощает процесс обновления информационной базы. Рассмотрим пошагово, как мы можем реализовать решение с помощью расширения.
Прежде всего, нам потребуется изменить форму документа "Командировка", чтобы поля "Номер" и "Дата" были доступны для редактирования секретарю. Для этого:
Номер и Дата.ТолькоПросмотр = Ложь или просто убеждаемся, что они интерактивно доступны для редактирования. Остальные поля документа останутся недоступными для изменения, согласно стандартным правам секретаря.Поскольку у секретаря не будет полных прав на изменение документа, обычная запись измененных номера и даты приведет к ошибке. Для решения этой проблемы необходимо реализовать обработку записи таким образом, чтобы она выполнялась в привилегированном режиме. Это означает, что серверный код, отвечающий за сохранение изменений номера и даты, будет выполняться с полными правами, игнорируя ограничения прав текущего пользователя.
Мы можем использовать событие формы документа, например, "ПриЗаписиНаСервере" или создать отдельную команду на форме, которая будет выполнять запись. Рассмотрим пример серверной процедуры:
// В модуле формы документа "Командировка" расширения,
// например, в обработчике команды "ЗаписатьНомерИДату" или "ПередЗаписьюНаСервере"
&НаСервере
Процедура ЗаписатьНомерИДатуДокументаНаСервере(Знач НовыйНомер, Знач НоваяДата)
// Получаем объект документа из ссылки
ДокументОбъект = Объект.ПолучитьОбъект();
// Проверяем, что изменился только номер и дата (или только то, что разрешено секретарю)
// Реальная логика проверки должна быть более сложной,
// например, сравнение текущих значений с значениями из базы данных.
// Для примера предположим, что мы получили эти значения на клиенте
// и передали в эту серверную функцию.
// Включаем привилегированный режим.
// Это позволит выполнить запись документа, даже если у текущего пользователя
// нет полных прав на объект.
УстановитьПривилегированныйРежим(Истина);
Попытка
// Изменяем только разрешенные реквизиты
ДокументОбъект.Номер = НовыйНомер;
ДокументОбъект.Дата = НоваяДата;
// Выполняем запись документа
ДокументОбъект.Записать();
Сообщить("Номер и дата документа успешно изменены.");
Исключение
Сообщить("Ошибка при изменении номера и даты: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
// Обязательно отключаем привилегированный режим после выполнения операции
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
В клиентском коде мы могли бы вызывать эту серверную процедуру, передавая новые значения номера и даты, введенные секретарем.
Для того чтобы изменения, внесенные расширением, работали корректно, потребуется создать или модифицировать профиль групп доступа и роль, которая будет разрешать секретарю:
Номер и Дата на форме документа, модифицированной расширением.Важно также убедиться, что для расширения отключен безопасный режим (если он был включен), иначе привилегированный режим может быть ограничен.
Создание внешней обработки, как предлагалось на форуме, также является жизнеспособным решением, особенно если необходимо предоставить секретарю более специализированный интерфейс для работы только с номерами и датами командировок, не открывая ему полную форму документа.
Внешняя обработка может представлять собой форму со списком документов "Командировка", где секретарь сможет выбрать нужный документ. Затем в этой же обработке или в отдельном диалоговом окне будет предоставлена упрощенная форма, позволяющая изменить только номер и дату выбранного документа. Это дает нам полный контроль над интерфейсом и доступными действиями.
Как и в случае с расширением, для сохранения изменений потребуется использовать привилегированный режим. Код внешней обработки, отвечающий за изменение и запись документа, должен быть выполнен с использованием УстановитьПривилегированныйРежим(Истина) перед записью и УстановитьПривилегированныйРежим(Ложь) после. Это позволит обойти стандартные ограничения прав на запись документа.
Рассмотрим пример кода из внешней обработки:
// В модуле формы внешней обработки
&НаКлиенте
Процедура ИзменитьИЗаписать(Команда)
// Предполагаем, что у нас есть поля формы:
// ПолеВводаСсылкаНаДокумент - для выбора командировки
// ПолеВводаНовыйНомер - для ввода нового номера
// ПолеВводаНоваяДата - для ввода новой даты
Если ЗначениеЗаполнено(ПолеВводаСсылкаНаДокумент) Тогда
Если Не ЗначениеЗаполнено(ПолеВводаНовыйНомер) Тогда
Сообщить("Поле 'Новый номер' должно быть заполнено!");
Возврат;
КонецЕсли;
Если ТипЗнч(ПолеВводаНоваяДата) <> Тип("Дата") Или Не ЗначениеЗаполнено(ПолеВводаНоваяДата) Тогда
Сообщить("Поле 'Новая дата' должно быть заполнено корректной датой!");
Возврат;
КонецЕсли;
// Вызываем серверную процедуру для выполнения изменений
ИзменитьИЗаписатьНаСервере(ПолеВводаСсылкаНаДокумент, ПолеВводаНовыйНомер, ПолеВводаНоваяДата);
Иначе
Сообщить("Выберите документ 'Командировка'.");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ИзменитьИЗаписатьНаСервере(СсылкаНаДокумент, НовыйНомер, НоваяДата)
// Получаем объект документа по ссылке
Попытка
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Исключение
Сообщить("Не удалось получить объект документа: " + ОписаниеОшибки(), СтатусСообщения.Важное);
Возврат;
КонецПопытки;
// Включаем привилегированный режим для записи
УстановитьПривилегированныйРежим(Истина);
Попытка
ДокументОбъект.Номер = НовыйНомер;
ДокументОбъект.Дата = НоваяДата;
// Если нужно провести документ после изменения
// Допустим, на форме обработки есть флажок "ПровестиДокумент"
Если ЭтотОбъект.ПровестиДокумент Тогда
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ " + ДокументОбъект.Номер + " успешно изменен и проведен.");
Иначе
ДокументОбъект.Записать();
Сообщить("Документ " + ДокументОбъект.Номер + " успешно изменен.");
КонецЕсли;
Исключение
Сообщить("Ошибка при изменении/проведении документа: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
// Обязательно отключаем привилегированный режим
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
Во внешней обработке мы можем реализовать дополнительные проверки, например, на уникальность вводимого номера документа, чтобы избежать дублирования, а также контроль корректности даты. Эти проверки желательно выполнять до включения привилегированного режима.
Привилегированный режим — это мощный инструмент, который позволяет коду выполнять операции с данными, даже если у текущего пользователя нет на это прямых прав. Мы должны использовать его с крайней осторожностью, поскольку некорректное применение может привести к нарушению безопасности данных или нежелательным изменениям.
УстановитьПривилегированныйРежим(Истина) в коде.УстановитьПривилегированныйРежим(Ложь). Это минимизирует потенциальные риски безопасности.Важно: При разработке решений с использованием привилегированного режима мы всегда должны тщательно проверять все входные данные и логику, чтобы предотвратить несанкционированные действия. Мы должны убедиться, что пользователь может изменить только те данные, которые мы ему разрешили, и никакие другие.
В запросе пользователя также упоминается "проведение этого документа". После изменения номера или даты документ, скорее всего, потребуется перепровести, чтобы изменения отразились в регистрах и повлияли на связанные расчеты (например, расчет среднего заработка). Мы должны учесть это в нашей разработке.
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение) внутри блока привилегированного режима.В 1С:ЗУП, как и в других типовых конфигурациях, существует механизм "Даты запрета изменения данных". Этот механизм устанавливается администратором для предотвращения редактирования документов за прошедшие периоды, например, после сдачи отчетности.
Оценив все рассмотренные подходы, мы приходим к выводу, что наиболее безопасным, гибким и рекомендуемым подходом для решения данной задачи является использование расширения конфигурации. Расширение позволяет нам:
Номер и Дата доступными для редактирования секретарю, сохраняя при этом остальные поля в режиме только для просмотра или недоступными.Выбрав расширение, мы получаем надежное и поддерживаемое решение, которое гармонично вписывается в архитектуру 1С:Предприятия и позволяет нам предоставить секретарю необходимый функционал без ущерба для безопасности и целостности данных.