В практике разработки на платформе 1С часто возникает задача учета занятости некоего объекта (оборудования, сотрудника, помещения) на определенный период времени. Классическая схема «начало — Истина, конец — Ложь» в периодическом регистре сведений хорошо работает для простых случаев, но пасует перед требованием бизнес-процесса: реализовать сторнирование (отмену) занятости без правки движений исходного документа. Рассмотрим подробнее, как спроектировать надежную архитектуру для решения этой задачи, проанализируем различные подходы и выберем оптимальные методы реализации.
Рассмотрим вариант перехода от регистра сведений к регистру накопления. Этот подход часто недооценивают в задачах учета времени, однако он обладает встроенным механизмом работы с изменениями и сторно. Мы можем представить «занятость» как ресурс, который можно суммировать.
Структура регистра:
ОбъектЭксплуатации.Занятость (тип: Число).Разберем логику работы этого механизма. Когда документ фиксирует занятость объекта, он делает запись в регистр с ресурсом «1». Когда период занятости заканчивается, создается запись с ресурсом «-1». Если же нам требуется сторнировать (отменить) бронь, документ сторно просто делает обратную запись (приход «-1»), которая в сумме с оригиналом даст ноль.
Проанализируем преимущества: проверка доступности на конкретную дату превращается в получение остатка по регистру. Если Остаток > 0 — объект занят. Если нам нужно проверить доступность на интервал, мы используем виртуальную таблицу ОстаткиИОбороты. Если на любом микро-периоде внутри искомого интервала остаток становится больше нуля, значит, объект в это время занят.
Если специфика задачи требует использования регистра сведений (например, нужно хранить дополнительные данные о брони), мы столкнемся с проблемой ключа записи. В 1С ключ записи периодического регистра состоит из периода и измерений. Если мы попытаемся записать «отмену» на ту же дату начала, система выдаст ошибку неуникальности.
Чтобы обойти это ограничение, добавим в структуру регистра измерение ИдентификаторИнтервала (тип: УникальныйИдентификатор или ссылка на документ-основание).
Рассмотрим алгоритм работы:
Объект, ДатаНачала (в ресурсе или периоде), ДатаОкончания и этот GUID.GUID, но устанавливаем специальный признак ЭтоСторно = Истина.При получении актуальных данных нам достаточно выполнить запрос, который исключит пары записей с одинаковым идентификатором, где есть признак сторно. Посмотрим на пример логики запроса:
ВЫБРАТЬ
Занятость.ОбъектЭксплуатации,
Занятость.ДатаНачала,
Занятость.ДатаОкончания
ИЗ
РегистрСведений.ЗанятостьОбъектов КАК Занятость
ГДЕ
Занятость.ИдентификаторИнтервала НЕ В (
ВЫБРАТЬ
Сторно.ИдентификаторИнтервала
ИЗ
РегистрСведений.ЗанятостьОбъектов КАК Сторно
ГДЕ
Сторно.Активность = Ложь ИЛИ Сторно.ЭтоСторно = Истина
)
Проанализируем наиболее мощный, но и более сложный инструмент — регистр расчета. В типовых конфигурациях (ЗУП, ERP) периоды занятости (отпуска, больничные) учитываются именно здесь. Главная ценность регистра расчета — механизм вытеснения.
Выясним причину, по которой это может быть полезно: если один интервал (например, «Ремонт») должен перекрывать другой («Работа»), система сама рассчитает фактические периоды действия. Сторнирование в регистрах расчета является штатной операцией (документ «Сторнирование»), которая корректно вытесняет или отменяет записи прошлого периода, не меняя сами документы прошлого периода. Это полностью соответствует требованию неизменности данных.
Вместо того чтобы хранить две записи (точку входа и точку выхода), мы можем хранить интервал целиком в одной записи независимого регистра сведений. Это значительно упрощает проверку пересечений.
Структура регистра:
Объект, ДатаНачала (Период регистра).ДатаОкончания, Актуально (Булево).Разберем, как проверить, свободен ли объект в периоде [Т_Начало, Т_Конец]. Нам нужно найти записи, которые пересекаются с нашим запросом. Математически условие пересечения двух отрезков выглядит так:
ГДЕ
Регистр.ДатаНачала < &Т_Конец
И Регистр.ДатаОкончания > &Т_Начало
И Регистр.Актуально = Истина
Если запрос возвращает хотя бы одну запись — объект занят. Сторнирование в такой модели реализуется созданием записи с тем же Объектом и ДатойНачала, но с ресурсом Актуально = Ложь. При использовании СрезПоследних мы всегда будем видеть текущий статус этого интервала.
Выясним, какой метод лучше подходит под ваши задачи:
ИдентификаторомИнтервала (Метод 2). Это обеспечит полный аудит изменений.Важный нюанс: при проектировании всегда учитывайте человеческий фактор и ошибки ввода. Использование сторнирующих документов — это признак зрелой архитектуры, так как оно сохраняет след первоначального управленческого решения, что критически важно для последующего бизнес-анализа.