Как в отчете на СКД по каждому документу вывести список связанных с ним документов-регистраторов (движений регистра)?

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

При разработке отчетов в системе 1С:Предприятие 8.3 часто возникает задача, когда необходимо представить данные в иерархическом виде: основной документ, а под ним – все документы, которые являются его регистраторами, то есть создали движения по регистрам, связанные с этим основным документом. Типичным примером является отчет по больничным листам, где для каждого больничного листа нужно увидеть, какие документы (например, начисления, отсутствие на работе) были связаны с ним. В этом руководстве мы подробно разберем, как реализовать такую структуру отчета с помощью Системы Компоновки Данных (СКД), используя несколько наборов данных и параметры связи. Отметим, что мы рассматриваем визуальную настройку.

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

Понимание проблемы: основной документ и его регистраторы

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

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

Шаг 1: Создание первого набора данных для основного документа

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

  1. Откройте схему компоновки данных (СКД) вашего отчета.
  2. Перейдите на вкладку "Наборы данных".
  3. Добавьте новый набор данных типа "Запрос".
  4. Сформируйте запрос для получения списка основных документов. Например, если мы ищем больничные листы, запрос может выглядеть так:
    
    ВЫБРАТЬ
        БольничныйЛист.Ссылка КАК БольничныйЛист,
        БольничныйЛист.Дата КАК ДатаБольничногоЛиста,
        БольничныйЛист.Сотрудник КАК Сотрудник
    ИЗ
        Документ.БольничныйЛист КАК БольничныйЛист
    

    Здесь БольничныйЛист.Ссылка – это уникальный идентификатор каждого документа "Больничный лист". Это поле будет ключевым для связи с вторым набором данных.

  5. Назовите этот набор данных, например, "ОсновныеДокументы".

Шаг 2: Создание второго набора данных для документов-регистраторов (движений регистров)

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

  1. Добавьте еще один новый набор данных типа "Запрос".
  2. Сформируйте запрос, который будет извлекать данные из виртуальной таблицы Движения нужного регистра. В нашем примере, предположим, что больничные листы могут создавать движения в регистре сведений НачисленияБольничныхЛистов или в регистре накопления ВзаиморасчетыПоЗарплате. Мы возьмем НачисленияБольничныхЛистов для примера.
    
    ВЫБРАТЬ
        ДвиженияРегистра.Регистратор КАК ДокументРегистратор,
        ДвиженияРегистра.Период КАК ДатаДвижения,
        ДвиженияРегистра.ВидДвижения КАК ВидДвижения,
        ДвиженияРегистра.Сотрудник КАК СотрудникДвижения,
        ДвиженияРегистра.БольничныйЛист КАК БольничныйЛистИзДвижения
    ИЗ
        РегистрСведений.НачисленияБольничныхЛистов.Движения КАК ДвиженияРегистра
    ГДЕ
        ДвиженияРегистра.БольничныйЛист = &БольничныйЛистПараметр
    

    Обратите внимание на строку ГДЕ ДвиженияРегистра.БольничныйЛист = &БольничныйЛистПараметр. Здесь &БольничныйЛистПараметр – это параметр запроса. Мы будем передавать в него значение ссылки на БольничныйЛист из первого набора данных.

    Если вам нужно получить регистраторы из нескольких регистров, вы можете либо сделать "Объединение" в рамках этого запроса, либо создать отдельные наборы данных для каждого регистра и затем объединить их через механизм СКД. Для простоты сейчас рассматриваем один регистр.

  3. Назовите этот набор данных, например, "ДвиженияРегистраторов".

Шаг 3: Настройка параметров связи между наборами данных

Это самый важный шаг. Нам нужно "сказать" СКД, что для каждого элемента из первого набора данных (ОсновныеДокументы) нужно выполнить запрос второго набора данных (ДвиженияРегистраторов), передав в него ссылку на текущий основной документ.

  1. В схеме компоновки данных перейдите на вкладку "Связи наборов данных".
  2. Добавьте новую связь.
  3. Укажите следующие параметры для связи:
    • Источник: Выберите набор данных "ОсновныеДокументы".
    • Приемник: Выберите набор данных "ДвиженияРегистраторов".
    • Нажмите кнопку "Параметры связи" (или перейдите на соответствующую вкладку, если она присутствует).
    • Создайте новый параметр связи:
      • Поле источника: Выберите поле БольничныйЛист из набора данных "ОсновныеДокументы". Это ссылка на документ "Больничный лист".
      • Поле приемника: Выберите параметр БольничныйЛистПараметр, который мы определили в запросе второго набора данных "ДвиженияРегистраторов".
      • Условие: Установите "Равно".

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

