Как ограничить просмотр оборотно-сальдовой ведомости по конкретному счету для отдельных пользователей в 1С:ERP?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Бухгалтерский учет IT и автоматизация бизнеса
← На главную

Рано или поздно перед разработчиками и системными архитекторами крупных баз на платформе 1С встает задача ограничения прав доступа внутри бухгалтерии. Самый частый сценарий — скрыть данные по 70 счету (расчеты с персоналом по оплате труда), чтобы рядовые бухгалтеры не видели заработные платы коллег и руководства. Аналогичные требования могут возникать для валютных счетов, кассы или расчетов с учредителями. Для комплексной защиты таких сведений можно использовать готовое расширение для ограничения доступа к зарплатным отчетам и документам.

В этой статье мы подробно разберем, почему стандартный механизм RLS (ограничение доступа на уровне записей) не подходит для решения этой задачи «в лоб», проанализируем возможные последствия и рассмотрим наиболее эффективные программные и организационные методы обхода этого ограничения.

---

Почему классический RLS на регистр бухгалтерии — это плохой путь?

Попытка настроить RLS непосредственно на регистр бухгалтерии Хозрасчетный или План счетов сталкивается с фундаментальными ограничениями платформы «1С:Предприятие» и методологии двойной записи:

  1. Нарушение принципа двойной записи: Бухгалтерская проводка всегда состоит из дебета одного счета и кредита другого. Если закрыть для пользователя счет 70, но оставить доступным счет 51 (расчетный счет), то при просмотре проводки по выплате зарплаты (Дт 70 - Кт 51) у пользователя возникнет коллизия. Система либо вообще скроет проводку (и тогда «поплывет» сальдо по открытому 51 счету), либо отобразит субконто и кор. счет как <Объект не найден>, что нарушит целостность отчетов.
  2. Проблема закрытия месяца и расчета итогов: При внедрении RLS на уровне регистра бухгалтерии (например, через добавление кастомного балансового измерения) платформа перестает корректно оптимизировать и сворачивать итоги для пользователей с ограниченными правами. Операция закрытия месяца может зависать, приводить к взаимоблокировкам СУБД или выдавать ошибки нехватки прав при выполнении регламентных операций под системными учетными записями.
  3. Ограничения производительности: Наложение сложных условий RLS на каждую запись гигантского регистра бухгалтерии в ERP драматически снижает скорость формирования любых отчетов (ОСВ, анализ счета, карточка счета) для всех пользователей.

Поэтому решать задачу необходимо либо на уровне интерфейса и компоновки отчетов, либо организационными методами.

---

Вариант 1. Организационное решение: учет «Сводно по сотрудникам»

Прежде чем приступать к написанию кода, проанализируем самый простой и надежный методологический путь. Если задача состоит в сокрытии детализации по зарплате (70 счет), то правильным решением будет отказ от ведения персонального учета сотрудников непосредственно в базе 1С:ERP.

Выясним, как это реализовать:

  1. Детальный расчет и начисление заработной платы выполняются в обособленной базе (например, 1С:ЗУП), доступ к которой имеет строго ограниченный круг лиц (расчетчик, главный бухгалтер, руководство). Для выделения кадрового и зарплатного контура в отдельную систему можно использовать перенос кадровых и расчётных данных ERP 2 — ЗУП 3.
  2. В настройках интеграции между 1С:ЗУП и 1С:ERP настраивается выгрузка данных сводно по сотрудникам, а для организации их регулярной передачи по расписанию применяется автоматический обмен данными между базами 1С.
  3. В самой 1С:ERP на 70 счете отключается ведение аналитики (субконто) по конкретным физическим лицам. Вместо этого все проводки идут на одно общее обезличенное субконто (например, «Все сотрудники»), а для контроля корректности таких итогов и поиска расхождений между базами можно запустить автоматическую сверку бухгалтерских проводок.

При таком подходе рядовые бухгалтеры видят общие обороты по 70 счету (что не является тайной, так как затраты на оплату труда все равно распределяются по публичным затратным счетам 20, 25, 26, 44), но физически не могут сопоставить суммы с конкретными персоналиями. Никаких доработок кода при этом не требуется.

---

Вариант 2. Программное ограничение формирования отчетов через расширение

Если административный вариант не подходит, и аналитика на счете должна быть, нам придется программно запретить пользователям без определенной роли формировать отчеты, в параметрах или отборах которых фигурирует запрещенный счет. Для решения этой задачи можно использовать готовое решение для ограничения видимости 70 счета.

Для реализации этого метода создадим профиль безопасности или роль, например, ДоступКЗакрытымСчетам. Пользователям, у которых этой роли нет, мы запретим выполнять отчеты. Все стандартные бухгалтерские отчеты в современных конфигурациях (ERP, КА, БП) проходят проверку заполнения настроек в общем модуле.

