Каталог решений - Маленькая хитрость СКД — выводим строки X раз

Маленькая хитрость СКД — выводим строки X раз

Маленькая хитрость СКД — выводим строки X раз

В наличии

Здесь я расскажу, как вывести в отчет СКД произвольное количество одинаковых строк.

Категория:

Описание

Был у меня как-то клиент, разрабатывали ему конфигурацию по управлению сетью хостелов.

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

Группировка по Хостелам и комнатам, детали: проживающий, дата заезда, планируемая дата выезда и что-то там еще по проживающим:

Комната 313 (5 мест)
   Иванов Иван Перович, 01.01.2016, 31.01.2016
   Пупкин Петр Васильевич, 05.01.2016, 25.01.2016
   СВОБОДНО
   СВОБОДНО 
   СВОБОДНО

Самое интересное и оказалось в том, что каждое свободное место в комнате должно выводиться отдельной строчкой.

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

Конечно, можно было бы быстренько состряпать отдельный отчет и сделать так:

Для i 1 по КоличествоСободныхМест Цикл
    ТабДок.Вывести("ОбластьСвободноеМесто");
КонецЦикла;

Но как только я давным давно познакомился С КД, я старался делать все отчеты с помощью компоновки. Причина в двух неоспоримых плюсах: быстрота разработки и гибкость настроек для пользователя. В 99% случаев я даже формы не создавал для отчетов, все прекрасно описывается в схеме компоновки. И псевдонимы полей, и списки значений, а если надо – можно пользоваться функциями общих модулей. В общем очень не хотел я делать шаг в прошлое, поэтому достаточно быстро в голове родился вариант решения. Томить не стану, вот оно само решение, набросал без метаданных, чтобы любой желающий смог быстро посмотреть его в консоли:
В 

ВЫБРАТЬ    0 КАК Число
ПОМЕСТИТЬ ВТ_До10
ОБЪЕДИНИТЬ
ВЫБРАТЬ    1
ОБЪЕДИНИТЬ
ВЫБРАТЬ    2
ОБЪЕДИНИТЬ
ВЫБРАТЬ    3
ОБЪЕДИНИТЬ
ВЫБРАТЬ    4
ОБЪЕДИНИТЬ
ВЫБРАТЬ    5
ОБЪЕДИНИТЬ
ВЫБРАТЬ    6
ОБЪЕДИНИТЬ
ВЫБРАТЬ    7
ОБЪЕДИНИТЬ
ВЫБРАТЬ    8
ОБЪЕДИНИТЬ
ВЫБРАТЬ    9
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_До10.Число * 10 + ВТ_До10_1.Число КАК Индекс
ПОМЕСТИТЬ ВТ_ПустыеСтроки
ИЗ
    ВТ_До10 КАК ВТ_До10,
    ВТ_До10 КАК ВТ_До10_1
//Повторить сколько угодно раз, ориентируясь на максимально возможный индекс
ГДЕ
    ВТ_До10.Число * 10 + ВТ_До10_1.Число > 0
;

////////////////////////////////////////////////////////////////////////////////
//Тестовые данные - Комнаты
ВЫБРАТЬ
    "Комната1" КАК Комната,
    5 КАК КоличествоМест
ПОМЕСТИТЬ ВТ_Комнаты

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    "Комната2",
    4
;

////////////////////////////////////////////////////////////////////////////////
//Тестовые данные - состояние проживающих
ВЫБРАТЬ
    "Комната1" КАК Комната,
    "Иванов Иван Иванович" КАК Постоялец,
    ДАТАВРЕМЯ(2016, 1, 1, 0, 0, 0) КАК ДатаЗаезда,
    ДАТАВРЕМЯ(2016, 1, 31, 0, 0, 0) КАК ПланируемаяДатаВыезда
ПОМЕСТИТЬ ВТ_ИнфорамцияОПроживающих

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    "Комната1",
    "Пупкин Петр Васильевич",
    ДАТАВРЕМЯ(2016, 1, 5, 0, 0, 0),
    ДАТАВРЕМЯ(2016, 1, 25, 0, 0, 0)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_ИнфорамцияОПроживающих.Комната,
    ВТ_ИнфорамцияОПроживающих.Постоялец,
    ВТ_ИнфорамцияОПроживающих.ДатаЗаезда,
    ВТ_ИнфорамцияОПроживающих.ПланируемаяДатаВыезда
ИЗ
    ВТ_ИнфорамцияОПроживающих КАК ВТ_ИнфорамцияОПроживающих

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    СвободныеМеста.Комната,
    "СВОБОДНО",
    NULL,
    NULL
ИЗ
    (ВЫБРАТЬ
        ВТ_Комнаты.Комната КАК Комната,
        ВТ_Комнаты.КоличествоМест - ЕСТЬNULL(КОЛИЧЕСТВО(ВТ_ИнфорамцияОПроживающих.Постоялец), 0) КАК СвободноМест
    ИЗ
        ВТ_Комнаты КАК ВТ_Комнаты
            ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИнфорамцияОПроживающих КАК ВТ_ИнфорамцияОПроживающих
            ПО ВТ_Комнаты.Комната = ВТ_ИнфорамцияОПроживающих.Комната
    
    СГРУППИРОВАТЬ ПО
        ВТ_Комнаты.Комната,
        ВТ_Комнаты.КоличествоМест) КАК СвободныеМеста
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ПустыеСтроки КАК ВТ_ПустыеСтроки
        ПО СвободныеМеста.СвободноМест >= ВТ_ПустыеСтроки.Индекс

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

has been added to your cart:
Оформление заказа