每年年初,人事都要把全员的工龄重算一遍。不是为了统计,是因为年假天数挂在工龄上。
《职工带薪年休假条例》的口径很清楚:累计工作满 1 年不满 10 年的 5 天,满 10 年不满 20 年的 10 天,满 20 年的 15 天。
差一天,可能就是 5 天与 10 天的差别。这种错,员工往往比人事更早发现。
在勤哲 Excel 服务器里,重算可以交给一条表间公式。但这条公式怎么写,前后试了三个版本。
每年年初,人事都要把全员的工龄重算一遍。不是为了统计,是因为年假天数挂在工龄上。
《职工带薪年休假条例》的口径很清楚:累计工作满 1 年不满 10 年的 5 天,满 10 年不满 20 年的 10 天,满 20 年的 15 天。
差一天,可能就是 5 天与 10 天的差别。这种错,员工往往比人事更早发现。
在勤哲 Excel 服务器里,重算可以交给一条表间公式。但这条公式怎么写,前后试了三个版本。
工龄指职工以工资收入为生活资料全部或主要来源的工作年限,分为一般工龄和连续工龄。前者是全部工作时间,后者是在同一单位的连续工作时间。
计算规则按国法[1978]104 号文件:满一个周年才算一年。7 月 15 日入职,次年 7 月 14 日仍不算满一年,到 7 月 15 日才算。
这一条直接排除了“年份相减”的写法。2016 与 2017 相减得 1,可 7 月 1 日的人还没过周年,实际应是 0。
所以问题不是取不到数,是取到的是一个近似值。在勤哲 Excel 服务器里写这条表间公式,要处理的正是这个“差一点”。
最直觉的写法,是直接取两个日期的间隔年数,填进工龄字段。
间隔时间(yy, 本报表.工龄_主表.入职日期, 系统变量.当前日期) → (填入值) 工龄
结果令人尴尬:2017 年 7 月 1 日打开报表,2016 年 7 月 15 日入职的人,工龄显示为 1。
原因在于 间隔时间(yy) 只做年份相减,2017 减 2016 等于 1,并不判断月份和日期有没有跨过周年那一天。
这个写法在年初特别容易出错:一月的报表里,所有下半年入职的人都会被多算一年。
既然按年取会粗,那就按天取,再折算成年。
间隔时间(dd, 本报表.工龄_主表.入职日期, 系统变量.当前日期) / 365 → (填入值) 工龄
问题换了个地方出现。平年 365 天,闰年 366 天,跨过 2 月 29 日的区间,除出来的结果会偏小。
偏小一点点,取整之后就差一年。为了处理小数,还得再套一层取整函数,公式越写越长,出错的地方也越多。
两次尝试都指向同一个结论:工龄不是除法题,是比较题。
换个思路:先算出间隔年数 x,再把这个 x 年加回入职日期,看落点在哪。
如果加完的那一天还没超过当前日期,说明确实满 x 年;如果超过了,说明只满了 x-1 年。
条件取值(日期加减(yy, 间隔时间(yy, 本报表.工龄_主表.入职日期, 系统变量.当前日期), 本报表.工龄_主表.入职日期) > 系统变量.当前日期, 间隔时间(yy, 本报表.工龄_主表.入职日期, 系统变量.当前日期) - 1, 间隔时间(yy, 本报表.工龄_主表.入职日期, 系统变量.当前日期)) → (填入值) 工龄
写成一整条虽然长,但结构是清楚的:一段算差、一段回推、一段判断,三段对着上面三步。
验证也简单。找一个 7 月 15 日入职的人,在 7 月 14 日和 7 月 15 日各打开一次报表,看数字有没有从 0 跳到 1。跳了,就对了。
间隔时间负责取差,日期加减负责回推,条件取值负责下判断。三个函数单看都不复杂,组合起来就是一套通用的周年判断写法。
合同到期提醒、试用期转正、设备保修到期、应收账龄分段,都是同一个套路:先算整年或整月,再回推,再和当天比一次。
差别只在粒度。按年判断用 yy,按月判断把参数换成 mm,按天算就换 dd。骨架不用重写。
在勤哲 Excel 服务器里,这类判断写在表间公式中,保存一次,之后每次打开报表都按当天重算,不需要有人手动维护工龄列。
有一个前提要注意:公式取的是系统变量里的当前日期,服务器时间必须准。跨时区部署或者有人手工改过系统时间,结果就会跟着偏。
公式能算对,靠的不是函数多,而是把“满一个周年”这句话翻译成了可比较的两个日期。翻译对了,后面都是顺的。