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

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

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

Метод 1. Программный обход выборки с контролем смены сотрудника

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

Во-первых, проанализируем структуру запроса. Чтобы данные было удобно обрабатывать, необходимо отсортировать результат по сотруднику и дате начала периода. Еще лучше — использовать группировки в самом запросе. Выясним, как правильно организовать цикл обработки:


// Пример структуры обхода выборки
ВыборкаСотрудники = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаСотрудники.Следующий() Цикл
    // 1. Получаем область строки из макета (ФИО и пустые ячейки календаря)
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ОбластьСтрока.Параметры.Сотрудник = ВыборкаСотрудники.Сотрудник;
    
    // 2. Вложенный цикл по детальным записям (конкретным отпускам)
    ВыборкаПериоды = ВыборкаСотрудники.Выбрать();
    Пока ВыборкаПериоды.Следующий() Цикл
        // Определяем, какие ячейки в текущей области нужно закрасить
        РазберемНиже(); 
    КонецЦикла;
    
    // 3. Только после обработки всех периодов выводим строку
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

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

Метод 2. Динамическое формирование колонок и закрашивание ячеек

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

Посмотрим на пример реализации заполнения ячеек:


// Предположим, ТекущаяДата - это день внутри интервала отпуска
// НачалоПериодаОтчета - дата начала формирования всего отчета

НомерКолонки = (НачалоДня(ТекущаяДата) - НачалоДня(НачалоПериодаОтчета)) / 86400 + 2; 
// +2, так как первая колонка обычно занята ФИО

ОбластьЯчейка = ОбластьСтрока.Область(1, НомерКолонки);
ОбластьЯчейка.ЦветФона = ЦветаСтиля.ОсобоеБронирование; // Или любой нужный цвет
ОбластьЯчейка.Текст = "—";

Чтобы закрасить весь интервал, мы должны внутри цикла по периодам запустить еще один цикл, который будет «шагать» по дням от ДатаНачалаОтпуска до ДатаОкончанияОтпуска. Это гарантирует, что даже если у сотрудника два отпуска в одном месяце, они оба отобразятся в одной строке макета.

Метод 3. Использование Системы компоновки данных (СКД)

Многие программисты забывают, что СКД умеет решать задачу группировки данных «в строку» автоматически. Для этого используется тип отчета «Таблица». Выясним, как это настроить:

  1. Настройка строк и колонок: В настройках СКД добавьте таблицу. В «Строки» добавьте поле Сотрудник, а в «Колонки» — поле Дата (с дополнением периодов по дням).
  2. Ресурсы: В качестве ресурса выберите какое-нибудь поле, которое заполнено только в дни отпуска (например, КоличествоДнейОтпуска).
  3. Условное оформление: Это ключевой момент. Создайте правило: если ЗначениеРесурса > 0, то установить Цвет фона в нужный вам цвет (например, зеленый).

Преимущество этого метода в том, что 1С сама построит шапку, сама распределит данные по нужным ячейкам и сгруппирует нескольких Иванов в одну строку. Нам остается только правильно написать запрос, который выберет все даты внутри периодов отпусков (этого можно добиться соединением с производственным календарем или таблицей чисел).

Метод 4. Визуализация через диаграмму Ганта

Если задача стоит не просто «вывести в макет», а «сделать наглядно», проанализируем возможность использования объекта ДиаграммаГанта. Это встроенный объект 1С, предназначенный именно для отображения интервалов времени.

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


Диаграмма = Элементы.ДиаграммаОтпусков;
Диаграмма.Обновление = Ложь;

// Точка - это строка (наш сотрудник)
Точка = Диаграмма.УстановитьТочку(Выборка.Сотрудник);

// Серия - это группа данных (например, "Плановый отпуск")
Серия = Диаграмма.УстановитьСерию("Отпуска");

// Значение - это конкретный интервал
Значение = Диаграмма.ПолучитьЗначение(Точка, Серия);

// Добавляем интервал в существующее значение (это позволяет выводить несколько полосок в ряд)
Интервал = Значение.Добавить();
Интервал.Начало = Выборка.ДатаНачала;
Интервал.Конец = Выборка.ДатаОкончания;
Интервал.Текст = "Отпуск";

Диаграмма.Обновление = Истина;

Диаграмма Ганта автоматически масштабируется, позволяет настраивать шкалу времени (день, неделя, месяц) и избавляет разработчика от ручного рисования сетки в макете табличного документа.

Оптимизация структуры данных

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

Для этого в самописных конфигурациях часто используют вспомогательный регистр сведений «Календарь» или «Даты года». Соединив таблицу отпусков с такой таблицей дат по условию Календарь.Дата МЕЖДУ Отпуска.ДатаНачала И Отпуска.ДатаОкончания, мы получим готовую плоскую таблицу, где каждая строка — это один закрашенный «квадратик» в будущем отчете. Пройти по такой выборке один раз гораздо быстрее, чем постоянно вычислять интервалы в коде 1С.

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

Мы проанализировали несколько подходов к решению задачи. Для простых отчетов с фиксированным периодом подойдет программный обход макета с использованием метода Присоединить(). Для сложных отчетов с динамическими группировками лучше использовать СКД с условным оформлением. Если же важна интерактивность и современный вид — выбирайте диаграмму Ганта. В любом случае, главным правилом остается предварительная подготовка данных в запросе, чтобы минимизировать логические вычисления в цикле вывода.

← На главную