ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: chrisfang

[Excel 函数与公式] [第37期]考勤情况统计[已总结]

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-7-21 17:05 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

本期总结:

在编写这道题目之前,我在论坛中发了一个有关TEXT函数应用的新帖:[原创]你也许未曾见过这样的Text函数用法,在这个帖子中曾经提到,使用TEXT函数来进行条件判断,在某些情况下可以大大简化公式。但是苦于一时半会儿找不到印证这一说法的实例,于是就想根据这个思路来编一道竞赛题,通过题目来展示TEXT函数的作用。通过大家竞答的结果也可以发现,最长的公式有780个字符,而最高效的公式只有163个字符,这其中的差距虽然并非完全是TEXT函数的功劳,但至少在很大程度上帮助大家更深刻地体会到了这个函数的用法。

本题目的本意是让对函数公式不太熟悉的用户也能有机会得分,并且通过一点所谓的小技巧来得到一定的提升。这里提到的小技巧,也是题目中预设的几个考点。先看一下我预设的180个字符的公式:

=TEXT(MAX(--TEXT(SUBSTITUTE(B2&"秒","点","时")/60&"","[="&QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4})/60&""&"]!"&{3,1}&"G/通用格式;4")),"[>4]!"&A2&"第aaa次-m点s.00分;")

此公式可再节省3个字符:177字符:

=TEXT(MAX(--TEXT(SUBSTITUTE(B2&"秒","点","时")/60&"","[="&QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4})/60&"]!"&{3,1}&"G/通用格式;4")),"[>4]!"&A2&"第aaa次-m点s.00分;")

虽然本题的解题思路可以有很多,我这个公式也并非最佳解答,但所涉及的考点基本上已经在这个公式里面包含了:

1,认祖归宗

“12点36分23”这种形式的字符串并不是可以直接被系统所识别的时间值,需要通过公式转换才能形成时间数值。通过公式“SUBSTITUTE(B2&"秒","点","时")”应该是最简单的方法之一,通过这样转换得到的字符串可以被系统识别为时间,前面加上--就可以转换为数值进行最值的比较。此类做法在论坛中已经很常见了。

2,李代桃僵

要将“12时36分23秒”这种形式的时间中秒数部分进位到十进制的分钟形式,成为下面这种形式“12点36.38分”的时间,方法其实有很多,不少初级用户都选择使用字符串分段组合的形式来解决。其实使用“=TEXT(("12时36分23秒")/60,"m点s.00分")”就可以很方便地得到结果,先除以60,将“时-分-秒”的结构退一位变成“分-秒-1/60秒”的结构,然后再使用表示分的格式代码m和表示秒的格式代码s来代替“时-分”的格式显示。因为“秒”有s.00的这种百分数显示格式,因此不需要进行其他运算,很方便就可以将60进制转换为十进制的显示了。

这次答题当中不少朋友都想到了这种方法,其实我在出题前几天也在回帖当中写到过:请问高手,在excel里如何将经纬度只以度分来表示,希望以此为大家留点提示。

以上两个小技巧我觉得都属于一般性的技巧,只要在论坛中多看一些帖子一般都能看到或想到。因此如果用到了这两个技巧,即使公式结构很普通,一般也能完成在290个字符以下,这就是我第一道分数线的设置原由。

例如此公式为289字符:

