设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 5835|回复: 16
打印 上一主题 下一主题

Office PK 第五期,Excel挑战Access:算个数(单条件计数)

[复制链接]
1#
发表于 2016-3-27 14:59:04 | 显示全部楼层
单行或者单列很简单。单列的话,dcount应该没问题。单行使用记录集,move到目标行计算即可。

这个题目难就难在于countif的自由性(任意区域,甚至多区域),为了尽量匹配到,需要用到VBA,这里先假定是任意连续区域(多区域条件暂不考虑):
  1. Function Countif(ByVal strWhere As String, _
  2.             ByVal lngSColumn As Long, _
  3.             ByVal lngEColumn As Long, _
  4.             ByVal lngSRow As Long, _
  5.             ByVal lngERow As Long) As Long
  6.             
  7.     Dim rst As New ADODB.Recordset
  8.     Dim i As Long, j As Long, lngCount As Long
  9.    
  10.    
  11.    
  12.     rst.Open "tbl_Countif", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
  13.    
  14.     '初始化,以免出错。数字格式部分暂由数据有效性处理,这里略去。
  15.     lngCount = 0
  16.     If lngSColumn < 1 Then lngEColumn = 1
  17.     If lngEColumn > rst.Fields.count Then lngEColumn = rst.Fields.count
  18.     If lngSRow < 1 Then lngEColumn = 1
  19.     If lngERow > rst.RecordCount Then lngERow = rst.RecordCount

  20.     For i = lngSRow To lngERow
  21.         For j = lngSColumn - 1 To lngEColumn - 1
  22.             If rst(j) Like "*" & strWhere & "*" Then
  23.                 lngCount = lngCount + 1
  24.             End If
  25.         Next
  26.         rst.MoveNext
  27.     Next
  28. Countif = lngCount
  29. End Function
复制代码

暂不做窗体,有兴趣的版友可以尝试做下。建议使用组合框来设置数据的有效性。这个例子支持通配符,例如:
Countif("可*", 1, 7, 1, 2)=1
Countif("可", 1, 7, 1, 2)=0
其它说明【不可能或较困难的任务】:
  • 由于Access的数据格式必须规范化,因此不可能做出同一列数字、文本混排然后再统计数字之类的。
  • 如果需要统计数字或者日期,则需要将条件的文本转换为条件,可能需要提取运算符(and,>=之类),或者使用where子句或者filter方法,实现起来较为困难。
大家可以先参考下,算是抛砖引玉吧。
另外,本例如果用记录集的getrows可能会有更高的效率,不过也更加繁琐(所以没测试)。具体思路大约是:
  • 先根据列标起止位置,获取列名(Field.Name)。
  • 根据引用行数(Rows),起始行数(Start)和1得到的数组作为参数,调用getrows方法,得到一个二维数组。
  • 然后转二维数组为一维数组(或者一列列追加到临时表也行)。
  • 用数组的Filter方法过滤掉,得到新的数组,计算Ubound,即为Countif结果。
  • 如果是追加到临时表,则应该在追加时就使用条件,否则较难判断。追加完毕后,可以使用Count聚合函数来计算或者使用ADO的RecountCount。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
2#
发表于 2016-4-4 22:07:39 | 显示全部楼层
pureshadow 发表于 2016-4-4 15:21
这个问题归根到底,如果有用Countif或者Dcount这样的函数的话,就是脱不了循环的法子,我这样理解对不对?

固定列的话,Dcount没问题(多个Dcount相加即可)。不过域函数(D字头)的效率较低,数据较多的时候,还是用ADO会方便些,或者用Count聚合函数(不过这时候就需要写where条件子句了)。
不定列的话,则基本只能使用ADO循环了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-5 03:02 , Processed in 0.111132 second(s), 25 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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