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

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

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

Вариант 1. Использование подчиненного регистра сведений

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

Преимущества подчиненного регистра:

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

Сложности реализации:

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


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

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

Вариант 2. Использование независимого регистра сведений

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

Почему программисты часто выбирают этот путь:

Риски использования независимого регистра:

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

Сравнение производительности и блокировок

Рассмотрим подробнее вопрос параллельной работы пользователей. Выбор типа регистра влияет на то, как база данных блокирует таблицы:

  1. Блокировки в подчиненном РС: Система блокирует записи по Регистратору. Это минимизирует конфликты, если разные пользователи меняют разные документы.
  2. Блокировки в независимом РС: Блокировка происходит по комбинации измерений. Если в качестве измерения у нас выступает ссылка на документ (ДокументОбъект), то ситуация схожа с подчиненным регистром.

Проанализируем структуру индексов в независимом периодическом РС. По умолчанию индекс строится как Период + Измерения. Если мы строим отчет по конкретному документу, а ссылка на документ является вторым или третьим измерением, поиск может замедлиться на больших объемах данных. В этом случае обязательно нужно установить признак Индексировать у измерения, содержащего ссылку на документ.

Безопасность и защита данных

Часто возникает вопрос: как защитить историю статусов от ручного изменения пользователями с полными правами? Посмотрим на пример реализации записи в независимый регистр через подписку на событие ПриЗаписи документа в расширении:


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

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

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

Методология 1С и БСП

Если мы работаем с современными типовыми конфигурациями (ERP, КА, УТ), стоит рассмотреть штатные механизмы Библиотеки Стандартных Подсистем (БСП). Разберем два альтернативных пути:

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

Подведем итог нашему анализу:

  1. Если ваша задача — создать простой лог событий («кто и когда нажал кнопку»), используйте независимый периодический регистр. Записывайте данные через подписки на события или непосредственно в коде АРМ.
  2. Если статус документа — это его критически важный ресурс, который должен жестко соответствовать состоянию проведения (например, статус «Проведен» или «К отгрузке»), используйте подчиненный регистр.
  3. Всегда индексируйте измерение со ссылкой на документ в независимом регистре, чтобы ваши отчеты не тормозили через год работы системы.
  4. Для защиты данных используйте привилегированные модули и ограничивайте права доступа через RLS (Record Level Security).

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

← На главную