Рассмотрим классическую задачу контроля рабочего времени. У нас есть база данных системы контроля и управления доступом (СКУД), в которой фиксируются события прохода сотрудников через турникеты или двери. Руководство ставит задачу: выявить всех сотрудников, которые в течение рабочего дня отлучались с рабочего места (выходили из рабочей зоны) более чем на 20 минут.
Проанализируем исходные данные. Как правило, таблица логов СКУД содержит следующие базовые поля:
TimeVal — точные дата и время события;HozOrgan — уникальный идентификатор (ID) сотрудника;Mode — тип события (например, 1 — вход, 2 — выход).Разберем два подхода к решению этой задачи: с помощью языка запросов 1С и с использованием алгоритма конечного автомата в коде. А также посмотрим на современные способы интеграции.
Первая мысль разработчика — написать запрос, который выберет все входы, все выходы, соединит их по идентификатору сотрудника и найдет разницу во времени. Посмотрим на пример запроса, где мы пытаемся получить временные таблицы входов и выходов, а затем вычислить интервал с помощью функции РАЗНОСТЬДАТ.
ВЫБРАТЬ
dbo_pLogData.HozOrgan КАК HozOrgan,
dbo_pLogData.TimeVal КАК времяВхода
ПОМЕСТИТЬ ВременнаяТаблицаВходы
ИЗ
ВнешнийИсточникДанных.ПроходнаяSQL.Таблица.dbo_pLogData КАК dbo_pLogData
ГДЕ
dbo_pLogData.Mode = 1
СГРУППИРОВАТЬ ПО
dbo_pLogData.HozOrgan,
dbo_pLogData.TimeVal
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
dbo_pLogData.HozOrgan КАК HozOrgan,
dbo_pLogData.TimeVal КАК времявыхода
ПОМЕСТИТЬ ВременнаяТаблицаВыходы
ИЗ
ВнешнийИсточникДанных.ПроходнаяSQL.Таблица.dbo_pLogData КАК dbo_pLogData
ГДЕ
dbo_pLogData.Mode = 2
СГРУППИРОВАТЬ ПО
dbo_pLogData.HozOrgan,
dbo_pLogData.TimeVal
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Входы.HozOrgan КАК HozOrgan,
ВЫБОР
КОГДА РАЗНОСТЬДАТ(Выходы.времявыхода, Входы.времяВхода, МИНУТА) > 20
ТОГДА РАЗНОСТЬДАТ(Выходы.времявыхода, Входы.времяВхода, МИНУТА)
КОНЕЦ КАК ВремяОтсутствия,
Входы.времяВхода КАК времяВхода,
Выходы.времявыхода КАК времявыхода
ИЗ
ВременнаяТаблицаВходы КАК Входы
ПОЛНОЕ СОЕДИНЕНИЕ ВременнаяТаблицаВыходы КАК Выходы
ПО Входы.HozOrgan = Выходы.HozOrgan
И (НАЧАЛОПЕРИОДА(Выходы.времявыхода, ДЕНЬ) = НАЧАЛОПЕРИОДА(Входы.времяВхода, ДЕНЬ))
И (Выходы.времявыхода < Входы.времяВхода)
Почему такой подход часто не работает? Сырые логи СКУД практически никогда не бывают идеальными. Сотрудник может выйти, не приложив карту (кто-то открыл дверь перед ним), приложить карту два раза подряд (турникет не сработал с первого раза). В результате в базе появляются два события «Вход» подряд без события «Выход». В таком случае полное или левое соединение в запросе выдаст некорректные декартовы произведения строк (задвоения), и результаты расчета времени поедут. Решить проблему краевых случаев исключительно запросом — невероятно сложная задача.
Выясним, как правильно обрабатывать поток событий. Лучший подход — отказаться от сложных соединений в запросе и пройтись по отсортированной выборке событий программно, используя логику конечного автомата. Разберем алгоритм по шагам.
TimeVal по возрастанию.Соответствие, где ключом будет ID сотрудника, а значением — структура его текущего состояния (например: ТекущийСтатус (Вошел/Вышел), ВремяПоследнегоСобытия, СсылкаНаСтрокуТаблицыОтсутствия).Такой программный проход в один цикл работает крайне быстро и позволяет гибко реагировать на любые аномалии в данных (например, если первое событие за день — это «Выход»).
Проанализируем ситуацию на сегодняшний день. Писать парсинг сырых логов СКУД с нуля требуется все реже. Современная практика диктует использование специализированных решений:
1. Специализированные модули интеграции. Вместо прямых SQL-запросов к таблицам СКУД сейчас используют готовые модули от производителей (например, Sigur, RusGuard или интеграции с системами Болид). Эти модули самостоятельно очищают логи от двойных прикладываний, формируют готовые смены и передают в 1С уже рассчитанные интервалы присутствия.
2. Настройка допусков без кода. Современные подсистемы Учета рабочего времени (WFM) позволяют кадровикам настраивать правила «на лету». Можно в режиме предприятия указать, что отлучки до 10 минут суммируются, но не считаются прогулом, а все, что больше 20 минут — жестко вычитается из табеля.
3. Связь с кадровыми документами (Т-13). Программная фиксация отсутствия в 25 минут — это только половина дела. Правильная интеграция сопоставляет эти пропуски с документами из 1С:ЗУП. Если на время отсутствия оформлена «Местная командировка» или согласованный отгул, система не посчитает это прогулом.
4. Аппаратная защита от "мусора" в логах. Чтобы не писать сложный код обработки ложных входов/выходов, безопасники включают на контроллерах функцию Anti-passback (запрет повторного прохода). Турникет просто не пустит человека внутрь по карте, если по базе он уже находится внутри. Это автоматически делает логи СКУД линейными и чистыми, что сводит написание отчетов в 1С к простейшим запросам.
Применяя данные рекомендации и комбинируя программные проверки с аппаратными настройками СКУД, вы сможете построить точную систему учета рабочего времени.