VBA RecordSet函数花费太多时间使用RecordCount更新记录

时间:2019-02-03 13:44:41

标签: access-vba

我有一张桌子和一个查询。两者具有相同的数据字段,但表COLUMN名称等于查询的ROW名称。我使用以下代码成功地从查询的行数据更新了表,但是由于每个员工的表名超过50列,因此更新时间太长了-

Set rst1 = CurrentDb.OpenRecordset("SELECT * FROM tblPayRollDataTEMP")
Set rst2 = CurrentDb.OpenRecordset("SELECT * FROM qryEmpVerifySalary ")

Do Until rst1.EOF
    rst2.MoveFirst
    Do Until rst2.EOF                  
        For l = 0 To rst1.Fields.count - 1
            If rst1!EmpID = rst2!EmpID And rst1.Fields(l).Name = rst2!Head And rst1!PayBillID = TempVars!BillID Then
                With rst1
                    rst1.Edit
                    rst1.Fields(l).Value = rst2!Amount
                    rst1!totDeductions = DSum("Amount", "qryEmpVerifySalary", "[PayHeadType] = 'Deductions' AND [EmpID] = " & rst2!EmpID & "") + DLookup("NPS", "qryEmpPayEarning", "[EmpID] = " & rst2!EmpID & "")
                    rst1!totRecoveries = DSum("Amount", "qryEmpVerifySalary", "[PayHeadType] = 'Recoveries' AND [EmpID] = " & rst2!EmpID & "")
                    rst1!NetPayable = rst1!totEarnings - (Nz(rst1!totDeductions, 0) + Nz(rst1!totRecoveries, 0))
                    rst1.Update
                End With

            End If

        Next
        rst2.MoveNext
    Loop
    rst1.MoveNext
Loop

Set rst1 = Nothing
Set rst2 = Nothing

如何提高代码的性能?

1 个答案:

答案 0 :(得分:1)

您应该使用查询来更新您的记录。这将是最快的解决方案。通常,将匹配EmpID并将字段拖放到更新查询中或使用表达式。如果您必须将分组或其他复杂的东西分组,则将其分为更多查询(两个或三个)。没关系,因为最后您只执行一个更新查询。

对于您的代码,您可以替换domainaggregate函数。 DLookup()DSum()等...对于性能而言最差。一个简单的select语句的运行速度比DLookup()快。这里有一些替代品:

Function DCount(Expression As String, Domain As String, Optional Criteria) As Variant

  Dim strSQL As String

  strSQL = "SELECT COUNT(" & Expression & ") FROM " & Domain

  'Other Replacements:
  'DLookup: strSQL = "SELECT " & Expression & " FROM " & Domain
  'DMax: strSQL = "SELECT MAX(" & Expression & ") FROM " & Domain
  'DMin: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
  'DFirst: strSQL = "SELECT FIRST(" & Expression & ") FROM " & Domain
  'DLast: strSQL = "SELECT LAST(" & Expression & ") FROM " & Domain
  'DSum: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
  'DAvg: strSQL = "SELECT AVG(" & Expression & ") FROM " & Domain

  If Not IsMissing(Criteria) Then strSQL = strSQL & " WHERE " & Criteria
  DCount = DBEngine(0)(0).OpenRecordset(strSQL, dbOpenForwardOnly)(0)

End Function