При разработке систем учета рабочего времени программисты часто сталкиваются с задачей вывода данных в виде кросс-таблицы, где строками являются сотрудники, а колонками — даты месяца. Основная сложность возникает, когда в ячейке на пересечении нужно отобразить не просто количество отработанных часов, а конкретные моменты регистрации: время первого прихода и последнего ухода. Рассмотрим, как правильно настроить систему компоновки данных (СКД) для решения этой задачи, избежав типичных ошибок с «левыми» данными в итогах.
Представим, что у нас есть независимый непериодический регистр сведений ОтметкиОВремениПриходаУходаСРаботы. В нем фиксируются события входа и выхода сотрудников. Структура регистра включает измерения Пользователь, Сотрудник, ДатаРабочегоДня и ресурсы ВремяПрихода, ВремяУхода, КоличествоЧасов. Наша цель — получить отчет, где в каждой дате для сотрудника будут выведены три показателя: время начала работы, время окончания и итоговые часы.
Разберем базовый запрос, который послужит фундаментом для нашего набора данных:
ВЫБРАТЬ
Отметки.Сотрудник КАК Сотрудник,
НАЧАЛОПЕРИОДА(Отметки.ДатаРабочегоДня, ДЕНЬ) КАК ДатаРабочегоДня,
Отметки.ВремяПрихода КАК ВремяПрихода,
Отметки.ВремяУхода КАК ВремяУхода,
Отметки.КоличествоЧасов КАК Часов
ИЗ
РегистрСведений.ОтметкиОВремениПриходаУходаСРаботы КАК Отметки
ГДЕ
Отметки.КоличествоЧасов <> 0
Просто выбрать данные недостаточно, так как при использовании кросс-таблицы СКД должна понимать, как агрегировать значения времени при сворачивании записей за день. Проанализируем ситуацию: если сотрудник совершал несколько перемещений в течение дня, нам нужно зафиксировать самое раннее время для прихода и самое позднее для ухода.
Перейдем на вкладку Ресурсы в схеме компоновки данных. Это ключевой этап, на котором совершается большинство ошибок. Для корректного отображения времени в кросс-таблице мы не можем просто суммировать время прихода. Вместо этого настроим ресурсы следующим образом:
Часов укажем выражение: Сумма(Часов).ВремяПрихода используем агрегатную функцию: Минимум(ВремяПрихода). Это позволит нам выцепить именно первый визит сотрудника за выбранную дату.ВремяУхода используем: Максимум(ВремяУхода). Таким образом, в отчете отобразится время последнего события за день.Важный нюанс: если мы оставим настройки по умолчанию, СКД может попытаться рассчитать эти значения для общих итогов, что приведет к нелогичным результатам (например, минимальное время прихода по всем сотрудникам организации). Рассмотрим, как этого избежать.
Выясним причину, по которой в отчете могут появляться некорректные или «чужие» данные. Это происходит из-за неправильной настройки области действия ресурсов. В колонке Рассчитывать по необходимо четко указать уровни группировок. Для нашего случая достаточно оставить расчет по полям Сотрудник и ДатаРабочегоДня.
Если в настройках макета кросс-таблицы вы видите лишние строки или пустые значения, проанализируем структуру группировок. Рекомендуется:
Сотрудник.ДатаРабочегоДня.Посмотрим на пример правильной настройки выбранных полей в кросс-таблице. Вместо авто-поля добавьте вручную:
ВремяПриходаВремяУходаЧасовЗачастую 1С хранит время в ресурсах как тип Дата, где дата установлена в значение «01.01.0001». Чтобы отчет выглядел профессионально, настроим условное оформление или формат полей. Рассмотрим подробнее:
Для полей ВремяПрихода и ВремяУхода на вкладке «Наборы данных» в колонке «Оформление» установим формат редактирования: ДФ=HH:mm. Это скроет пустую дату и оставит только часы и минуты.
Если ваши «Часы» хранятся в десятичном формате (например, 3.5 часа вместо 3:30), мы можем преобразовать их для удобства пользователя. Разберем по шагам создание вычисляемого поля:
// Пример выражения для вычисляемого поля в СКД
Целое(Часов) + ":" + Формат((Часов - Целое(Часов)) * 60, "ЧЦ=2; ЧВН=")
Однако помните, что суммировать такие строки напрямую нельзя — математические операции должны проводиться над числовыми ресурсами, а строковое представление используется только для вывода.
Проанализируем ситуацию, когда база данных содержит сотни тысяч записей. Чтобы отчет не «тормозил», необходимо убедиться, что измерения регистра Сотрудник и ДатаРабочегоДня проиндексированы. В запросе СКД также полезно использовать виртуальные таблицы, если это возможно, но для непериодического регистра сведений мы работаем с физической таблицей.
Совет по ускорению формирования: в запросе всегда выбирайте Сотрудник.Представление, если планируете выводить только ФИО. Это уменьшит количество обращений к таблице справочника физических лиц или сотрудников при компоновке результата.
Подведем итог. Чтобы правильно составить запрос и настроить отчет по приходу-уходу, мы должны отойти от простого вывода строк и использовать мощные механизмы агрегации СКД. Основные моменты:
МИНИМУМ для входа и МАКСИМУМ для выхода.ДФ=HH:mm.Следуя этой методике, вы получите чистый, понятный отчет, который корректно отображает рабочие смены сотрудников без «фантомных» записей из общих итогов.