Разберем по шагам, как вклиниться в этот процесс с помощью механизма расширений:

  1. Создаем новое расширение конфигурации.
  2. Заимствуем в расширение общий модуль БухгалтерскиеОтчетыВызовСервера.
  3. Создаем метод-перехватчик для процедуры ОбработкаПроверкиЗаполнения с аннотацией &После.

Посмотрим на пример реализации кода в расширении:


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

// Вспомогательная функция для безопасного чтения свойств объекта
Функция Свойство(Объект, ИмяСвойства)
    Попытка
        Возврат Объект[ИмяСвойства] <> Неопределено;
    Исключение
        Возврат Ложь;
    КонецПопытки;
КонецФункции

Этот способ надежно защищает от формирования специализированных отчетов (например, «Карточка счета 70» или «ОСВ по счету 70»). Однако остается лазейка: пользователь может сформировать общую ОСВ по всему плану счетов и увидеть там итоговую строку по 70 счету.

---

Вариант 3. Исключение проводок запрещенного счета из общих отчетов

Чтобы закрыть лазейку с просмотром общих отчетов (где счет 70 выступает как один из многих или как корреспондирующий), нам потребуется вмешаться в процесс формирования выборки данных. Рассмотрим, как решить эту задачу в модуле менеджера отчета (например, ОСВ) перед компоновкой макета.

Проанализируем ситуацию: в запросах получения движений нам нужно полностью отсечь проводки, в которых задействован наш запрещенный счет. Сделать это нужно как для дебетовой, так и для кредитовой стороны проводки.

Важный логический нюанс: при написании условий исключения разработчики часто допускают ошибку в логических операторах И / ИЛИ. Если мы хотим убрать проводки, где хотя бы одна из сторон равна запрещенному счету, условие отбора в запросе должно выглядеть следующим образом:

ГДЕ Движения.СчетДт <> &ЗапрещенныйСчет И Движения.СчетКт <> &ЗапрещенныйСчет

Если написать через ИЛИ (СчетДт <> 70 ИЛИ СчетКт <> 70), то под отбор попадет проводка, где Дт равен 70, а Кт равен 51 (так как 51 действительно не равен 70, и условие ИЛИ вернет Истину). Использование оператора И гарантирует, что проводка будет выбрана только в том случае, если ни одна из ее сторон не содержит запрещенный счет.

Внедрить это условие можно через перехват компоновщика настроек в процедуре ПередКомпоновкойМакета менеджера отчета в расширении:


&Перед("ПередКомпоновкойМакета")
Процедура Расш_ПередКомпоновкойМакета(ПараметрыМакета, КомпоновщикНастроек, СхемаКомпоновкиДанных)
    
    Если Не РольДоступна("ДоступКЗакрытымСчетам") Тогда
        
        ЗапрещенныйСчет = ПланыСчетов.Хозрасчетный.НайтиПоКоду("10.06"); // Пример для теста
        
        // Добавляем жесткий отбор в настройки компоновщика программно
        ГруппаОтбора = КомпоновщикНастроек.Settings.Filter.Elements.Add(Type("ГруппаЭлементовОтбораКомпоновкиДанных"));
        ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
        ГруппаОтбора.Использование = Истина;
        
        ЭлементОтбораДт = ГруппаОтбора.Elements.Add(Type("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбораДт.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СчетДт");
        ЭлементОтбораДт.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавен;
        ЭлементОтбораДт.ПравоеЗначение = ЗапрещенныйСчет;
        ЭлементОтбораДт.Использование = Истина;
        
        ЭлементОтбораКт = ГруппаОтбора.Elements.Add(Type("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбораКт.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СчетКт");
        ЭлементОтбораКт.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавен;
        ЭлементОтбораКт.ПравоеЗначение = ЗапрещенныйСчет;
        ЭлементОтбораКт.Использование = Истина;
        
    КонецЕсли;
    
КонецПроцедуры

При таком подходе любые формируемые пользователем отчёты будут выводить данные корректно для открытых счетов, но все проводки, корреспондирующие с закрытым счетом, будут просто отсекаться из результата компоновки данных. Итоговые суммы по открытым счетам будут уменьшены на суммы скрытых проводок. Бухгалтер должен быть предупрежден о том, что при отсутствии прав итоговый баланс в его отчетах может «не сходиться».

---

Резюме и рекомендации

Полностью и бесшовно скрыть бухгалтерский счет в типовой конфигурации 1С без методологических последствий невозможно. Выбирая стратегию реализации, придерживайтесь следующих правил:

← На главную