1

所以我有一个内置的系统,它设置了一些不同的标志等等,但我想做的一件事是获取临时表的内容并将其发送到另一个用于跟踪的表。我正在尝试使用插入循环来做到这一点,但我根本无法弄清楚如何使其按预期工作。

Private Sub Form_Load()
    DoCmd.SetWarnings False
    DoCmd.OpenQuery ("qryDeleteEmail")
    Dim db As Object
    Dim rst As Object
    Dim test As Object

    Set db = Application.CurrentDb
    Set rst = db.OpenRecordset("qryDate")
    Set test = db.OpenRecordset("tblEmailTemp")

    If Me.RecordsetClone.RecordCount = 0 Then
        MsgBox ("No delinquent accounts. No email will be generated.")
        Me.Refresh
        DoCmd.Close acForm, "qryDate", acSaveNo
        DoCmd.CancelEvent
    Else
        rst.MoveFirst
        Do Until rst.EOF
           rst.Edit
           rst!NeedsEmail = 1
           rst.Update
           rst.MoveNext
        Loop

        'DoCmd.Requery
        'rst.Close


        DoCmd.RunMacro ("StagingTable")
        test.MoveFirst

        Do Until test.EOF
            CurrentDb.Execute "Insert Into EmailTracking (Account, ExpirationDate)" & _
                "Values ('" & AccountName & "', '" & ExpirationDate & "')"
            test.MoveNext              
        Loop

        test.Close
        rst.MoveFirst

        Do Until rst.EOF
            rst.Edit
            rst!EmailSent = 1
            rst.Update
            rst.MoveNext
        Loop

        'DoCmd.Requery
        rst.Close
        DoCmd.RunMacro ("Close")
        'DoCmd.OpenQuery ("qryDeleteEmail")
    End If
    Exit Sub
End Sub

现在发生的事情是将临时表的第一条记录复制两次。例如,我有一个帐户名 A 和一个帐户名 S,但不是插入 A 的记录和 S 的记录,而是简单地插入 A 两次。

任何帮助将不胜感激!

4

2 回答 2

4

创建并测试一个更简单的程序,该程序只专注于您要解决的问题。不幸的是,我不确定那个问题是什么。反正我会建议这个...

Public Sub TestLoopThruTable()
    Dim db As DAO.database
    Dim test As DAO.Recordset
    Dim strInsert As String

    DoCmd.SetWarnings True ' make sure SetWarnings is on
    Set db = CurrentDb
    Set test = db.OpenRecordset("tblEmailTemp")
    Do While Not test.EOF
        strInsert = "INSERT INTO EmailTracking (Account, ExpirationDate)" & vbCrLf & _
            "VALUES ('" & AccountName & "', '" & ExpirationDate & "')"
        Debug.Print strInsert
        'db.Execute strInsert, dbFailOnError
        test.MoveNext
    Loop
    test.Close
    Set test = Nothing
    Set db = Nothing
End Sub

ExpirationDate)请注意,在您的原始版本中和之间没有空格Values。我使用了换行符 ( vbCrLf) 而不是空格,但两者都可以让 db 引擎满意。

我确定SetWarnings是开着的。在您的代码中,您在开始时将其关闭,但从未再次将其重新打开。使用SetWarningsoff 操作会抑制重要信息,否则您可以使用这些信息来理解代码问题。

当该代码循环遍历记录集时,它只是创建一个INSERT语句并为每一行显示它。您可以在立即窗口中查看输出(使用Ctrl+g键盘快捷键转到那里)。复制其中一个INSERT语句并通过粘贴到新 Access 查询的 SQL 视图中进行测试。如果它在那里失败,找出你需要改变什么来满足数据库引擎。如果INSERT成功,请尝试从您的代码中执行它们:db.Execute通过从该行的开头删除单引号来启用该行。

您编写VALUES子句的方式似乎[ExpirationDate]是一个文本字段。但是,如果它的数据类型实际上是日期/时间,则不要在要插入的值周围加上引号;使用#日期分隔符而不是引号。

还要确保包含Option Explicit在代码模块的声明部分中,如下所示:

Option Compare Database
Option Explicit

我提到了这一点,因为在这个问题的早期版本中你展示了Option Compare但没有Option Explicit。尝试对代码进行故障排除Option Explicit是浪费时间 IMO。

于 2012-12-27T18:01:20.637 回答
1

我不确定您要在这里做什么;很难理解声明ErrorHandler中的内容Else(即使已评论)。

就循环记录集而言,我建议您阅读一些有关 MS-Access 中 VBA 编程基础的内容。您可以从阅读以下文章开始。这是关于 VBA 记录集的快速介绍,然后是 VBA 中最常见的错误。

http://allenbrowne.com/ser-29.html

http://www.techrepublic.com/blog/10things/10-mistakes-to-avoid-when-using-vba-recordset-objects/373

它应该可以帮助您改进代码。

于 2012-12-27T17:00:53.120 回答