Sub adoSort()
Dim Conn As Object, rst As Object, objRst As Object, strSQL$, k&, tmp!, arr
'---------------------------------------------------------------------------------------
'以下代码建立连接
Set Conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
Set objRst = CreateObject("ADODB.Recordset")
Conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;Imex=1;Hdr=yes';Data Source=" & ThisWorkbook.FullName
'---------------------------------------------------------------------------------------
'从Weight取回数据到recordset对象
strSQL = "Select * from [Weight$b2:e] where 姓名<>'' and 班组<>'临时'"
rst.Open strSQL, Conn
ThisWorkbook.Worksheets("Weight").Range("g3").CopyFromRecordset rst '取回数据到相应位置
rst.movefirst '当你用copyfromrecordset取回数据后,当前记录移至最后,因为你后面还要用rst给objrst添加记录,所以需要把当前记录移至首位
'---------------------------------------------------------------------------------------
'建一个临时的recordset对象进行排序,此对象有id字段为递增字段,排序后,恢复以此字段排序
'以使原表顺序不变
With objRst
.Fields.Append "ID", adInteger '此字段为保留原始顺序
.Fields.Append "sex", adVarWChar, 1 '此字段为分组依据,以便进行按性别排序
.Fields.Append "class", adVarWChar, 10 '此字段为分组依据,以便进行按班组排序
.Fields.Append "Weight", adSingle '此字段为排序依据
.Fields.Append "rRank", adInteger '存放排序结果
.Fields.Append "gRank", adInteger '存放按性别排序结果
.Fields.Append "bRank", adInteger '存放按班组排序结果
.Open locktype:=adLockBatchOptimistic
'---------------------------------------------------------------------------------------
'以下程序把数据放入objRst中 这里是先用rst把数据取回,再把数据传给objRst,当然你可以用数组把记录传给objRst
Do While Not rst.EOF
k = k + 1
.addnew Array(0, 1, 2, 3), Array(k, rst!性别, rst!班组, rst!体重)
rst.MoveNext
Loop
'---------------------------------------------------------------------------------------
'以下程序全体排序
.Sort = "Weight Desc" '体重降序排序
k = 0 '初始化变量
tmp = 0 '初始化变量
Do While Not .EOF
If !Weight.Value <> tmp Then '只有当下一个体重不等于上一个部分时,名次才加1
k = k + 1
tmp = !Weight.Value '记录当前体重,以与下一个体重比较
End If
!rRank.Value = k '赋与名次
.MoveNext
Loop
'---------------------------------------------------------------------------------------
rst.Close '数据放入objRst后,使命完成,关闭对象
strSQL = "Select distinct 性别 from [Weight$b2:d]" '提取不重复性别,为性别内排序做准备,如果你用数据取代rst的话,可以用字典取不重复值
rst.Open strSQL, Conn
'---------------------------------------------------------------------------------------
'以下程序对按性别排序
.Sort = "Weight Desc"
Do While Not rst.EOF 'rst内存有不重复性别
.Filter = "sex='" & rst!性别.Value & "'" '循环rst记录,依次以性别过滤objRst
k = 0
tmp = 0
Do While Not .EOF
If !Weight.Value <> tmp Then
k = k + 1
tmp = !Weight.Value
End If
!gRank.Value = k
.MoveNext
Loop
rst.MoveNext
Loop
'---------------------------------------------------------------------------------------
rst.Close '数据放入objRst后,使命完成,关闭对象
strSQL = "Select distinct 班组 from [Weight$b2:d] where 班组<>'临时'" '提取不重复性别,为性别内排序做准备
rst.Open strSQL, Conn
'---------------------------------------------------------------------------------------
'以下程序对按班组排序
.Sort = "Weight Desc"
Do While Not rst.EOF 'rst内存有不重复性别
.Filter = "class='" & rst!班组.Value & "'" '循环rst记录,依次以班组过滤objRst
k = 0
tmp = 0
Do While Not .EOF
If !Weight.Value <> tmp Then
k = k + 1
tmp = !Weight.Value
End If
!bRank.Value = k
.MoveNext
Loop
rst.MoveNext
Loop
'---------------------------------------------------------------------------------------
.Filter = 0 '排序完成,清除过滤器
.Sort = "ID" '恢复原始顺序
arr = .GetRows(Fields:=Array("rRank", "grank", "brank")) '把总名次,性别名次,班组名次放入数组
End With
'把结果写回工作表区域
ThisWorkbook.Worksheets("Weight").Range("k3"). _
Resize(UBound(arr, 2) + 1, UBound(arr, 1) + 1) = Application.Transpose(arr)
End Sub
|