Как запретить неоперативное проведение документов задним числом в 1С?

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

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

Почему отключение интерактивного неоперативного проведения не помогает?

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

  1. Программный вызов проведения из формы документа. Право Интерактивное проведение неоперативное контролируется платформой исключительно при стандартном проведении через системные команды списка или формы. В большинстве типовых конфигураций (например, в «Управление торговлей 10.3») нажатие кнопки «ОК» или «Провести» перехватывается кодом модуля формы, где вызывается метод Записать(РежимЗаписиДокумента.Проведение). Для платформы такой вызов является программным. При программной записи проверяется только общее право Проведение, а интерактивные ограничения игнорируются.
  2. Сложение прав ролей. В системе «1С:Предприятие» права пользователя объединяются по логическому правилу «ИЛИ». Если пользователю назначена хотя бы одна дополнительная роль (например, базовая роль пользователя или роли, назначенные через группы), в которой разрешено неоперативное проведение, доступ будет предоставлен.
  3. Разница между понятиями «задним числом» и «неоперативно». Неоперативным считается проведение не только за прошлые дни, но и сегодняшним числом, если время документа меньше текущего системного времени, а также для документов, у которых в свойствах метаданных свойство ОперативноеПроведение установлено в значение Запретить.

Посмотрим на практические методы решения, позволяющие обойти эти ограничения.

Способ 1. Контроль через подписку на событие «ПередЗаписью»

Наиболее надежным способом запрета проведения задним числом на программном уровне конфигурации является создание подписки на событие. Этот метод перехватывает любую попытку проведения документа — как интерактивную, так и программную.

Разберем по шагам реализацию данного механизма:

  1. Создадим в дереве метаданных новую роль, например, ПравоНеоперативногоПроведения (для пользователей, которым проведение задним числом разрешено).
  2. Создадим общую подписку на событие, укажем в источнике необходимые документы (или ДокументОбъект), выберем событие ПередЗаписью.
  3. В обработчике подписки разместим проверку режима проведения и наличия прав у текущего пользователя.

Посмотрим на пример процедуры обработчика:


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

КонецПроцедуры

В этом коде мы анализируем параметр РежимПроведения. Если документ переводится в проведенное состояние и платформа определяет режим как РежимПроведенияДокумента.Неоперативный, выполнение транзакции прерывается установкой Отказ = Истина.

Способ 2. Использование механизма «Граница запрета изменения данных»

Если требуется запретить ввод и проведение документов за предыдущие дни без доработки конфигурации кодом, рассмотрим использование типового механизма даты запрета изменения данных.

В типовых конфигурациях за это отвечает регистр сведений ГраницыЗапретаИзмененияДанных. Чтобы не двигать границу вручную каждое утро, автоматизируем этот процесс:

  1. Через регламентное задание: в клиент-серверной базе настраиваем регламентное задание, которое запускается ежедневно в 00:01 и программно смещает границу запрета для нужных пользователей на конец предыдущего дня: КонецДня(ТекущаяДата() - 86400).
  2. При начале работы системы: если база данных работает в файловом режиме без постоянно активного сервера, вызов смещения границы даты запрета можно поместить в процедуру ПриНачалеРаботыСистемы. При входе первого пользователя система актуализирует дату запрета на вчерашнее число.

Важный нюанс: механизм даты запрета блокирует любые изменения в закрытом периоде (включая проведение за прошлые дни), однако он позволяет пользователю свободно проводить документы текущей датой неоперативно (например, в 16:00 провести документ с временем 10:00), если это не ограничено логикой подписки на событие.

Способ 3. Проверка даты документа в форме

Если требуется запретить пользователю менять дату документа на прошедшие дни непосредственно при интерактивной работе в окне документа, разберем настройку формы:

  1. В свойствах элемента управления поля Дата на форме устанавливаем флаг ТолькоПросмотр или отключаем доступность для пользователей без роли администратора.
  2. В обработчике события формы ПередЗаписью проанализируем соотношение дат:
    
    Если НачалоДня(ЭтотОбъект.Дата) < НачалоДня(ТекущаяДата()) Тогда
        Предупреждение("Запрещено вводить и проводить документы прошлыми датами!");
        Отказ = Истина;
    КонецЕсли;
    

Таким образом, для комплексной и надежной защиты от ввода документов задним числом рекомендуется совмещать подписку на событие ПередЗаписью (блокирующую неоперативное проведение на уровне ядра) и автоматическое смещение даты запрета изменения данных.

← На главную