Вопрос ограничения прав доступа на уровне конкретных записей (так называемый RLS — Record Level Security) в современных версиях 1С решается штатными средствами. Однако для платформы 1С:Предприятие 7.7, особенно в конфигурациях вроде "Торговля и склад", эта задача превращается в настоящий технический вызов. Проблема заключается в том, что в "семерке" права доступа в конфигураторе настраиваются только на объекты метаданных целиком: пользователь либо видит все документы данного вида, либо не видит ни одного.
В этой статье мы подробно разберем, как можно обойти это ограничение, проанализируем различные подходы — от простых программных фильтров до использования внешних компонент — и выясним, какой метод наиболее эффективен для баз формата DBF и SQL.
Самый очевидный путь — это использование встроенного механизма отборов. Рассмотрим ситуацию, когда нам нужно, чтобы менеджер видел только «своих» контрагентов и документы по ним. Для этого сначала необходимо определить критерий фильтрации. Чаще всего в справочнике Пользователи создается дополнительный реквизит (например, список разрешенных контрагентов или ссылка на основного менеджера).
Проанализируем алгоритм действий:
Контрагенты и во всех необходимых журналах документов (или формах списков документов) мы прописываем код в процедуре ПриОткрытии().УстановитьОтбор(), чтобы ограничить выборку.Разберем пример кода для формы списка журнала:
Процедура ПриОткрытии()
// Предположим, у нас есть глобальная переменная ТекущийМенеджер
Если ПустоеЗначение(ТекущийМенеджер) = 0 Тогда
// Устанавливаем отбор по контрагенту, если журнал позволяет
// Или используем встроенную переменную для фильтрации
УстановитьОтбор("Контрагент", ТекущийКонтрагентИзСписка);
КонецЕсли;
КонецПроцедуры
Однако здесь мы сталкиваемся с серьезным ограничением платформы 7.7: стандартный метод УстановитьОтбор() работает только по одному значению и только по тем реквизитам, для которых в конфигураторе включен признак "Отбор". Если нам нужно разрешить менеджеру видеть группу контрагентов, штатных средств будет недостаточно.
Для решения проблемы фильтрации по нескольким значениям (массиву контрагентов) в поздних релизах платформы 7.7 (начиная с 21-го) появился метод ИспользоватьСписокОтбора(). Рассмотрим его применение. Мы можем сформировать объект типа СписокЗначений, наполнить его разрешенными контрагентами и передать в журнал.
Посмотрим на пример реализации:
Процедура ПриОткрытии()
СписокРазрешенных = СоздатьОбъект("СписокЗначений");
// Здесь логика заполнения списка из справочника Пользователи
ВыбратьСтрокиИзСправочникаДоступа(СписокРазрешенных);
// Применяем фильтр к текущей форме журнала
ИспользоватьСписокОтбора(СписокРазрешенных);
КонецПроцедуры
Важный нюанс: этот метод скрывает записи из визуального списка, но опытный пользователь может попытаться обойти его через инструменты поиска или переключение интервалов журнала. Поэтому совместно с этим методом необходимо программно блокировать кнопки настройки фильтров и соответствующие горячие клавиши в меню формы.
В типовых конфигурациях, таких как "Торговля и склад", отображение строк в журналах часто управляется через функции в глобальном модуле (например, глНазваниеДокументаВЖурнале). Рассмотрим этот "хитрый" способ ограничения видимости. Мы не удаляем строки из списка, но делаем их нечитаемыми для неавторизованных пользователей.
Выясним, как это работает:
Этот метод считается "малой кровью", так как он не требует переписывания архитектуры базы данных, но он несет чисто психологический эффект: пользователь видит наличие документа, но не знает его содержания.
Если ваша база работает в формате SQL, перед вами открываются гораздо более мощные возможности. Использование внешней компоненты 1С++ позволяет полностью заменить стандартные журналы документов на виртуальные, построенные на прямых SQL-запросах.
Проанализируем этот подход подробнее:
Вместо стандартного журнала создается экранная обработка. На форму помещается объект "ТабличноеПоле", который работает через ПоставщикДанных. При формировании запроса к базе данных мы в секцию WHERE добавляем жесткое условие фильтрации по контрагентам. Для пользователя это выглядит как обычный журнал, но на уровне SQL-запроса система просто «не знает» о существовании других документов.
Пример логики запроса (псевдокод SQL в 1С++):
ТекстЗапроса = "
|SELECT
| Журнал.IDDoc as [Документ $Документ],
| Журнал.IDDocDef as Документ_виды,
| $Общ.Контрагент as [Контрагент $Справочник.Контрагенты]
|FROM
| _1SJOURN as Журнал
|INNER JOIN
| $Документ.Реализация as Док ON Док.IDDoc = Журнал.IDDoc
|WHERE
| $Док.Контрагент IN (СписокРазрешенныхИД)
|";
Это самый надежный и быстрый способ, но он требует высокой квалификации программиста и перевода базы на SQL-версию.
Разберем ситуацию с форматом DBF, упомянутую в обсуждении. Главная проблема DBF в том, что любой пользователь, имеющий доступ к папке с базой, может просто скопировать файл 1SCONST.DBF или файлы документов и открыть их сторонней утилитой. Никакие программные ограничения внутри 1С здесь не помогут.
Чтобы действительно защитить данные в 1С 7.7 DBF, мы рекомендуем комплекс мер:
DB таким образом, чтобы пользователь имел права на чтение и запись файлов, но не имел права на «Просмотр содержимого папки». В этом случае 1С сможет работать с файлами, зная их имена, а пользователь через проводник не увидит список файлов и не сможет их украсть.Мы проанализировали ситуацию и пришли к выводу, что полноценный RLS в 1С 7.7 реализуем только при значительных трудозатратах. Если бюджет ограничен, стоит использовать программные фильтры ИспользоватьСписокОтбора() и модификацию глобальных функций отображения. Если же требования к безопасности высоки, единственным верным решением будет либо использование 1С++ на SQL-базе, либо переход на современную платформу 1С:Предприятие 8.3, где механизмы ограничения доступа по контрагентам встроены в ядро системы и настраиваются на уровне ролей без написания сложного кода.