|
单行或者单列很简单。单列的话,dcount应该没问题。单行使用记录集,move到目标行计算即可。
这个题目难就难在于countif的自由性(任意区域,甚至多区域),为了尽量匹配到,需要用到VBA,这里先假定是任意连续区域(多区域条件暂不考虑):
- Function Countif(ByVal strWhere As String, _
- ByVal lngSColumn As Long, _
- ByVal lngEColumn As Long, _
- ByVal lngSRow As Long, _
- ByVal lngERow As Long) As Long
-
- Dim rst As New ADODB.Recordset
- Dim i As Long, j As Long, lngCount As Long
-
-
-
- rst.Open "tbl_Countif", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
-
- '初始化,以免出错。数字格式部分暂由数据有效性处理,这里略去。
- lngCount = 0
- If lngSColumn < 1 Then lngEColumn = 1
- If lngEColumn > rst.Fields.count Then lngEColumn = rst.Fields.count
- If lngSRow < 1 Then lngEColumn = 1
- If lngERow > rst.RecordCount Then lngERow = rst.RecordCount
- For i = lngSRow To lngERow
- For j = lngSColumn - 1 To lngEColumn - 1
- If rst(j) Like "*" & strWhere & "*" Then
- lngCount = lngCount + 1
- End If
- Next
- rst.MoveNext
- Next
- Countif = lngCount
- 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
|