Часто при доработке конфигурации 1С:ЗУП 3 (в том числе локализованных версий, где могут отсутствовать некоторые типовые регистры) возникает задача получить фактически отработанное время сотрудника за конкретный день или нестандартный период. На первый взгляд кажется, что достаточно обратиться к регистру ОтработанноеВремя или выдернуть готовый запрос из отчета Т-13. Однако на практике эти подходы не работают: регистр хранит общие итоги в разрезе начислений (например, 168 часов за месяц), а запрос отчета Т-13 динамически модифицируется перед выполнением.
Давайте подробно разберем, как устроена архитектура учета времени в ЗУП 3 и какие рабочие способы существуют для решения этой задачи.
Проанализируем главную особенность системы: в ЗУП 3 нет единого физического регистра, в котором безусловно хранится фактическое отработанное время на каждый конкретный день. Система использует так называемый метод отклонений. Это означает, что данные формируются «на лету» по формуле:
Фактическое время = Плановое время по графику - Отклонения (отпуска, больничные и т.д.) + Сверхурочные.
Физически записи в разрезе дней появляются в системе только тогда, когда введен и проведен документ Табель (метод сплошной регистрации). Если такого документа нет, время на конкретную дату нужно вычислять программно.
Выясним причину, почему простое копирование запроса из СКД отчета Унифицированная форма Т-13 не приносит результата. Дело в том, что в отчетах ЗУП запрос-болванка из макета СКД перед выполнением проходит через программную модификацию в зависимости от настроек, параметров и вариантов отчета.
Вместо извлечения запроса мы рассмотрим метод программного выполнения СКД с выводом результата напрямую в ТаблицаЗначений. Это позволит нам использовать всю мощь типовых алгоритмов компоновки.
Отчеты.ТабельУчетаРабочегоВремениТ13.Создать().КомпоновщикМакетаКомпоновкиДанных для сборки макета с учетом наших настроек.ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений.Пример программного кода для вывода в таблицу значений выглядит примерно так:
ОтчетОбъект = Отчеты.ТабельУчетаРабочегоВремениТ13.Создать();
// Заполнение параметров отчета...
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ОтчетОбъект.СхемаКомпоновкиДанных, ОтчетОбъект.КомпоновщикНастроек.Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
В результате во внутреннюю таблицу значений попадут уже готовые, корректно рассчитанные часы по дням.
Если вариант с СКД вам не подходит по соображениям производительности или архитектуры решения, разберем по шагам алгоритм ручного сбора данных.
ИндивидуальныйГрафик.ГрафикиРаботыПоВидамВремени, в котором хранится расписание основных графиков сотрудников.СостоянияСотрудников на искомую дату. Если сотрудник был в отпуске или на больничном, плановые часы обнуляются (или классифицируются другим видом времени, например "Б" или "ОТ").В типовых конфигурациях ЗУП 3 существуют специализированные общие модули для работы со временем, такие как УчетРабочегоВремени и УчетРабочегоВремениРасширенный. В них содержатся экспортные функции для получения нормы и факта времени.
Если стандартные функции (вроде СоздатьВТДанныеУчетаВремениИСостоянийСотрудников) не отрабатывают из-за отсутствия нужного регистра в вашей локализации, внимательно изучите эти модули. Зачастую в них присутствуют более низкоуровневые функции, возвращающие массивы видов времени или формирующие структуры параметров, которые опираются на графики и состояния, минуя итоговые регистры. Их вызов позволит собрать нужную информацию, не изобретая велосипед с нуля.