=IF(--SUBSTITUTE(B2&"秒","点","时")=MIN(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时"))),A2&"第一次-"&TEXT(SUBSTITUTE(B2&"秒","点","时")/60,"m点s.00分"),IF(--SUBSTITUTE(B2&"秒","点","时")=MAX((A$2:A$16=A2)*SUBSTITUTE(B$2:B$16&"秒","点","时")),A2&"第二次-"&TEXT(SUBSTITUTE(B2&"秒","点","时")/60,"m点s.00分"),""))

3,鱼和熊掌

题目要对最大值和最小值进行判断,少不了要求取最值。分开求取最值的代价很大,包括使用计数方式来分别求取的方法。而要两者兼得又排除其他数据的干扰,使用QUARTILE函数就是一个不错的选择。“QUARTILE(....{0,4})”就可以得到一个同时包含最大值和最小值的数组,至于这个数组的后续处理,那就需要其他的技巧了。看一下这期在200个字符以下的公式(包括我在评分说明中所优化的几个公式),几乎都使用到了这个函数。说句不太谦虚的话,所谓“英雄所见略同”,这些高手们果然都毫不客气地祭出了这一法宝。

4,移花接木

因为题目要求显示“第一次”、“第二次”,很多朋友得到了数值1、2,想要转换为中文字符“一”和“二”还是动用了不少脑筋。如果用[dbnum1]吧,后续的时间值不太好处理,把两个分开写成两段条件格式吧,又有些不太甘心。这里就要有些小聪明,借用格式代码中的aaa显示星期几的方法来代替这里中文字符的显示。看上去“星期几”这个格式与我们的“一”和“二”毫不相关,但在这里却是很好的一个移花接木的方法。要在时间前面加日期才能构成星期的显示,加日期的方法有很多,各位高手也都各显神通了。gouweicao版主一开始使用了这个技巧,但后来由于思路的改变而放弃了,而willin2000版主则借助这个技巧最终得到了本期的最短公式。

以上四个技巧就是本期竞赛题主要想跟大家分享的内容,我的180个字符的公式也是由此而来,不过由于太想把条件判断放入TEXT函数当中,反而错失了更简单使用IF函数进行条件判断的做法,其他大致思路均与willin2000版主的答案比较相似。当我看到willin2000版主195个字符的解答时真的是很惊讶,题目的几个考点几乎完完全全都被用到了。看来大家脑袋里面的东西真的是相差不多,关键就是看如何去调配组合了。

昨天写的比较急,还有一些想再补充一下:

除了上面提到的四点内容,其他有关在TEXT函数中使用的一些小技巧可参考前面所提到的那个“Text函数用法”帖中的相关说明。

此外有关在TEXT函数中进行数值的相等比较还有一点需要特别说明一下,如果比较对象是无穷小数,那么由于Excel数值运算保留位数的问题,直接使用=号进行比较会出现错误,例如:

=TEXT(1/3,"[="&1/3&"]!a;!b")  这个公式的本意是当第一参数等于1/3时显示字符a,其他情况显示字符b,可是公式的结果却得到了b。

要使公式能够真正起作用,需要将数值转换为文本再进行比较:

=TEXT(1/3&"","[="&1/3&"]!a;!b")   这个公式的返回结果才是a。需要注意的是,这个公式并不是将两个文本字符串进行比较,比较的还是1/3这个运算结果的数值,只不过将第一参数和第二参数中的运算结果统一了保留位数的标准,可以进行真正的数值比较了。例如下面这个公式也可以得到结果a:

=TEXT(1/3&"","[="&2/6&"]!a;!b")

我此帖一开始所提到的180字符的公式,以及下面红色字体的几个公式中都使用到了这种条件判断方式,其中“SUBSTITUTE(B2&"秒","点","时")/60&""”的作用即在于此。由于后来我发现,第一参数用过&""后,第二参数中就不再需要&"",因此这几个公式都可以比原来再减少3个字符,因此再做了修改。

下面整理一下本期中比较好的思路解法,包括我设想和修改的一些公式:

195字符:=TRIM(LEFT(TEXT(MAX((B2=TEXT(QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4}),"h点m分s"))*{9,3}),"!"&A2&"第aaa次-;;"&REPT("  ",9))&TEXT(SUBSTITUTE(B2&"秒","点","时")/60,"m点s.00分"),14))

189字符:=TEXT(MAX(--TEXT(SUBSTITUTE(B2&"秒","点","时")/60&"","[="&QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4})/60&"]""08-7-"&{7,1}&" ""h:m:s.00;!0")),"[>0]!"&A2&"第aaa次-m点s.00分;")

188字符:=TEXT(TEXT(SUM((-SUBSTITUTE(B$2:B$16&"秒","点","时")>=-SUBSTITUTE(B2&"秒","点","时"))*(A$2:A$16=A2)),"[=1]2;[="&COUNTIF(A:A,A2)&"]3;4")+SUBSTITUTE(B2&"秒","点","时")/60,"[<4]!"&A2&"第aaa次-m点s.00分;")

187字符:=TEXT(SUM((-SUBSTITUTE(B$2:B$16&"秒","点","时")>=-SUBSTITUTE(B2&"秒","点","时"))*(A$2:A$16=A2))+SUBSTITUTE(B2&"秒","点","时")/60,"[<2]!"&A2&"第一次-m点s.00分;[>"&COUNTIF(A:A,A2)&"]!"&A2&"第二次-m点s.00分;")

184字符:=TEXT(MIN(--TEXT(SUBSTITUTE(B2&"秒","点","时")/60&"","[="&QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4})/60&"]"&{2,3}&"."&REPT(0,9)&";4")),"[<4]!"&A2&"第aaa次-m点s.00分;")

180字符:=LOOKUP("々",IF({0,1,1},IF(B2=TEXT(QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4,0}),"h点m分s"),A2&TEXT({0,3,2}+SUBSTITUTE(B2&"秒","点","时")/60,"第aaa次-m点s.00分")),""))

177字符:=TEXT(MAX(--TEXT(SUBSTITUTE(B2&"秒","点","时")/60&"","[="&QUARTILE(IF(A$2:A$16=A2,--SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4})/60&"]!"&{3,1}&"G/通用格式;4")),"[>4]!"&A2&"第aaa次-m点s.00分;")

163字符:=TEXT(MIN(IF(TEXT(QUARTILE(IF(A$2:A$16=A2,1*SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4}),"h点m分s")=B2,{2,3}))+SUBSTITUTE(B2&"秒","点","时")/60,"[>1]!"&A2&"第aaa次-m点s.00分;")

好了,就讲到这里吧。有事跟帖,无事退朝。

 

[此贴子已经被作者于2008-7-24 10:05:41编辑过]

TA的精华主题

