【问题标题】:Access VBA Loop (Not Responding)访问 VBA 循环(无响应)
【发布时间】:2015-11-02 09:16:04
【问题描述】:

我正在遍历记录集以执行一些基本功能或编辑。

通常对于超过 50 条记录的记录集,访问将停止响应。

我在循环命令之前有me.repaint,但窗口总是冻结并且访问标题栏显示:...(未响应)。

知道如何解决这个问题吗?

谢谢。

戴夫。

编辑:添加循环代码

If Me.Dirty = True Then Me.Dirty = False
Dim rs As DAO.Recordset
Set rs = Me.Guardians_Subform1.Form.Recordset

Dim strFirstName, strLastName As String

If Not (rs.EOF And rs.BOF) Then
    rs.MoveFirst 

    Do Until rs.EOF = True     
rs.Edit
    strFirstName = Trim(StrConv(rs!FirstName, 3))
    strLastName = Trim(StrConv(rs!LastName, 3))
    If rs!FirstName <> strFirstName Then
    rs!FirstName = strFirstName
    End If

    If rs!LastName <> strLastName Then
    rs!LastName = strLastName
    End If

     rs.Update
       rs.MoveNext
Me.Repaint
    Loop  
Else
    MsgBox "There are no records in the recordset."
End If
Set rs = Nothing 

【问题讨论】:

  • 嗨,戴夫,请您提供此代码。我们会更容易为您提供帮助。
  • 此外,访问应该能够处理最大为1gig 的记录集。你的记录有多大?
  • 最后一个记录集少于 100 条记录。我已经添加了循环代码。谢谢!
  • 为什么不只运行一个更新语句来修剪字段值?

标签: ms-access vba


【解决方案1】:

正如其他人指出的那样,您可以使用 DoEvents 释放您的处理器以在继续之前执行其他操作。当我在循环中使用 DoEvents 时,我使用了一个计数器。

Dim iCounter as Integer

Do Until
' some code here
   iCounter=iCounter+1
   If iCounter = 100 then
      DoEvents
      iCounter=0
   End if
Loop

这可以防止 DoEvent 过于频繁地触发并导致您的整体代码变慢。将计数器调整为您认为合适的任何迭代。

【讨论】:

    【解决方案2】:

    您需要在循环中调用DoEvents-Function 以将控制权传递给操作系统以重绘您的Access-GUI 并处理可能需要处理的任何其他窗口消息。这样,应用程序将不会在任务管理器和标题栏中标记为“未响应”。

    Do Until rs.EOF = True
      [...]
      rs.MoveNext
      DoEvents
    Loop  
    

    有一个小的性能折衷。如果不调用 DoEvents,则循环的总执行时间会短一些,但 Access 将不执行任何其他操作,然后处理您的循环。因此它似乎没有响应。

    【讨论】:

      【解决方案3】:

      使用记录集循环进行此类编辑并不是最好的方法。 UPDATE 查询效率更高。

      例如

      UPDATE tblGuardians
      SET FirstName = Trim(StrConv(FirstName, 3))
      WHERE StrComp(FirstName, Trim(StrConv(FirstName, 3)), 0) <> 0
      

      LastName 也是如此。

      这使用StrComp 而不是简单的&lt;&gt; 比较,因为后者不区分大小写。第三个参数0=vbBinaryCompare

      【讨论】:

      • 我同意,单个 SQL 语句通常比通过记录集循环编辑多条记录要好得多。 - 但是这个答案并没有解决处理循环时访问冻结的一般问题。
      • 谢谢!所以我应该这样做: DoCmd.RunSQL "UPDATE tblGuardians SET Firstname = FirstName = Trim(StrConv(FirstName, 3)) WHERE ID =" & rs![ID] & ";"
      • @DaveB:不,这个查询不在记录集循环中运行,这就是重点。它一次更新所有记录。此查询(加上姓氏查询)是循环代码的替换
      猜你喜欢
      • 1970-01-01
      • 2015-09-29
      • 2019-08-29
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      • 2013-07-17
      • 1970-01-01
      相关资源
      最近更新 更多