Как правильно реализовать дату запрета редактирования в самописной конфигурации 1С

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

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

Почему проверки в модуле документа недостаточно

Проанализируем типичную ситуацию: разработчик добавляет константу ДатаЗапретаИзменений и в модуле каждого документа прописывает отказ в ОбработкаПроведения. На первый взгляд это работает, но давайте выясним причину, по которой такой подход считается небезопасным. Во-первых, процедура проведения срабатывает только при попытке провести документ. Пользователь может просто нажать «Записать», изменив при этом любой реквизит (например, сумму или контрагента), и данные в базе изменятся без фактического перепроведения. Во-вторых, обычное удаление объекта вообще не задействует механизмы проведения. Для полноценной защиты нам потребуется комплексный подход, включающий подписки на события и настройку прав доступа.

Шаг 1: Реализация универсальной проверки через подписки на события

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

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


Процедура ЗапретИзмененийПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    // Если это загрузка данных (например, обмен), проверку обычно пропускают
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    ДатаЗапрета = Константы.ДатаЗапретаИзменений.Получить();
    
    // 1. Проверяем текущую дату документа
    Если Источник.Дата < ДатаЗапрета Тогда
        Сообщить("Документ находится в закрытом периоде (до " + Формат(ДатаЗапрета, "ДФ=dd.MM.yyyy") + ")");
        Отказ = Истина;
        Возврат;
    КонецЕсли;

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

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

Шаг 2: Запрет удаления документов

Даже если мы запретили запись, документ все еще можно пометить на удаление или удалить непосредственно (если у пользователя есть такие права). Чтобы предотвратить это, создадим еще одну подписку на событие — ПередУдалением.


Процедура ЗапретИзмененийПередУдалением(Источник, Отказ) Экспорт
    
    ДатаЗапрета = Константы.ДатаЗапретаИзменений.Получить();
    
    Если Источник.Дата < ДатаЗапрета Тогда
        Сообщить("Удаление документов в закрытом периоде запрещено!");
        Отказ = Истина;
    КонецЕсли;
    
КонецПроцедуры

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

Шаг 3: Улучшение пользовательского интерфейса (UX)

Проверка в ПередЗаписью надежна, но она срабатывает в самый последний момент. Пользователь может потратить 15 минут на заполнение документа и только при нажатии кнопки «Записать» узнать, что период закрыт. Это вызывает раздражение. Давайте сделаем интерфейс «дружелюбным» и заблокируем форму сразу при открытии.

Для этого в формах документов лучше использовать событие ПриЧтенииНаСервере. Установка свойства ТолькоПросмотр для всей формы — это самый простой и эффективный способ.


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    
    ДатаЗапрета = Константы.ДатаЗапретаИзменений.Получить();
    
    Если ТекущийОбъект.Дата < ДатаЗапрета Тогда
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;
    
КонецПроцедуры

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

Шаг 4: Оптимизация и расширение функционала

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

  1. Создадим параметр сеанса ТекущаяДатаЗапрета.
  2. В модуле сеанса, в процедуре УстановкаПараметровСеанса, пропишем инициализацию этого параметра.
  3. В подписках на события будем обращаться к ПараметрыСеанса.ТекущаяДатаЗапрета вместо Константы.ДатаЗапретаИзменений.Получить().

Если же простая константа перестанет удовлетворять требованиям бизнеса (например, когда бухгалтеру нужно разрешить правки в прошлом месяце, а менеджерам — нет), стоит перейти к использованию регистра сведений. В таком регистре можно хранить настройки в разрезе пользователей или групп пользователей. Проверка в подписке в этом случае будет искать наиболее подходящую запись для текущего пользователя.

Итоги и рекомендации

Подведем итог нашему исследованию. Для реализации качественной даты запрета в «нетленке» необходимо:

Следуя этим правилам, вы создадите механизм, который по надежности не уступает типовым решениям от фирмы 1С, оставаясь при этом максимально простым и понятным в сопровождении.

← На главную