Как исключить выбывшие основные средства из среза последних периодического регистра сведений?

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

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

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

Анализ исходной архитектурной ошибки (Many-to-Many vs Many-to-One)

Давайте проанализируем структуру регистра, предложенную автором темы в самом начале. Он выбрал периодический регистр сведений с двумя измерениями: РабочееМесто и ОС (Основное средство). Это классическая ошибка проектирования связей в базах данных.

Два измерения в регистре сведений создают связь вида "Многие-ко-Многим". Такая структура предполагает, что одно и то же уникальное основное средство может одновременно находиться на нескольких рабочих местах, а на одном рабочем месте может одновременно находиться множество различных ОС. Если второе утверждение верно (на одном столе могут стоять монитор, системный блок и принтер), то первое утверждение в реальном учете физически невозможно: уникальный компьютер с конкретным серийным номером не может одновременно стоять в двух разных кабинетах.

Следовательно, связь между основным средством и рабочим местом является связью вида "Многие-к-Одному" (у одного рабочего места может быть много ОС, но у каждого ОС может быть только одно рабочее место в конкретный момент времени). Для реализации такой связи в 1С применяется другое правило:

Уникальный объект (в данном случае ОС) должен быть единственным измерением регистра, а место его нахождения (РабочееМесто) должно быть ресурсом.

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

Проблема "засорения" среза последних при выбытии

Теперь рассмотрим ключевой вопрос автора: что происходит при уходе (списании) ОС и как сделать так, чтобы в срезе последних не было этой записи?

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

Давайте разберем три профессиональных паттерна решения этой проблемы.

Решение 1: Использование статуса или признака доступности (Базовый паттерн)

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

Когда оборудование списывается или утилизируется, документ-регистратор делает новую запись в этот регистр с текущим периодом (датой списания). При этом в ресурс РабочееМесто записывается пустая ссылка, а в ресурс Выбыл устанавливается значение Истина (или СтатусУчета принимает значение Списано).

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


ВЫБРАТЬ
    МестонахождениеОССрезПоследних.ОС КАК ОС,
    МестонахождениеОССрезПоследних.РабочееМесто КАК РабочееМесто
ИЗ
    РегистрСведений.МестонахождениеОС.СрезПоследних(&Период, ) КАК МестонахождениеОССрезПоследних
ГДЕ
    НЕ МестонахождениеОССрезПоследних.Выбыл

Этот запрос мгновенно отсечет все списанные основные средства. При этом на уровне СУБД срез последних будет работать очень эффективно.

Решение 2: Разделение на два регистра (Паттерн ERP / Бухгалтерия)

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

  1. Регистр сведений "История местонахождения ОС" — периодический регистр. Он хранит только факты перемещений оборудования между кабинетами и сотрудниками. В нем нет понятия "выбытия", там зафиксирована вся хронология жизни объекта.
  2. Регистр сведений "Состояния ОС" (или "Актуальное состояние") — непериодический регистр. Измерением является ОС, а ресурсами — текущее рабочее место и статус его активности. При списании ОС запись из этого регистра полностью физически удаляется (или перезаписывается). Соответственно, этот регистр всегда остается "чистым", легким и содержит только те данные, которые эксплуатируются прямо сейчас.

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


ВЫБРАТЬ
    АктуальноеСостояниеОС.ОС,
    АктуальноеСостояниеОС.РабочееМесто
ИЗ
    РегистрСведений.АктуальноеСостояниеОС КАК АктуальноеСостояниеОС
ГДЕ
    АктуальноеСостояниеОС.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияОС.Списано)

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

Решение 3: Интервальный регистр сведений (Паттерн ЗУП 3.1)

Этот современный паттерн проектирования активно применяется разработчиками фирмы 1С в конфигурации "Зарплата и управление персоналом" для хранения различных периодических состояний (например, плановых начислений или графиков работы сотрудников).

Мы создаем непериодический регистр сведений, но добавляем в него два обязательных реквизита даты: ДатаНачала и ДатаОкончания.

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

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


ВЫБРАТЬ
    ИнтервальныйУчетОС.ОС КАК ОС,
    ИнтервальныйУчетОС.РабочееМесто КАК РабочееМесто
ИЗ
    РегистрСведений.ИнтервальныйУчетОС КАК ИнтервальныйУчетОС
ГДЕ
    &Период МЕЖДУ ИнтервальныйУчетОС.ДатаНачала И ИнтервальныйУчетОС.ДатаОкончания

Поскольку у выбывшего ОС интервал времени закрыт датой списания, условие МЕЖДУ на текущую дату вернет ложь, и этот компьютер автоматически не попадет в выборку. При этом вся история перемещений остается в базе в виде красивых, непересекающихся временных интервалов.

Почему регистр накопления (РН) — это архитектурная ловушка

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

Автор рассуждал так: "При списании я сделаю движение по регистру накопления "в минус", остаток станет равным нулю, и запись автоматически исчезнет из таблицы остатков".

Это опасное заблуждение. Давайте разберем, как устроена работа СУБД с регистрами накопления остатков в 1С:

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

Оптимизация среза последних на уровне платформы 8.3

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

В свойствах периодического регистра сведений в Конфигураторе присутствует настройка "Разрешить итоги: Срез последних".

Давайте посмотрим, что дает включение этой опции:

  1. Платформа создает в СУБД отдельную реальную таблицу итогов среза последних (таблица с суффиксом _RG). В ней хранится ровно одна (самая последняя) запись по каждому уникальному измерению.
  2. При записи новых движений платформа сама обновляет эту таблицу.
  3. При выполнении запроса СрезПоследних без указания конкретной даты (то есть на текущее время), СУБД не рассчитывает срез по всей исторической таблице, содержащей миллионы строк. Она мгновенно считывает данные напрямую из готовой таблицы итогов.

Благодаря этому механизму, даже если ваше предприятие имеет миллионы записей истории перемещений оборудования, получение текущих остатков с использованием условия ГДЕ НЕ Выбыл будет выполняться за доли секунды. Главное — не забывать накладывать отборы по измерениям непосредственно в параметрах виртуальной таблицы среза последних, а не во внешнем условии ГДЕ запроса.

← На главную