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

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

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

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

Решение 1. Запись автора и даты в модуле объекта (Быстрый способ)

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

Для начала нам необходимо открыть конфигуратор и добавить в структуру нашего документа два новых реквизита:

  1. ДатаПоследнегоИзменения (тип: Дата, состав даты: Время и Дата)
  2. ПоследнийИзменивший (тип: СправочникСсылка.Пользователи)

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


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

Проанализируем ситуацию и выясним причину использования именно этих методов:

Решение 2. Ограничение доступа к полям формы (Только просмотр)

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

Посмотрим на пример настройки управляемой формы документа. Перейдите в редактор формы вашего документа и перетащите реквизиты ДатаПоследнегоИзменения и ПоследнийИзменивший на форму в виде полей ввода.

Чтобы заблокировать их редактирование для пользователя, выполните следующие действия:

  1. Выделите добавленный элемент формы (например, поле ДатаПоследнегоИзменения).
  2. В палитре свойств найдите категорию "Поведение" и установите флажок напротив свойства ТолькоПросмотр в значение Истина.
  3. Повторите операцию для второго поля.

Если требуется управлять доступностью динамически (например, разрешать редактирование только Администраторам), мы можем прописать это программно в обработчике формы ПриСозданииНаСервере:


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

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

Решение 3. Масштабирование задачи с помощью общих реквизитов и подписок

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

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

Разберем этот процесс по шагам:

Шаг 1. Создание Общих реквизитов.
В ветке метаданных конфигуратора перейдите в раздел Общие -> Общие реквизиты. Добавьте два реквизита: ОбщийАвторИзменения и ОбщаяДатаИзменения. В свойствах каждого из них откройте параметр "Состав" и укажите список документов информационной системы, в которых они должны присутствовать, установив для них режим "Использовать".

Шаг 2. Создание подписки на событие.
Чтобы автоматизировать заполнение, перейдите в раздел Общие -> Подписки на события и добавьте новую подписку:

Посмотрим на пример программного кода в общем модуле для автоматического заполнения общих реквизитов:


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

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

Решение 4. Оптимизация записи (Борьба с избыточными транзакциями)

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

Если мы будем перезаписывать автора при каждом таком техническом перепроведении, мы потеряем ценную информацию о том, какой реальный пользователь последним редактировал документ вручную. Нам будет казаться, что все документы изменил "Администратор" или "Робот".

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


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

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

Решение 5. Платформенный механизм «История данных»

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

Выясним основные преимущества платформенной "Истории данных" перед самописными решениями и механизмами версионирования БСП на базе регистра ВерсииОбъектов:

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

← На главную