TA的得分主题

发表于 2008-7-22 15:59 | 显示全部楼层

学习啦

1,没注意过"x时x分x秒"的问题

2,QUARTILE函数第一次见到

3,使用TEXT想到了,可是不会

TA的精华主题

TA的得分主题

发表于 2008-7-23 00:24 | 显示全部楼层
QUOTE:
以下是引用willin2000在2008-6-30 19:38:21的发言:

答案已发送至chrisfang版主, 2种方法 *^__^*  :

优化原来的思路公式长172.

新思路的最新长度163个字符.

QUOTE:
4,163字符: =TEXT(MIN(IF(TEXT(QUARTILE(IF(A$2:A$16=A2,1*SUBSTITUTE(B$2:B$16&"秒","点","时")),{0,4}),"h点m分s")=B2,{2,3}))+SUBSTITUTE(B2&"秒","点","时")/60,"[>1]!"&A2&"第aaa次-m点s.00分;")


高!实在是高!只有猛学习的份。

TA的精华主题

TA的得分主题

发表于 2008-7-23 11:20 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

哎,原来是审题有误。看到方版题目中第2点和第3点要求,还以为B列的数据也要随机生成的呢!

关于直接将答案写在帖子里,非常抱歉。记得给版主一共发了三个帖子,第一个帖子是严格遵循论坛和版主的要求发的,可是发出去之后没有显示出来(级别太菜了可能~~),还以为所有的帖子版主都会审核后才贴上来呢,后来感觉有更精简的答案,兴奋之余也就直接帖在帖子里了,真是非常之对不起。

参与也是一种乐趣,现在见到这么多的精彩答案,要努力学习了,谢谢高手们的智慧分享

TA的精华主题

TA的得分主题

发表于 2008-7-23 16:54 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

需要补充一个技巧或知识点,MIN{FALSE,FALSE}=0,MIN{FALSE,3}=3,MIN{2,3}=2,我在最开始时曾闪过使用MIN,但当时想当然地以为没法得出结果.在进一步的优化过程中,又重新具体的试了,才发现是可以使用的,这为节省字符起了很大作用.这也就是我想分享的另外一点就是,有时候一闪而过的念头一定要试一下,不要马上放弃,很多时候,别有洞天就是这样发生的.

谢谢chrisfang兄将TEXT的应用又掀起一个高潮.

下面一些是有关TEXT使用的帖子,有的是以前的竞赛题,有的是高手的经验之谈,顺便汇总一下,给刚开始学习TEXT函数的网友作个参考:

[原创]你也许未曾见过这样的Text函数用法

[讨论]看下列条件,用TEXT能玩出什么新花样?

[分享]将带小数的数值转换为代表时间的方法

Text基础: 应用技巧集锦

[第28期]时间归类统计[已总结]

[第29期]高考最高分统计排序

[31期]求不重复组合之和及个数[已结]

将中文日期文本逆转为数字日期值(新解)

[分享]九种人民币大写数字相互转换及新增人民币写法三种

金额中文式大写公式设计

转换大写人民币公式新解

[此贴子已经被作者于2008-7-25 21:36:08编辑过]

TA的精华主题

TA的得分主题

发表于 2008-7-24 00:06 | 显示全部楼层

谢谢chrisfang兄详细精彩总结,谢谢willin2000兄给的精彩链接。

我也补充两句:

1、思路决定出路:平时没用过Quartile,这次在willin2000兄明显提示下终于想出他的163字符。而我第一个解法苦于如何构建一个包含Max、Min和B2的数组,无奈用了Match+Choose。第二个解法用了COUNTIF配合计数来做,思路的改变,直接省了很多字符。因此,思路非常关键。

2、同样的思路,我最省了吗?很多时候,我们会不断地问自己这个问题,有些小技巧在这次答题中可以说说的,比如:

(1)正负号与大小于号的反转,大家都知道--减负运算转换文本为数值,因此很多--substitute<--substitute。其实,仅一个减号也可以转换,但得到的是负数,需要将比较运算符反过来。因而从-s>-s就省略2个字符;sum(-s>-s)+1。

(2)这种计数方式变通为sum(-s>=-s),再省1个字符。

(3)-(SUBSTITUTE(B2,"点","时")&"秒")变为-SUBSTITUTE(B2&"秒","点","时"),秒字换个地方,省一对括号。

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-7-24 09:56 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

又想到了一些内容进行了一些补充,修改在21楼总结帖中了。红色字体部分为新修改的内容。

TA的精华主题

TA的得分主题

发表于 2008-7-24 15:07 | 显示全部楼层

我在取最大和最小的地方出了问题,看了点评后,学习了。

Quartile平时都没用过!

TA的精华主题

TA的得分主题

发表于 2012-2-24 20:40 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-6-5 17:20 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
不用quartile公式要长很多
SMALL(IF($A$2:$A$16=A3,--SUBSTITUTE($B$2:$B$16&"秒","点","时")),IF({1,0},COUNTIF($A$2:$A$16,A3),1))
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-21 18:55 , Processed in 0.052582 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表