Как реализовать отчет по загрузке номерного фонда и настроить структуру подчиненности для нетиповых документов?

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

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

Анализ исходной задачи и типичных ошибок

Рассмотрим ситуацию: нам необходимо вывести график загрузки номерного фонда, где по вертикали (в точках) отображается иерархия «Номер — Комната — Койка», а по горизонтали (на шкале времени) — периоды проживания гостей. В исходном коде автора мы видим использование объекта ДиаграммаГанта и попытку заполнить её данными из регистра сведений ЗагруженностьНФ.

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

Шаг 1. Оптимизация получения данных (избавляемся от запросов в цикле)

Для того чтобы отчет работал мгновенно, нам необходимо собрать все данные одним запросом. Мы будем использовать ЛЕВОЕ СОЕДИНЕНИЕ справочника номерного фонда с регистром занятости и группировку ИТОГИ ПО. Это позволит нам получить древовидную структуру данных сразу из результата запроса.

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


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Койки.Владелец.Владелец КАК НомерОбъект,
|	Койки.Владелец КАК КомнатаОбъект,
|	Койки.Ссылка КАК КойкаОбъект,
|	Загруженность.ДатаЗаселения КАК ДатаНачала,
|	Загруженность.ДатаВыезда КАК ДатаОкончания,
|	Загруженность.Статус КАК Статус
|ИЗ
|	Справочник.Койки КАК Койки
|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗагруженностьНФ КАК Загруженность
|		ПО Койки.Ссылка = Загруженность.КойкаПроживания
|ГДЕ
|	(Загруженность.Период МЕЖДУ &НачалоПериода И &КонецПериода ИЛИ Загруженность.Период ЕСТЬ NULL)
|УПОРЯДОЧИТЬ ПО
|	НомерОбъект.Наименование,
|	КомнатаОбъект.Наименование,
|	КойкаОбъект.Наименование
|ИТОГИ ПО
|	НомерОбъект,
|	КомнатаОбъект,
|	КойкаОбъект";

Запрос.УстановитьПараметр("НачалоПериода", Отчет.Период.ДатаНачала);
Запрос.УстановитьПараметр("КонецПериода", Отчет.Период.ДатаОкончания);
РезультатЗапроса = Запрос.Выполнить();

Шаг 2. Программное заполнение Диаграммы Ганта

Теперь, когда у нас есть оптимизированная выборка, разберем, как правильно перенести эти данные на диаграмму. Важно помнить, что ДиаграммаГанта состоит из трех основных сущностей: Точки (строки), Серии (легенда/категории) и Значения (сами полоски интервалов).

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

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


Процедура ЗаполнитьДиаграмму(РезультатЗапроса)
    ДГ.Очистить();
    ДГ.АвтоОпределениеПолногоИнтервала = Ложь;
    ДГ.УстановитьПолныйИнтервал(Отчет.Период.ДатаНачала, Отчет.Период.ДатаОкончания);
    
    СерияЗанято = ДГ.УстановитьСерию("Проживание");
    
    ВыборкаНомер = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    Пока ВыборкаНомер.Следующий() Цикл
        ТочкаНомер = ДГ.УстановитьТочку(ВыборкаНомер.НомерОбъект);
        
        ВыборкаКомната = ВыборкаНомер.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
        Пока ВыборкаКомната.Следующий() Цикл
            ТочкаКомната = ТочкаНомер.Точки.Добавить();
            ТочкаКомната.Значение = ВыборкаКомната.КомнатаОбъект;
            ТочкаКомната.Текст = Строка(ВыборкаКомната.КомнатаОбъект);
            
            ВыборкаКойка = ВыборкаКомната.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
            Пока ВыборкаКойка.Следующий() Цикл
                ТочкаКойка = ТочкаКомната.Точки.Добавить();
                ТочкаКойка.Значение = ВыборкаКойка.КойкаОбъект;
                
                ВыборкаДанные = ВыборкаКойка.Выбрать();
                Пока ВыборкаДанные.Следующий() Цикл
                    Если ВыборкаДанные.ДатаНачала = NULL Тогда Продолжить; КонецЕсли;
                    
                    // Устанавливаем интервал для конкретной койки
                    Значение = ДГ.ПолучитьЗначение(ТочкаКойка, СерияЗанято);
                    Интервал = Значение.Добавить();
                    Интервал.Начало = ВыборкаДанные.ДатаНачала;
                    Интервал.Конец = ВыборкаДанные.ДатаОкончания;
                    Интервал.Цвет = WebЦвета.ЦветМорскойВолны;
                    Интервал.Текст = "Гость: " + ВыборкаДанные.Статус;
                КонецЦикла;
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры

Шаг 3. Реализация структуры подчиненности в нетиповых документах

Когда мы работаем с самописными документами (например, «Заселение» или «Бронирование»), стандартная кнопка «Структура подчиненности» может не работать. Разберем два способа решения этой задачи.

Способ А: Использование Критериев отбора.
Это наиболее простой платформенный механизм. Выполним следующие действия в конфигураторе:

  1. Найдем ветку Общие -> Критерии отбора.
  2. Создадим новый объект, например, СвязанныеДокументы.
  3. На вкладке «Данные» укажем тип значения (те документы, которые будут выступать «родителями»).
  4. На вкладке «Состав» отметим реквизиты других документов, в которых хранится ссылка на наш родительский документ.

После этого платформа автоматически сможет строить дерево связей, используя этот критерий.

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

Шаг 4. Добавление интерактивности в отчет

Чтобы отчет был не просто «картинкой», а рабочим инструментом, добавим возможность открывать документы прямо из диаграммы. Проанализируем событие Выбор (или ПриНажатии в зависимости от версии платформы) элемента формы ДиаграммаГанта.

При двойном клике на полоску интервала мы можем получить данные:


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

Заключение

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

← На главную