请高手来帮看看这段代码如何提高效率

slowgrace slowgrace 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
我是在ACCESS的VBA里编程。数据库就用的ACCESS 2003,VBA的代码也是直接就写在同一MDB里。用的是DAO.

下面的代码是用来一次性计算层次百分比。关于层次百分比的概念我解释在这个帖子里:http://blog.csdn.net/slowgrace/archive/2009/04/16/4084636.aspx。下面这段代码对一个有两万多条记录的节点表进行计算时需时20分钟,如果用注释掉那个则需时16分钟。注释掉的部分和没注释掉的部分的区别在,注释掉的用的是DAO的edit和update方法,没注释掉的用的是update语句。我真没想到直接用update语句还慢。但不管是哪种都太慢了,是吧?请各位前辈高人指点:

'算从lngrootid这个根节点开始的所有子节点(含根节点)的金额和百分比
'并把计算结果放在节点表的相应字段里
'返回根节点的值
Public Function CalValuePercent(strNodeTable As String, lngRootId As Long) As Single
On Error GoTo Err_CalValuePercent

Dim rstNode As DAO.Recordset, rstDetail As DAO.Recordset
Dim strSql As String
Dim sngValue As Single
Dim blnNoChild As Boolean

sngValue = 0

'得到每个孩子的值(递归)并累积自己的值(等于所有孩子的值的总和)
strSql = "SELECT lngNodeId FROM " & strNodeTable & " WHERE lngFatherId = " & lngRootId
Set rstNode = CurrentDb.OpenRecordset(strSql)
If rstNode.EOF Then
blnNoChild = True
Else
blnNoChild = False
While Not rstNode.EOF
sngValue = sngValue + CalValuePercent(strNodeTable, rstNode.Fields("lngNodeId")) '递归调用
rstNode.MoveNext
Wend
End If
rstNode.Close
Set rstNode = Nothing

'将自己的值记录到数据库里
If blnNoChild Then
strSql = "SELECT strDetailTable, lngDetailId FROM " & strNodeTable & " WHERE lngNodeId = " & lngRootId
Set rstNode = CurrentDb.OpenRecordset(strSql)
If IsBasicTable3Db(Nz(rstNode.Fields("strDetailTable"))) Then '如果是基础节点,则从基础表抄value过来
strSql = "SELECT sngValue FROM " & rstNode.Fields("strDetailTable") & " WHERE lngId = " & rstNode.Fields("lngDetailId")
Set rstDetail = CurrentDb.OpenRecordset(strSql)
sngValue = Nz(rstDetail.Fields("sngValue"))
rstDetail.Close
Set rstDetail = Nothing
End If
rstNode.Close
Set rstNode = Nothing
End If
strSql = "UPDATE [" & strNodeTable & "] SET [sngValue] = " & sngValue & " WHERE lngNodeId = " & lngRootId
CurrentDb.Execute strSql
' strSql = "SELECT lngNodeId, strDetailTable, lngDetailId, sngValue FROM " & strNodeTable & " WHERE lngNodeId = " & lngRootId
' Set rstNode = CurrentDb.OpenRecordset(strSql)
' If blnNoChild And IsBasicTable3Db(Nz(rstNode.Fields("strDetailTable"))) Then '如果是基础节点,则从基础表抄value过来
' strSql = "SELECT sngValue FROM " & rstNode.Fields("strDetailTable") & " WHERE lngId = " & rstNode.Fields("lngDetailId")
' Set rstDetail = CurrentDb.OpenRecordset(strSql)
' sngValue = Nz(rstDetail.Fields("sngValue"))
' rstDetail.Close
' Set rstDetail = Nothing
' End If
' rstNode.Edit
' rstNode.Fields("sngValue") = sngValue
' rstNode.Update
' rstNode.Close
' Set rstNode = Nothing


'计算每个孩子的百分比
If Not blnNoChild Then
strSql = "UPDATE [" & strNodeTable & "] SET [sngPercent] = " & _
"IIF(" & sngValue & "=0, 0, [sngValue]/" & sngValue & ") " & _
"WHERE [lngFatherId]=" & lngRootId
CurrentDb.Execute strSql

' strSql = "SELECT lngNodeId, sngValue, sngPercent FROM " & strNodeTable & " WHERE lngFatherId = " & lngRootId
' Set rstNode = CurrentDb.OpenRecordset(strSql)
' While Not rstNode.EOF
' rstNode.Edit
' If sngValue = 0 Then
' rstNode.Fields("sngPercent") = 0
' Else
' rstNode.Fields("sngPercent") = rstNode.Fields("sngValue") / sngValue
' End If
' rstNode.Update
' rstNode.MoveNext
' Wend
' rstNode.Close
' Set rstNode = Nothing
End If

CalValuePercent = sngValue
Exit Function

Err_CalValuePercent:
Stop
Debug.Print ERR.Description
Resume
End Function



...全文
评论 13
收藏 已收藏
分享
返回顶部
slowgrace
Access 7,731 成员 28,797 内容