Как запретить помечать на удаление записи при заданных условиях

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

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

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

  1. Этот механизм автоматически блокирует не только запись новых движений, но и любые изменения реквизитов, включая ПометкаУдаления (удобно настраивать изменение запрета по группам).
  2. Настройка позволяет гибко разграничить права: запретить редактирование всем пользователям, кроме администраторов или бухгалтеров, ответственных за закрытие периода.
  3. Система проверяет дату документа. Если она меньше или равна установленной дате запрета, любое интерактивное действие будет пресечено платформой.

Если же штатный механизм по каким-то причинам не подходит (например, требуется динамическое условие, зависящее от работы конкретной обработки в данный момент), перейдем к программным методам.

Способ 2. Подписка на событие «ПередЗаписью» (Универсальный метод)

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

Разберем по шагам создание такой проверки:

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

Посмотрим на пример кода, который позволяет определить, что документ именно сейчас помечается на удаление:


Процедура ПроверитьЗапретПометкиНаУдаление(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

    // Если это новый документ, проверка не нужна
    Если Источник.ЭтоНовый() Тогда
        Возврат;
    КонецЕсли;

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

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

Важный нюанс: Обращение к Источник.Ссылка внутри события ПередЗаписью позволяет получить состояние объекта до момента его изменения. Это критически важно для определения факта установки пометки.

Способ 3. Использование обработчика «ОбработкаУдаленияПроведения»

Рассмотрим ситуацию, когда пользователь пытается пометить на удаление уже проведенный документ. В 1С это действие всегда инициирует отмену проведения. Следовательно, мы можем использовать модуль объекта самого документа.

Проанализируем пример кода в модуле объекта:


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

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

Этот метод хорош тем, что он срабатывает при попытке снять проведение из любого интерфейсного места: из формы документа, из списка или из окна Структура подчиненности. Однако помните, что он не сработает, если документ изначально не был проведен.

Способ 4. Проверка в формах списка (UI-контроль)

Для улучшения пользовательского опыта (UX) полезно пресекать действия еще до того, как они попадут в транзакцию записи базы данных. В обычных формах (как в УПП 1.3) для этого используется событие формы списка ПередУстановкойПометкиУдаления.

Рассмотрим пример реализации в форме списка документа ОтчетОПроизводствеЗаСмену:


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

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

Важное ограничение: Проверки в формах не являются абсолютной защитой. Они легко обходятся программными обработками или действиями в других связанных формах. Поэтому их следует использовать только как дополнение к методам в МодулеОбъекта или Подписках на события.

Способ 5. Ограничение через RLS (Record Level Security)

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

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

Рекомендации по снижению количества блокировок

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

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

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

← На главную