王樹賢 羅鋒 覃云韜

[摘 要] 流行的企業考勤系統多與排班系統關聯,在有復雜排班情況的企業里,排班系統因數據錄入工作量太大而多被棄用,導致考勤系統統計功能喪失,人工統計效率非常低下。通過將考勤系統與排班系統分離,并經方案優化和算法優化,極大地提高了統計效率。
[關鍵詞] 企業;考勤;排班;統計;優化
doi : 10 . 3969 / j . issn . 1673 - 0194 . 2018. 07. 036
[中圖分類號] TP311 [文獻標識碼] A [文章編號] 1673 - 0194(2018)07- 0087- 04
1 引 言
目前,通過引入考勤機來監控員工的出勤紀律,已經十分普及。考勤機設備也發展出了刷卡式、指紋式、甚至人像識別式等多種先進型號,在事業型單位、一班制的企業等簡單環境下的應用,已經相當的成熟。但是,針對有多班次倒班、允許員工私下調班等具有復雜排班模式的企業單位,考勤系統在考勤數據的整理、出勤時間的統計、異常數據的發現等方面,統計算法還遠未成熟。
2 目前考勤系統存在的問題
為了應對多班次倒班等復雜的排班情況,目前流行的考勤系統主要通過和排班系統結合起來的方式來實現數據的關聯。即把所有員工的班次信息也錄入系統,這樣,某員工上班和下班預設的時間段就確定了下來,考勤數據與這個預設的時間段相對比,得到正常出勤和非正常出勤的情況。
這種模式的缺點有如下幾個方面:
(1)根據實際生產情況,員工的排班情況是多變的。可能這幾天生產任務緊需要3班倒,過兩天不太緊張了只需要上2班;某員工這一周上晚班,下周又可能上白班。這就需要不斷地往系統里錄入大量的排班信息,工作量很大,生產管理人員對于數據錄入的積極性不高。
(2)對于員工眾多的企業,某員工因有私事私下和工友調班是允許的,否則管理起來更加復雜。這樣就使得系統里排班數據和考勤數據對不上,還是不能自動處理。
(3)多班次倒班時,員工上班時間和下班時間可能已不在同一天,即跨日期上下班。這給數據統計也帶來了一些麻煩。
(4)員工難免有漏刷卡、重復刷卡的現象,當考勤數據不成對兒出現時,對上班刷卡還是下班刷卡的判斷也會出現問題。
鑒于上述種種原因,許多企業已經放棄了考勤系統的統計功能,而僅僅是從系統中導出考勤記錄,在Excel中手工逐條處理數據,工作量之大可想而知。
3 改進思路
3.1 措施一:上下班考勤機分離
針對以上問題,一個有效的改進途徑是上下班考勤機分離,即上班和下班分別刷不同的考勤機。這樣可以大幅降低系統處理的復雜度,目前已有考勤系統支持這種方式。
通過上下班考勤機分離,使得原來復雜的業務邏輯大幅簡化。理論上,如果員工刷卡沒有錯誤,就可以很容易計算出出勤時間。即使出現漏刷卡、多刷卡等異常情況,系統也很容易排查出異常,甚至可以判斷錯誤原因,免除手工排查的大量工作。嚴格執行上下班分離的刷卡考勤制度,或者與門禁系統相結合,就可以隨時計算出車間在崗人員數量,甚至可以列出在崗人員名單,使車間管理更加精細、更加直觀。
上下班考勤機分離也有缺點。如果考勤機安裝位置設計不夠合理,員工不能輕易清晰的區分上班考勤機和下班考勤機,員工刷卡時會把上班和下班弄反,同樣會導致考勤數據的錯亂。所以,考勤機安裝位置的設計非常關鍵,一定要考慮人們的思維習慣,一般設計在出入方向的右手邊,并用醒目的文字標注,同時配合有效的培訓和出錯懲罰的管理制度。考勤機上下班分離方案,能夠以較小的投入換來較大的改進效果。
3.2 措施二:考勤數據統計算法的優化
3.2.1 與排班系統分離
為了有效減少系統維護的數據量,針對有復雜排班需求的生產型企業,果斷放棄考勤系統與排班系統的集成,單從考勤數據中提取員工的出勤情況。
3.2.2 考勤數據的整理
在生成報表前,先對考勤數據進行預處理。比如剔除無效數據、補充遺漏數據等。當然首先是提取出某時間段數據,再針對該部分數據進行處理。實踐中,一般以一個月為一個統計周期。代碼略。
3.2.2.1 無效刷卡數據的剔除
針對員工難免出現的重復刷卡的現象,系統盡可能的刪除無效刷卡數據。可以采取的策略有:
(1)間隔5分鐘內重復刷上班卡,以最后1次為準(代碼以SQL Server為例,下同)。
DELETE a
FROM #t a JOIN #t b
ON a.工號=b.工號 AND a.日期=b.日期 AND a.考勤機=b.考勤機
WHERE DATEDIFF(ss, a.日期時間, b.日期時間) BETWEEN 1 AND 300
AND a.刷卡用途='上班';
(2)間隔5分鐘內重復刷下班卡,以第1次為準。
DELETE a
FROM #t a JOIN #t b
ON a.工號=b.工號 AND a.日期=b.日期 AND a.考勤機=b.考勤機
WHERE DATEDIFF(ss, b.日期時間, a.日期時間) BETWEEN 1 AND 300
AND a.刷卡用途='下班';
注意DATEDIFF()函數中,日期時間的參數順序與第(1)條的順序相反。
(3)間隔2分鐘內刷上班和下班卡,以最后1次為準。
DELETE a
FROM #t a JOIN #t b
ON a.工號=b.工號 AND a.日期=b.日期
WHERE DATEDIFF(ss, a.日期時間, b.日期時間) BETWEEN 1 AND 120;
3.2.2.2 跨日期上下班考勤數據的預處理
最直觀的報表形式為每日出勤情況,所以針對跨日期上下班考勤數據,需要進行一些預處理。
(1)一天第1次刷卡為下班卡的,若為9點之前下班,則認為是跨零點上班,即前一天上班當天下班。當天從零點計算出勤時間。系統補零點上班卡。
INSERT INTO #t(工號, 姓名, 部門, 二級部門, 三級部門
, 日期, 序號, 視同時間, 刷卡用途
)
SELECT 工號, 姓名, 部門, 二級部門, 三級部門, 日期, 0 序號
, CASE WHEN 刷卡時間<'09:00:00' THEN '0:00:00' END 視同時間
, '上班' 刷卡用途
FROM #t
WHERE 序號=1 AND 刷卡用途='下班';
(2)一天最后1次刷卡為上班卡的,若為15點之后上班,則認為是跨零點上班,即當天上班第二天下班。當天計算出勤時間到24點,系統補24點下班卡。
with t AS
(
SELECT 工號, 日期
, MAX(序號) 序號
FROM #t
GROUP BY 工號, 日期
), t2 AS
(
SELECT #t.工號, #t.姓名, #t.部門, #t.二級部門, #t.三級部門
, #t.日期, #t.序號, #t.刷卡時間
FROM #t JOIN t ON #t.工號=t.工號 AND #t.日期=t.日期
AND #t.序號=t.序號 AND 刷卡用途='上班'
)
INSERT INTO #t(工號, 姓名, 部門, 二級部門, 三級部門
, 日期, 序號, 視同時間, 刷卡用途
)
SELECT 工號, 姓名, 部門, 二級部門, 三級部門
, 日期
, 序號+1 序號
, CASE WHEN 刷卡時間>'15:00:00' THEN '23:59:59' END 視同時間
, '下班' 刷卡用途
FROM t2;
3.2.2.3 漏刷卡數據處理
經過上述數據處理之后,相鄰兩次刷卡刷卡用途還相同,即均為上班卡或均為下班卡的,則認為中間缺一次刷卡操作,系統補1次時間為空的刷卡記錄。
(1)重新整理序號,方便后面相鄰兩次相同用途刷卡數據處理。
;with t AS
(
SELECT 工號, 日期, 序號
, rn=ROW_NUMBER() OVER(PARTITION BY 工號, 日期 ORDER BY 序號)
FROM #t
)
UPDATE #t
SET #t.序號=t.rn
FROM #t JOIN t ON #t.工號=t.工號
AND #t.日期=t.日期 AND #t.序號=t.序號;
(2)補1次時間為空的刷卡記錄,用以報表中提示缺1次刷卡操作。
INSERT INTO #t(工號, 姓名, 部門, 二級部門, 三級部門
, 日期, 序號, 刷卡用途
)
SELECT a.工號, a.姓名, a.部門, a.二級部門, a.三級部門
, a.日期
, a.序號-0.5 序號
, CASE a.刷卡用途 WHEN '下班' THEN '上班' ELSE '下班' END 刷卡用途
FROM #t a JOIN #t b ON a.工號=b.工號 AND a.日期=b.日期
AND a.序號=b.序號+1
WHERE a.刷卡用途=b.刷卡用途;
3.2.2.4 數據預處理注意事項
以上數據預處理步驟,充分運用了順序號這一字段。所以,維護好順序號,是數據處理的關鍵。不同目的數據處理操作的先后順序,也要仔細考量。
3.2.3 生成出勤報表
經過上述一系列的數據處理,系統終于可以生成出勤數據報表了。
with t1 AS
(
SELECT 工號, 姓名, 部門, 二級部門, 三級部門, 日期, 視同時間, 刷卡用途
, Row_Number()Over(partition by 工號, 日期, 刷卡用途 order by 序號) 序號
FROM #t
), t2 AS
(
SELECT 工號, 姓名, 部門, 二級部門, 三級部門, 日期, 序號
, CASE WHEN 序號=1 AND 刷卡用途='上班' THEN 視同時間 END 上班1
, CASE WHEN 序號=1 AND 刷卡用途='下班' THEN 視同時間 END 下班1
, CASE WHEN 序號=2 AND 刷卡用途='上班' THEN 視同時間 END 上班2
, CASE WHEN 序號=2 AND 刷卡用途='下班' THEN 視同時間 END 下班2
, CASE WHEN 序號=3 AND 刷卡用途='上班' THEN 視同時間 END 上班3
, CASE WHEN 序號=3 AND 刷卡用途='下班' THEN 視同時間 END 下班3
, CASE WHEN 序號=4 AND 刷卡用途='上班' THEN 視同時間 END 上班4
, CASE WHEN 序號=4 AND 刷卡用途='下班' THEN 視同時間 END 下班4
, CASE WHEN 序號=5 AND 刷卡用途='上班' THEN 視同時間 END 上班5
, CASE WHEN 序號=5 AND 刷卡用途='下班' THEN 視同時間 END 下班5
, CASE WHEN 序號=6 AND 刷卡用途='上班' THEN 視同時間 END 上班6
, CASE WHEN 序號=6 AND 刷卡用途='下班' THEN 視同時間 END 下班6
FROM t1
), t3 AS
(
SELECT 工號, 姓名, 部門, 二級部門, 三級部門, 日期
, MAX(上班1) 上班1
, MAX(下班1) 下班1
, MAX(上班2) 上班2
, MAX(下班2) 下班2
, MAX(上班3) 上班3
, MAX(下班3) 下班3
, MAX(上班4) 上班4
, MAX(下班4) 下班4
, MAX(上班5) 上班5
, MAX(下班5) 下班5
, MAX(上班6) 上班6
, MAX(下班6) 下班6
FROM t2
GROUP BY 工號, 姓名, 部門, 二級部門, 三級部門, 日期
)
SELECT 工號, 姓名, 部門, 二級部門, 三級部門, 日期
, 上班1, 下班1
, 上班2, 下班2
, 上班3, 下班3
, 上班4, 下班4
, 上班5, 下班5
, 上班6, 下班6
, ROUND((ISNULL(DateDiff(n, 上班1, 下班1), 0)
+ISNULL(DateDiff(n, 上班2, 下班2), 0)
+ISNULL(DateDiff(n, 上班3, 下班3), 0)
+ISNULL(DateDiff(n, 上班4, 下班4), 0)
+ISNULL(DateDiff(n, 上班5, 下班5), 0)
+ISNULL(DateDiff(n, 上班6, 下班6), 0)
) * 1.0 / 60, 1) 出勤時間
FROM t3
ORDER BY 工號, 日期;
某一天的出勤數據報表預覽示例如表1所示。
通過報表預覽可以很明顯的發現,工號為2010023的員工盤××漏刷了一次下班卡。后來通過視頻監控錄像證實了該員工正常按時下班,因漏刷卡對該員工給予警告處理。在手工補齊下班考勤數據后,即可正式生成報表。
經過數據整理,針對部分重復刷卡的無效數據已經剔除,漏刷卡情況也給與明確提示。通過報表預覽,可以快速的發現數據錯誤,進行手工的數據處理后再生成最終報表,統計效率得以極大改善。
4 結 論
經某企業的應用實踐證明,通過方案改進和算法改進,對于復雜排班環境下的生產型企業,考勤系統的實用性大大提高,考勤統計人員的工作量大幅減少,極大地提高了工作效率,得到用戶的好評。