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

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

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

Метод 1: Регистр накопления и принцип «баланса занятости»

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

Структура регистра:

Разберем логику работы этого механизма. Когда документ фиксирует занятость объекта, он делает запись в регистр с ресурсом «1». Когда период занятости заканчивается, создается запись с ресурсом «-1». Если же нам требуется сторнировать (отменить) бронь, документ сторно просто делает обратную запись (приход «-1»), которая в сумме с оригиналом даст ноль.

Проанализируем преимущества: проверка доступности на конкретную дату превращается в получение остатка по регистру. Если Остаток > 0 — объект занят. Если нам нужно проверить доступность на интервал, мы используем виртуальную таблицу ОстаткиИОбороты. Если на любом микро-периоде внутри искомого интервала остаток становится больше нуля, значит, объект в это время занят.

Метод 2: Регистр сведений с уникальным идентификатором интервала

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

Чтобы обойти это ограничение, добавим в структуру регистра измерение ИдентификаторИнтервала (тип: УникальныйИдентификатор или ссылка на документ-основание).

Рассмотрим алгоритм работы:

  1. При создании записи о занятости генерируется GUID.
  2. Запись фиксирует Объект, ДатаНачала (в ресурсе или периоде), ДатаОкончания и этот GUID.
  3. Для сторнирования мы создаем новую запись с тем же GUID, но устанавливаем специальный признак ЭтоСторно = Истина.

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


ВЫБРАТЬ
    Занятость.ОбъектЭксплуатации,
    Занятость.ДатаНачала,
    Занятость.ДатаОкончания
ИЗ
    РегистрСведений.ЗанятостьОбъектов КАК Занятость
ГДЕ
    Занятость.ИдентификаторИнтервала НЕ В (
        ВЫБРАТЬ
            Сторно.ИдентификаторИнтервала
        ИЗ
            РегистрСведений.ЗанятостьОбъектов КАК Сторно
        ГДЕ
            Сторно.Активность = Ложь ИЛИ Сторно.ЭтоСторно = Истина
    )

Метод 3: Использование регистра расчета и механизма вытеснения

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

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

Метод 4: Хранение интервалов как отрезков (Начало — Конец) в одной записи

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

Структура регистра:

Разберем, как проверить, свободен ли объект в периоде [Т_Начало, Т_Конец]. Нам нужно найти записи, которые пересекаются с нашим запросом. Математически условие пересечения двух отрезков выглядит так:


ГДЕ
    Регистр.ДатаНачала < &Т_Конец
    И Регистр.ДатаОкончания > &Т_Начало
    И Регистр.Актуально = Истина

Если запрос возвращает хотя бы одну запись — объект занят. Сторнирование в такой модели реализуется созданием записи с тем же Объектом и ДатойНачала, но с ресурсом Актуально = Ложь. При использовании СрезПоследних мы всегда будем видеть текущий статус этого интервала.

Рекомендации по выбору решения

Выясним, какой метод лучше подходит под ваши задачи:

  1. Если важна простота и скорость разработки: используйте Регистр Накопления (Метод 1). Он автоматически суммирует изменения и легко поддается сторнированию через стандартные механизмы движений.
  2. Если нужно хранить историю правок: (кто, когда и почему отменил бронь) — выбирайте Регистр Сведений с ИдентификаторомИнтервала (Метод 2). Это обеспечит полный аудит изменений.
  3. Если система предполагает сложные приоритеты занятости: (например, аварийный ремонт всегда «вытесняет» плановую работу) — не бойтесь использовать Регистр Расчета (Метод 3).
  4. Если требуется высокая производительность запросов на больших объемах данных: используйте хранение интервалов в одной записи (Метод 4). Условие пересечения отрезков крайне эффективно индексируется СУБД.

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

← На главную