前面说过,Excel本身也可以作为数据库来使用。
我们在使用VBA处理Excel数据的时候,很多时候就是对数据进行分类汇总、查找等等。一般这种功能都是使用字典来实现,比如汇总数据功能。
假设数据源是这样的:
序号 | 项目 | 数据 | 备注 |
---|---|---|---|
1 | A | 856 | |
2 | B | 999 | |
3 | A | 774 | |
4 | C | 686 | |
5 | B | 372 |
用字典来汇总数据的代码:
Sub vba_main()
Dim arr() As Variant
Dim i_row As Long
'获取最后一行的行号
i_row = Cells(Cells.Rows.Count, 1).End(xlUp).Row
'读取数据
arr = Range("A1").Resize(i_row, 4).Value
'声明字典对象
Dim dic As Object
Set dic = VBA.CreateObject("Scripting.Dictionary")
Dim i As Long
'循环统计,项目作为字典的key,统计的数据作为item
For i = 2 To i_row
dic(VBA.CStr(arr(i, 2))) = dic(VBA.CStr(arr(i, 2))) + VBA.CDbl(arr(i, 3))
Next
Dim keys As Variant, items As Variant
keys = dic.keys()
items = dic.items()
'输出
Range("F1").Resize(UBound(keys) + 1, 1).Value = Application.WorksheetFunction.Transpose(keys)
Range("G1").Resize(UBound(items) + 1, 1).Value = Application.WorksheetFunction.Transpose(items)
End Sub
得到结果:
A | 1630 |
---|---|
B | 1371 |
C | 686 |
程序不算复杂,这样的程序一旦数据源有些改动,比如需要按照2个甚至多个条件来分类汇总的时候,这段代码就需要进行改动了:
dic(VBA.CStr(arr(i, 2))) = dic(VBA.CStr(arr(i, 2))) + VBA.CDbl(arr(i, 3))
如果简单的用&把多个条件的字段数据进行连接起来,可能会出现一些问题。
比如现在需要按2个条件汇总数据:
序号 | 条件1 | 条件2 | 数据 | 备注 |
---|---|---|---|---|
1 | AB | C | 856 | |
2 | B | A | 999 | |
3 | A | BC | 774 | |
4 | C | A | 686 | |
5 | B | A | 372 |
序号1和序号3的2个条件连接起来都是ABC,可是想要的结果显然不是这样的,这个时候可能就会在2个条件连接的中间再加一个特殊的符号,用这样的方式来避免这种错误。
总的来说,对这样一个简单的程序,代码改起来都会有一点点小麻烦,让我们看看用ADO是如何做的:
Sub Test()
Dim AdoConn As Object
Set AdoConn = VBA.CreateObject("ADODB.Connection")
'打开数据库
AdoConn.Open "Provider =Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES"";"
Range("F1").CopyFromRecordset AdoConn.Execute("select 项目,Sum(数据) from [Sheet2$] group by 项目", , 1)
AdoConn.Close
Set AdoConn = Nothing
End Sub
可以看到,代码非常的简洁清爽,其中只有一句是专用的:
Range("F1").CopyFromRecordset AdoConn.Execute("select 项目,Sum(数据) from [Sheet2$] group by 项目", , 1)
其他几乎所有使用ADO的都是一样的代码,一旦需要修改按2个条件汇总,只需要修改一下sql语句就可以了:
Range("F1").CopyFromRecordset AdoConn.Execute("select 条件1,条件2,Sum(数据) from [Sheet2$] group by 条件1,条件2", , 1)
仅仅是修改了一下sql语句中需要分类汇总用的字段名称,相比用字典来汇总简化了非常多。