В практике сопровождения систем на базе 1С:Предприятие 7.7 часто возникает задача разграничения прав доступа, которая выходит за рамки стандартных возможностей конфигуратора. Типичный сценарий: необходимо сделать так, чтобы определенные сотрудники могли просматривать документы, но не имели права их изменять. Кроме того, часто требуется ввести жесткое ограничение на редактирование документов, с момента создания которых прошло более суток. В отличие от платформы 8.x, где многие из этих функций реализуются механизмом RLS (Row Level Security) или простыми флажками в ролях, в "семерке" нам потребуется прибегнуть к программированию.
В данной статье мы подробно разберем, как реализовать такие ограничения, проанализируем различные подходы и выберем наиболее надежные методы защиты данных.
Рассмотрим самый простой способ, который предлагает типовая конфигурация (например, "Торговля и Склад" или "Бухгалтерия"). В системе существует механизм контроля даты запрета редактирования. Мы можем автоматизировать установку этой даты при входе пользователя в систему.
Для этого нам необходимо внести изменения в процедуру ПриНачалеРаботыСистемы, которая находится в Глобальном модуле. Проанализируем ситуацию: если мы хотим запретить редактирование всего, что было создано ранее текущего дня, мы можем использовать следующий код:
Процедура ПриНачалеРаботыСистемы()
// Проверяем, относится ли пользователь к категории ограниченных
Если НазваниеИнтерфейса() = "Продавец" Тогда
Константа.ДатаЗапретаРедактирования = ТекущаяДата() - 1;
КонецЕсли;
КонецПроцедуры
Однако у этого метода есть существенный недостаток. Константа ДатаЗапретаРедактирования является общей для всей базы. Если один пользователь войдет в систему и код изменит значение константы, это повлияет на всех остальных участников процесса. Поэтому, как правильно отметили участники обсуждения, более грамотным решением будет вынос даты запрета в Параметры пользователя или использование локальной переменной, которая проверяется при открытии форм.
Разберем более гибкий подход, который позволяет управлять доступностью формы индивидуально для каждого документа. Основной инструмент здесь — свойство формы ТолькоПросмотр. Мы можем изменять его в предопределенной процедуре ПриОткрытии.
Посмотрим на пример кода, который реализует логику: если документ создан не сегодня, он открывается только для чтения:
Процедура ПриОткрытии()
Если ДатаДокумента < ТекущаяДата() Тогда
Форма.ТолькоПросмотр(1);
Предупреждение("Редактирование старых документов запрещено!");
КонецЕсли;
КонецПроцедуры
Чтобы не прописывать этот код в каждом документе, мы можем использовать возможности Глобального модуля. В типовых решениях 7.7 часто встречается функция глПроверкаРазрешенияРедактирования(Конт). Давайте проанализируем, как ее модифицировать. Нам нужно передать в нее контекст формы и внутри проверить все условия.
Функция глПроверкаРазрешенияРедактирования(Конт) Экспорт
// 1. Проверяем полномочия пользователя
Если глПользовательОграничен = 1 Тогда
// 2. Проверяем дату документа
Если Конт.ДатаДокумента < ТекущаяДата() Тогда
Конт.Форма.ТолькоПросмотр(1);
Возврат 0; // Редактирование запрещено
КонецЕсли;
КонецЕсли;
Возврат 1; // Редактирование разрешено
КонецФункции
Иногда руководство ставит задачу более точно: запретить правки не просто со сменой календарного дня, а ровно через 24 часа после создания. В 1С 7.7 для этого нужно сравнивать и дату, и время документа. Выясним, как это реализовать программно.
Нам понадобится получить время документа с помощью функции СформироватьОтметкуВремени или через обращение к атрибутам Час, Минута, Секунда. Рассмотрим алгоритм расчета:
// Пример логики расчета 24 часов
ВремяДок = 0;
МинДок = 0;
СекДок = 0;
Док.ПолучитьВремя(ВремяДок, МинДок, СекДок);
СекундПрошло = (ТекущаяДата() - Док.ДатаДокумента) * 86400 +
(ТекущееВремя() - (ВремяДок * 3600 + МинДок * 60 + СекДок));
Если СекундПрошло > 86400 Тогда
Форма.ТолькоПросмотр(1);
КонецЕсли;
Этот метод гораздо надежнее, так как он учитывает реальный момент создания записи и не зависит от того, наступила ли полночь.
Вопрос автора включал и отчеты. В 1С 7.7 нет встроенного механизма запрета на запуск конкретных отчетов через права, если они не вынесены в отдельный интерфейс. Рассмотрим два пути решения этой задачи:
Сформировать, добавим проверку прав текущего пользователя.Пример реализации проверки в отчете:
Процедура Сформировать()
Если НазваниеРоли(ТекущийПользователь()) = "ОграниченныйДоступ" Тогда
Предупреждение("У вас нет прав на формирование этого отчета!");
Возврат;
КонецЕсли;
// ... далее идет основной код формирования отчета
КонецПроцедуры
Проанализируем ситуацию: опытный пользователь может попытаться обойти ограничение ТолькоПросмотр. Например, через контекстное меню в журнале документов, выбрав пункт "Пометить на удаление", или используя внешние обработки. Чтобы закрыть эти "дыры", необходимо выполнить следующие шаги:
ТолькоПросмотр защищает только форму. Чтобы защитить сам объект в базе, нужно добавить проверку в процедуру ПриЗаписи в модуле каждого документа.
Процедура ПриЗаписи()
Если (ДатаДокумента < ТекущаяДата()) И (ЗапретРедактирования = 1) Тогда
Предупреждение("Запись старого документа невозможна!");
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Если стандартных средств недостаточно, мы рекомендуем обратить внимание на внешнюю компоненту FormEx. Она позволяет расширить возможности интерфейса 1С 7.7. С её помощью можно перехватывать любые события формы, управлять доступностью отдельных кнопок и даже раскрашивать строки в списках. Например, документы, которые уже нельзя редактировать, можно выделить в журнале серым цветом, чтобы пользователь заранее видел ограничения.
Подводя итог, можно сказать, что реализация ограничения доступа в 1С 7.7 требует комплексного подхода: сочетания настроек в Конфигураторе (роли и интерфейсы) и программного кода в Глобальном модуле и модулях форм. Правильное использование процедуры ПриОткрытии в связке с ТолькоПросмотр и контролем ПриЗаписи позволит создать надежную систему защиты данных от несанкционированного изменения.