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

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

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

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

1. Разделение понятий «Статус» и «Состояние»

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

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

2. Хранение статуса в реквизите документа

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

Преимущества:

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

Ограничения:

  1. Закрытый период: если документ уже проведен в закрытом периоде, изменение статуса стандартным способом вызовет ошибку контроля даты запрета изменения данных.
  2. Отсутствие истории: реквизит хранит только текущее значение, без информации о том, кто и когда изменил статус.

3. Хранение статуса в регистре сведений

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

Преимущества:

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

Ограничения:

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

4. Комбинированный (гибридный) подход

Для высоконагруженных систем оптимальным является совмещение обоих вариантов:

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

5. Реализация логики переходов (паттерн «Конечный автомат»)

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


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

6. Организация пользовательского интерфейса (UI)

Вместо размещения на форме множества кнопок для каждого возможного статуса с постоянным скрытием и отображением элементов, рекомендуется использовать следующие решения:

  1. Кнопка с выпадающим меню: на форму выносится единая командная панель или кнопка с подменю Установить статус, пункты которой формируются динамически при открытии или смене статуса на основе матрицы переходов.
  2. Проверка прав и заполнения: перед сменой статуса процедура проверяет заполненность обязательных для целевого статуса реквизитов и права текущего пользователя на совершение конкретного перехода.

7. Управление через бизнес-процессы

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

В этой схеме статус документа соответствует текущей активной точке маршрута бизнес-процесса, а смена статуса происходит автоматически при выполнении задач пользователями (объект ЗадачаИсполнителя).

← На главную