某工厂的机加工车间,车间员工的考勤表如下图所示,现在统计员需要手动统计员工的两个指标,一个是实际出勤天数,一个是最长连续上班(出勤)天数。因为整个车间员工比较多,一个一个手工统计比较麻烦,希望设计一个公式来解决手动填写的问题? 实际出勤这一块比较好统计,直接用统计函数COUNTIFS就可以实现。因为出勤的条件就是单元格内有“√”,所以只需要录入公式: =COUNTIF(H4:AI4,"√")并下拉填充就可以了。 动态数组公式写法如下: =MAP(C4:C23,LAMBDA(X,COUNTIFS(OFFSET(X,,1,,31),"√"))) 公式释义: 定义X=C4:C23,对于每个单元格,它使用一个lambda函数来计算满足条件的单元格的数量。这个lambda函数使用OFFSET函数来获取当前单元格向下偏移1行,并跨越31列的单元格,然后使用COUNTIFS函数来计算这个偏移单元格中值为'√'的数量。所以,整个公式的含义是计算C4到C23的单元格中,向下偏移31列并且值为'√'的单元格的数量。 连续出勤是指连续上班的天数,中间只要断了一天,就需要重新计算。用中文来描述是比较简单的,用公式就会比较难,先分步计算。 录入函数: =IF(D4:AH23="√",D3:AH3,0)-D3:AH3 函数释义:如果出勤就返回日期的数字,如7号号出勤返回数字7,8号出勤返回数字8,没有出勤返回0,再用这个数字减去日期的数字,这样出勤的就是变成0了,没有出勤的就变成当天日期的负数了。可以发现0是连续出现的,就代表连续出勤了,效果如下图: 录入函数: =SCAN(0,IF(D4:AH23="√",D3:AH3,0)-D3:AH3,LAMBDA(x,y,IF(y=0,x+1,0))) 函数释义: 也就是上图的结果定义为SCAN函数的y 值。配合x 值 0,进行递归运算,如果y 值等于0,就是用x+1,一直累加,这样连续0就会返回一组数1,2,3,4,……;不等于0的就返回0值。 最后配合BYROW函数收尾: =BYROW(SCAN(0,IF(D4:AH23="√",D3:AH3,0)-D3:AH3,LAMBDA(x,y,IF(y=0,x+1,0))),LAMBDA(h,MAX(h))) 函数释义: 把步骤2的结果定义为BYROW函数的H值,统计每行的最大值,这样就得到了连续出勤的天数。效果如下图所示: 知识点1:统计函数的常规写法和动态数组的写法 知识点2:利用SCAN函数进行分步运算的递归写法; SCAN函数是Excel中的函数,它通过对每个值应用LAMBDA来扫描数组,并返回包含一系列值的数组。SCAN函数的作用是进行“累加”运算,其中“累加”运算通过LAMBDA函数定义,可以进行任何处理,并不仅仅限于元素相加。 知识点3:利用BYROW函数进行每一步的最值判断; Excel的BYROW函数是一个新函数,用于对数组或引用的每一行应用LAMBDA函数,并返回一个数组作为结果。 BYROW函数有两个参数,第一个参数是需要逐行遍历的数据,可以是引用也可以是数组。当是引用时会保留引用的特性。第二个参数是一个LAMBDA函数,该函数默认第1参数是一个变量,指向BYROW函数第1参数的每行数据,第2参数表示计算方式。 BYROW函数的应用场景非常广泛。例如,可以使用BYROW函数来求二维区域中每一行的最大值、最小值、平均值、中位数、众数、方差等数值,或者对每行数据合并等。