欢迎转发和点一下“在看”,文末留言互动!
置顶公众号或设为星标及时接收更新不迷路
朋友们好,这里是EXCEL应用之家,坚持分享EXCEL操作技巧。
今天来和大家分享一道按条件统计的题目。题目稍微有些难度,今天的推文中通过一条公式,三段代码来从不同角度解析这道题目。
原题是这样的:
有这样一组清单(我截取了一部分,如上图),记录了每个用户的登录时间。现在需要找出那些连续七天都有登录的用户名单。
提到连续问题,就要考虑使用FREQUENCY函数了。
01
FREQUENCY函数法
在单元格F3中输入下列公式,并向下填充。
=INDEX(A:A,SMALL(IF(FREQUENCY(ROW($1:$45),(B$3:B$46-B$2:B$45<>1)*ROW($1:$45))>=7,ROW(A$2:A$46)),ROW(A1)))
这个类型的题目我们在FREQUENCY函数的专题帖中有过相关讨论,这里就不再详细介绍了。
如有问题朋友们可以给我留言!
02
VBA循环法
完整代码如下:
Sub 连续7天() Dim i%, j%, h%, m%, k%, arr As Variant, brr As Variant arr = Range("A1").CurrentRegion.Offset(1) ReDim brr(1 To 10, 1 To 1) For i = 1 To UBound(arr) - 1 If arr(i, 1) <> arr(i + 1, 1) Then k = k + 1 For j = h + 1 To i - 1 If CDate(arr(j + 1, 2)) - CDate(arr(j, 2)) = 1 Then m = m + 1 If m + 1 >= 7 Then brr(k, 1) = arr(j, 1) End If Next If m + 1 < 7 Then k = k - 1 h = i: m = 0 End If Next [E3].Resize(UBound(brr), 1) = brrEnd Sub
简单说一下这段代码。
判断一下前后两个相邻的单元格相减结果是否为1。如果是,就对变量m累积加1。当m+1的值大于等于7后(为什么要m+1?),对应的人名符合题目设定的条件,将其录入到数值brr中。
若m+1小于7,则表明在同一个人对应的区域中没有连续7天登录,这时对变量k要停留在当前的累计值不动,直到下一个符合条件的人名出现。原因是变量k控制着数组brr的行数。
在变量j循环时,通过变量h来控制不同用户的起始位置。
03

VBA循环法
完整代码如下:
Sub 连续7天1() Dim i%, m%, k%, arr As Variant, brr As Variant arr = Range("A1").CurrentRegion.Offset(1) ReDim brr(1 To 10, 1 To 1) k = 1 For i = 1 To UBound(arr) - 1 If arr(i, 1) <> arr(i + 1, 1) Then k = k + 1 If arr(i, 1) = arr(i + 1, 1) Then If CDate(arr(i + 1, 2)) - CDate(arr(i, 2)) = 1 Then m = m + 1 If m + 1 >= 7 Then brr(k, 1) = arr(i, 1) End If Else If m + 1 < 7 Then k = k - 1 m = 0 End If Next [E3].Resize(UBound(brr), 1) = brrEnd Sub
和上面一段代码相似。都是通过判断在同一个相同人名的区域内,是否连续7天登录,根据结果来录入数据。
04
VBA字典方法
完整代码如下:
Sub 连续7天2() Dim i%, arr As Variant, mydic As Object, d arr = Range("A2:B46") Set mydic = CreateObject("scripting.dictionary") For i = 1 To UBound(arr) If Not mydic.exists(arr(i, 1)) Then mydic(arr(i, 1)) = Array(arr(i, 2), 1) Else If CDate(arr(i, 2)) - CDate(mydic(arr(i, 1))(0)) = 1 Then mydic(arr(i, 1)) = Array(arr(i, 2), mydic(arr(i, 1))(1) + 1) Else mydic(arr(i, 1)) = Array(arr(i, 2), 1) End If End If Next For Each d In mydic.keys If mydic(d)(1) < 7 Then mydic.Remove (d) Next [E3].Resize(mydic.Count, 1) = Application.Transpose(mydic.keys)End Sub
这段代码使用了字典方法。同时,它也可以处理用户名为乱序排列的情况。
我就知道你“在看”