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

Программист Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

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

Анализ проблемы: почему справочник — это не место для оперативных данных

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

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

Шаг 1. Создание структуры хранения данных через регистр

Вместо использования табличной части в справочнике Посетители, создадим документ ВыдачаКниги и периодический регистр сведений СостояниеКниг. Рассмотрим структуру регистра:

  1. Измерение: Книга (тип СправочникСсылка.Книги). Это ключевое поле, по которому мы будем искать информацию.
  2. Ресурс: Читатель (тип СправочникСсылка.Посетители).
  3. Ресурс: ПредполагаемаяДатаВозврата (тип Дата).

Теперь, при проведении документа ВыдачаКниги, мы будем записывать данные в этот регистр. Это позволит нам всегда знать «Срез последних» данных — то есть текущее состояние каждой книги на любой момент времени.

Шаг 2. Программное получение ссылки на книгу из табличной части

Разберем вопрос автора о том, как получить ссылку на книгу при ее выборе в табличной части. Если вы работаете в форме документа, и вам нужно обработать изменение строки, используйте свойство ТекущиеДанные. Рассмотрим пример кода для обработчика события ПриИзменении в табличной части:


&НаКлиенте
Процедура СписокКнигКнигаПриИзменении(Элемент)
    // Получаем строку, в которой произошло изменение
    ТекущаяСтрока = Элементы.СписокКниг.ТекущиеДанные;
    
    Если ТекущаяСтрока <> Неопределено Тогда
        // Обращаемся к ссылке на книгу
        ВыбраннаяКнига = ТекущаяСтрока.Книга;
        
        // Здесь можно выполнить дополнительные действия, например,
        // заполнить дату выдачи по умолчанию
        ТекущаяСтрока.ДатаВыдачи = ТекущийДатуСеанса();
    КонецЕсли;
КонецПроцедуры

Если же задача стоит в том, чтобы обойти всю таблицу при записи или проведении документа на сервере, проанализируем следующий цикл:


// В модуле объекта документа
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    Для Каждого СтрокаТЧ Из СписокКниг Цикл
        // СтрокаТЧ.Книга — это и есть нужная нам ссылка
        Запись = Движения.СостояниеКниг.Добавить();
        Запись.Период = Дата;
        Запись.Книга = СтрокаТЧ.Книга;
        Запись.Читатель = Посетитель; // Реквизит шапки
        Запись.ПредполагаемаяДатаВозврата = СтрокаТЧ.ДатаВозврата;
    КонецЦикла;
КонецПроцедуры

Шаг 3. Визуализация владельца в списке книг (Динамический список)

Чтобы выполнить условие «в справочнике книг должна быть возможность быстро посмотреть, у кого на руках находится книга», не изменяя сам справочник, мы воспользуемся механизмом Динамического списка с произвольным запросом. Разберем, как это настроить в форме списка справочника Книги.

В свойствах списка установим флаг «Произвольный запрос» и напишем следующий текст запроса:


ВЫБРАТЬ
    СправочникКниги.Ссылка КАК Ссылка,
    СправочникКниги.Наименование КАК Наименование,
    СправочникКниги.Автор КАК Автор,
    СостояниеКнигСрезПоследних.Читатель КАК ТекущийДержатель,
    СостояниеКнигСрезПоследних.ПредполагаемаяДатаВозврата КАК ДатаВозврата
ИЗ
    Справочник.Книги КАК СправочникКниги
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостояниеКниг.СрезПоследних(&Период, ) КАК СостояниеКнигСрезПоследних
        ПО СправочникКниги.Ссылка = СостояниеКнигСрезПоследних.Книга

Благодаря ЛЕВОЕ СОЕДИНЕНИЕ, в списке отобразятся все книги. Если книга выдана — в колонке ТекущийДержатель будет указан человек, если книга в библиотеке — поле останется пустым. Это самый эффективный способ отображения оперативных данных.

Шаг 4. Обработка статуса «Просрочена» и условное оформление

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

Рассмотрим, как добавить визуальное выделение просроченных книг в списке. Для этого в настройках динамического списка (вкладка «Условное оформление») создадим новое правило:

  1. Оформление: Цвет текста — Красный.
  2. Условие: ДатаВозврата меньше &ТекущаяДата И ТекущийДержатель заполнено.
  3. Оформляемые поля: Вся строка или поле ДатаВозврата.

Теперь администратор при открытии списка книг мгновенно увидит проблемные позиции без необходимости запускать отдельные отчеты.

Шаг 5. Контроль при выдаче (Проверка на доступность)

Проанализируем ситуацию: что если администратор попытается выдать книгу, которая уже занята? Для этого в документе ВыдачаКниги перед записью или проведением необходимо добавить проверку. Мы должны обратиться к тому же регистру сведений и проверить наличие записи по конкретной книге.


Функция КнигаСвободна(ПроверяемаяКнига)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   СостояниеКнигСрезПоследних.Читатель
        |ИЗ
        |   РегистрСведений.СостояниеКниг.СрезПоследних(, Книга = &Книга) КАК СостояниеКнигСрезПоследних";
    
    Запрос.УстановитьПараметр("Книга", ПроверяемаяКнига);
    Результат = Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат Истина; // Записей нет, книга в библиотеке
    Иначе
        Выборка = Результат.Выбрать();
        Выборка.Следующий();
        // Если читатель не заполнен (например, зафиксирован возврат), книга свободна
        Возврат Не ЗначениеЗаполнено(Выборка.Читатель);
    EndIf;
КонецФункции

Резюме

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

← На главную