При разработке конфигураций для учета материальных ценностей, таких как библиотека, часто возникает вопрос: как отслеживать не просто общее количество товара, а каждый конкретный экземпляр? В этой статье мы разберем архитектурный подход к решению этой задачи, проанализируем ошибки начинающих разработчиков и сформируем правильную структуру данных для работы с уникальными номерами экземпляров.
Представим ситуацию: в библиотеку поступает 10 экземпляров книги "Евгений Онегин". У каждого экземпляра есть свой уникальный инвентарный номер. Нам необходимо знать, где находится каждый конкретный номер в любой момент времени: в архиве, на полке или у конкретного читателя. Типичная ошибка новичка — попытка «перезаписывать» или «удалять» записи в регистре сведений при смене владельца книги. Разберем, почему это тупиковый путь и как сделать правильно.
Первое, что нам необходимо сделать, — это отделить сущность «Книга» (название, автор, описание) от сущности «Экземпляр» (конкретный физический объект с номером). Простая запись номера в регистр сведений ограничивает возможности системы. Рассмотрим, почему лучше использовать подчиненный справочник.
Создадим справочник ЭкземплярыКниг и сделаем его подчиненным справочнику Книги. Это позволит нам:
Для того чтобы знать, где находится книга, нам не нужно удалять старые записи. Нам нужно хранить историю состояний. Для этого мы создадим РегистрСведений.СостоянияЭкземпляров.
Проанализируем необходимые настройки регистра:
Экземпляр (Тип: СправочникСсылка.ЭкземплярыКниг).Состояние (Перечисление: ВБиблиотеке, НаРуках, Списана) и Абонент (Тип: СправочникСсылка.Пользователи).Теперь разберем, как документы должны взаимодействовать с нашим регистром. Основная идея заключается в том, что каждый новый документ «перекрывает» своим состоянием предыдущую запись в истории.
Документ «Поступление»:
При поступлении книг мы должны программно создать элементы в справочнике ЭкземплярыКниг. В модуле проведения документа мы записываем в регистр сведения: Экземпляр №1 — Состояние: "В библиотеке".
Документ «Выдача»:
Когда читатель берет книгу, документ «Выдача» создает новую запись в регистре с тем же измерением Экземпляр, но с новым ресурсом Абонент. Система не удаляет запись о поступлении, она просто добавляет новую строку с более поздней датой.
Посмотрим на пример кода в модуле проведения документа ВыдачаКниги:
Процедура ОбработкаПроведения(Отказ, Режим)
// Создаем набор записей регистра
Движения.СостоянияЭкземпляров.Записывать = Истина;
Для Каждого ТекСтрокаКниги Из СписокКниг Цикл
Движение = Движения.СостоянияЭкземпляров.Добавить();
Движение.Период = Дата;
Движение.Экземпляр = ТекСтрокаКниги.Экземпляр;
Движение.Состояние = Перечисления.СостоянияКниг.НаРуках;
Движение.Абонент = Абонент;
КонецЦикла;
КонецПроцедуры
Самый важный вопрос: как понять, где книга сейчас, если в регистре хранятся сотни записей о её перемещениях? Для этого в 1С существует механизм Среза последних.
Метод СрезПоследних() позволяет получить наиболее актуальную запись на определенную дату. Если мы запросим срез на «текущий момент», система проигнорирует запись о поступлении (так как она старая) и выдаст запись о последней выдаче.
Проанализируем ситуацию в запросе для проверки остатков перед выдачей:
ВЫБРАТЬ
СостоянияСрезПоследних.Состояние КАК ТекущееСостояние,
СостоянияСрезПоследних.Абонент КАК ТекущийВладелец
ИЗ
РегистрСведений.СостоянияЭкземпляров.СрезПоследних(&МоментВремени, Экземпляр = &ВыбранныйЭкземпляр) КАК СостоянияСрезПоследних
Этот запрос всегда вернет только одну — самую актуальную — строку по конкретному экземпляру. Если состояние равно "На руках", мы можем запретить проведение документа выдачи, чтобы избежать дублирования.
Рассмотрим аргументы против удаления записей, о котором задумывался автор темы:
Мы выяснили, что для эффективной работы библиотеки необходимо комбинировать справочники и периодические регистры сведений. Справочник Экземпляры дает нам уникальность объекта, а РегистрСведений — хронологию его жизни. Использование Среза последних избавляет разработчика от необходимости вручную управлять актуальностью данных, делегируя эту задачу платформе 1С.
Такой подход является стандартным (best practice) не только для библиотек, но и для любого пономерного учета: оборудования, транспортных средств или серийных номеров электроники.