Шаг 4: Настройка структуры отчета в СКД

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

  1. Перейдите на вкладку "Настройки" в схеме компоновки данных.
  2. Добавьте новую группировку верхнего уровня – по полю Сотрудник из набора данных "ОсновныеДокументы" (если это актуально для вашего отчета).
  3. Внутри группировки Сотрудник добавьте следующую группировку – по полю БольничныйЛист из набора данных "ОсновныеДокументы". Это будет наш основной документ.
  4. Самое важное: Внутри группировки БольничныйЛист добавьте "Детальные записи". Убедитесь, что для этих детальных записей в поле "Используемые поля" (или в соответствующем списке) выбраны поля из набора данных "ДвиженияРегистраторов" (например, ДокументРегистратор, ДатаДвижения, ВидДвижения).
  5. Настройте выбранные поля для отображения в отчете.
  6. При необходимости добавьте сортировки, условное оформление и другие элементы дизайна отчета. Если стандартные заголовки колонок не вписываются в концепцию, может потребоваться программное изменение заголовка группировки для более тонкой настройки вывода.

Пример желаемой структуры в макете СКД будет выглядеть примерно так:


- Сотрудник (Группировка из "ОсновныеДокументы")
    - БольничныйЛист (Группировка из "ОсновныеДокументы")
        - Детальные записи (из "ДвиженияРегистраторов")
            - Поле: ДокументРегистратор
            - Поле: ДатаДвижения
            - Поле: ВидДвижения

Пример работы с несколькими регистрами или дополнительными полями

Что делать, если нужные регистраторы находятся в нескольких регистрах? Есть несколько подходов:

  1. Объединение запросов во втором наборе данных: Вы можете использовать оператор ОБЪЕДИНИТЬ ВСЕ в запросе второго набора данных для сбора данных из разных виртуальных таблиц Движения разных регистров. Главное, чтобы структуры выбираемых полей были совместимы.
    
    ВЫБРАТЬ
        ДвиженияРС.Регистратор КАК ДокументРегистратор,
        ДвиженияРС.Период КАК ДатаДвижения,
        "РегистрСведений" КАК ТипРегистра,
        ДвиженияРС.БольничныйЛист КАК БольничныйЛистИзДвижения
    ИЗ
        РегистрСведений.НачисленияБольничныхЛистов.Движения КАК ДвиженияРС
    ГДЕ
        ДвиженияРС.БольничныйЛист = &БольничныйЛистПараметр
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ДвиженияРН.Регистратор КАК ДокументРегистратор,
        ДвиженияРН.Период КАК ДатаДвижения,
        "РегистрНакопления" КАК ТипРегистра,
        ДвиженияРН.ИзмерениеБольничныйЛист КАК БольничныйЛистИзДвижения
    ИЗ
        РегистрНакопления.ВзаиморасчетыПоЗарплате.Движения КАК ДвиженияРН
    ГДЕ
        ДвиженияРН.ИзмерениеБольничныйЛист = &БольничныйЛистПараметр
    

    Обратите внимание на добавление поля ТипРегистра для лучшего понимания источника данных в отчете и на возможное различие в именах полей (например, БольничныйЛист и ИзмерениеБольничныйЛист).

  2. Несколько наборов данных-приемников: Вы можете создать отдельные наборы данных для каждого регистра (например, "ДвиженияРС", "ДвиженияРН") и установить отдельные параметры связи от "ОсновныеДокументы" к каждому из них. В редких случаях, когда логика становится слишком сложной, некоторые разработчики даже используют две разных схемы в отчете СКД, хотя обычно достаточно грамотного использования группировок.

Важные аспекты и советы

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

← На главную