Как в 1С:ЗУП 3.1 программно получить количество отработанных дней сотрудником?

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

В конфигурации 1С:Зарплата и управление персоналом 3.1 задача получения отработанного времени программным способом часто ставит разработчиков в тупик. Это связано с тем, что данные могут храниться в разных местах в зависимости от того, рассчитана ли зарплата, введен ли документ Табель или используются ли только документы-отклонения и графики. Чтобы разобраться в многообразии программных интерфейсов, полезно изучить справочник методов конфигурации Зарплата и кадры 3.1. Разберем наиболее универсальные и правильные способы получения этой информации, которые используют сами разработчики фирмы "1С" в типовом решении.

Анализ механизмов учета времени

Прежде чем приступать к написанию кода, проанализируем, откуда система берет данные. В ЗУП 3.1 существует два принципиально разных подхода к получению данных об отработанных днях:

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

Рассмотрим подробнее самый надежный и современный способ — работу с временными таблицами через типовые функции. Для отладки таких механизмов и проверки данных в запросах крайне полезна консоль запросов ЗУП с поддержкой обращения к методам программного интерфейса, которая позволяет выполнять запросы к динамически формируемым данным.

Использование функции СоздатьВТДанныеУчетаВремениИСостоянийСотрудников

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

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


// 1. Подготовка структуры параметров
Параметры = УчетРабочегоВремениРасширенный.ПараметрыДляЗапросВТДанныеУчетаВремениИСостоянийСотрудников();
Параметры.ДатаНачала = ДатаНачалаПериода;
Параметры.ДатаОкончания = ДатаОкончанияПериода;
Параметры.ИмяВТСотрудники = "ВТСотрудники"; // Имя таблицы, которую мы подготовим заранее
Параметры.РассчитыватьПлановоеВремя = Истина;

Обратите внимание, что перед вызовом функции в менеджере временных таблиц вашего запроса уже должна существовать таблица ВТСотрудники. В ней должны быть как минимум колонки Сотрудник, ДатаНачала и ДатаОкончания.

Пошаговая реализация программного кода

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

Шаг 1. Подготовка списка сотрудников. Создадим временную таблицу со списком интересующих нас лиц. Это необходимо, чтобы функция понимала, по кому именно собирать данные.


Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    &Сотрудник КАК Сотрудник,
    |    &ДатаНачала КАК ДатаНачала,
    |    &ДатаОкончания КАК ДатаОкончания
    |ПОМЕСТИТЬ ВТСотрудники";
Запрос.УстановитьПараметр("Сотрудник", ВыбранныйСотрудник);
Запрос.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаОкончания", КонецМесяца(ТекущаяДата()));
Запрос.Выполнить();

Шаг 2. Вызов типового механизма. Теперь вызовем функцию, которая наполнит наш менеджер временных таблиц данными о времени.


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

Шаг 3. Получение итогового результата. После выполнения функции в менеджере появится таблица с именем ВТДанныеУчетаВремени. Нам остается только прочитать её и просуммировать отработанные дни. Примеры реализации подобных алгоритмов можно встретить в готовых решениях, таких как отчет Отработанное и оплаченное время сотрудников организации.


Запрос.Текст = 
    "ВЫБРАТЬ
    |    ДанныеВремени.Сотрудник КАК Сотрудник,
    |    СУММА(ДанныеВремени.Дни) КАК ОтработаноДней
    |ИЗ
    |    ВТДанныеУчетаВремени КАК ДанныеВремени
    |ГДЕ
    |    ДанныеВремени.ВидУчетаВремени В (
    |        ВЫБРАТЬ Ссылка ИЗ Справочник.ВидыИспользованияРабочегоВремени ГДЕ РабочееВремя = ИСТИНА
    |    )
    |СГРУППИРОВАТЬ ПО
    |    ДанныеВремени.Сотрудник";

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

В этом запросе мы используем фильтр по признаку РабочееВремя = ИСТИНА в справочнике ВидыИспользованияРабочегоВремени. Это позволяет автоматически включить в подсчет не только обычную "Явку", но и командировки, работу в выходные и прочие виды времени, которые считаются отработанными.

Важные нюансы и альтернативы

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

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

Когда можно использовать регистры? Если в вашей организации бизнес-процесс жестко закрепляет, что данные анализируются только после окончательного расчета месяца, вы можете существенно упростить код, обратившись к регистру накопления ОтработанноеВремяПоСотрудникам. Однако в специфических случаях, например, когда требуется изолированное ведение табеля в удаленных подразделениях, алгоритмы получения данных могут потребовать дополнительной синхронизации и кастомной логики доступа к регистрам.

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

← На главную