Как вывести сводные данные из табличных частей документов за период в 1С?

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

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

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

Почему стандартный механизм «Вывести список» не всегда подходит?

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

Метод 1: Программное формирование через запрос и макет

Самый гибкий способ — это использование объекта Запрос для получения данных и объекта ТабличныйДокумент для их отображения. Проанализируем ситуацию, когда табличная часть имеет "горизонтальную" структуру (например, колонки День1, День2 ... День31). Нам необходимо выбрать эти данные, сгруппировать их и вывести в понятном виде.

Рассмотрим пример кода, который собирает данные из табличной части ОтработанноеВремя документа ТабельУчетаРабочегоВремениОрганизации. Обратите внимание, как в запросе мы обращаемся к реквизитам как самой табличной части, так и к полям владельца (ссылки):


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

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

Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

После получения данных необходимо подготовить ТабличныйДокумент. Разберем по шагам процесс вывода:

  1. Создаем новый объект ТабличныйДокумент.
  2. Получаем Макет отчета, в котором заранее нарисованы области Заголовок, Шапка и Строка.
  3. Используем метод Вывести() для каждой секции макета.

ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("СводныйТабель");

// Выводим заголовок один раз
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьЗаголовок.Параметры.ТекстЗаголовка = "Сводный отчет за период с " + Формат(ДатаНачала, "ДЛФ=D");
ТабДокумент.Вывести(ОбластьЗаголовок);

// Выводим строки данных
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Пока Выборка.Следующий() Цикл
    ОбластьСтрока.Параметры.Заполнить(Выборка);
    // Здесь можно добавить дополнительную логику расчета, 
    // например, суммирование часов по строке перед выводом.
    ТабДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

ТабДокумент.Показать("Сводный отчет по ТЧ");

Метод 2: Использование Динамического списка (для обычных форм)

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

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

Для реализации этого метода нам потребуется "развернуть" данные. Выясним причину, почему это бывает сложно: в табличных частях типа Табеля данные хранятся горизонтально. Чтобы сделать их удобными для отчета, иногда полезно применить оператор ОБЪЕДИНИТЬ ВСЕ в запросе, превращая каждую колонку дня в отдельную строку. Это позволит легко суммировать Явки или Больничные через стандартные итоги.

Особенности обработки данных при выводе

Проанализируем ситуацию, когда в ячейках отчета нужно выводить не просто значения из базы, а результат вычислений (как в сообщении 22 форума). Часто в табелях в одной ячейке должен отображаться и вид времени (например, "Я"), и количество часов. При ручном обходе выборки мы можем формировать текст ячейки динамически:


ТекстЯчейки = "";
Если Выборка.КоличествоЧасов > 0 Тогда
    ТекстЯчейки = Строка(Выборка.ВидВремениКод) + " " + Строка(Выборка.КоличествоЧасов);
Иначе
    ТекстЯчейки = Строка(Выборка.ВидВремениКод);
КонецЕсли;

ОбластьСтрока.Ячейки.День1.УстановитьТекст(ТекстЯчейки);

Важный момент: Если вы работаете с конфигурациями, где ведется расчет зарплаты (ЗУП, УПП), помните, что данные табличных частей документов — это лишь намерение. Физические данные о времени и начислениях хранятся в Регистрах расчета или Регистрах накопления. Для серьезных отчетов за период рекомендуется использовать именно виртуальные таблицы регистров, так как они работают быстрее и содержат уже проверенные (проведенные) данные.

Подведение итогов

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

← На главную