【问题标题】:Recordset Edits and Updates the Wrong Record记录集编辑和更新错误记录
【发布时间】:2013-09-06 06:52:58
【问题描述】:

我有以下代码循环遍历两个表并将它们合并到一个新表中:

Public Function MyFunction()
Dim Db As DAO.Database
Dim rst(1 To 3) As DAO.Recordset
Dim fld As DAO.Field
Dim fldname, fldtype As String
Dim PxID As Integer
Dim Iter, Counter As Integer

Set Db = CurrentDb
Set rst(1) = Db.OpenRecordset("Table1")

Call PrepTable                       ' Creates table named Test

rst(1).MoveFirst

Do While Not rst(1).EOF
    PxID = rst(1)!PersonID
    Set rst(2) = Db.OpenRecordset("SELECT * FROM Table2 WHERE PersonID=" & PxID)

    If rst(2).RecordCount > 0 Then
        rst(2).MoveLast
        'set limit to 4 records if recordcount > 4
        Iter = IIf(rst(2).RecordCount > 4, 4, rst(2).RecordCount)          
        rst(2).MoveFirst

        For Counter = 1 To Iter
            For Each fld In rst(2).Fields
                If fld.OrdinalPosition = 0 Then
                    fldname = "PersonID"
                Else
                    fldname = fld.Name & Trim(Str(Counter))
                End If

                If Not IsNull(fld.Value) Then
                    Set rst(3) = Db.OpenRecordset("Test")
                    'create new record on Test only if on new record on Table2
                    If (fldname = "PersonID" And Counter = 1) Then       
                        rst(3).AddNew
                    Else
                        rst(3).Move 0
                        rst(3).Edit
                    End If
                    rst(3)(fldname).Value = fld.Value
                    rst(3).Update
                    rst(3).Bookmark = rst(3).LastModified                     'not sure about this at all
                End If
            Next

        rst(2).MoveNext
        Next
        rst(3).Close
    End If

    rst(2).Close
    Set rst(2) = Nothing
    Set rst(3) = Nothing
    rst(1).MoveNext
Loop
rst(1).Close
Set rst(1) = Nothing

Debug.Print "Done."
Db.TableDefs.Refresh
DoCmd.OpenTable "Test", acViewNormal

End Function

Table1 包含 10 条记录。此函数在 Test 表上正确创建了 10 条记录。但是,只有第一条记录被更新(导致新数据覆盖旧数据)。最后 9 条记录为 Test 表的 autonumber 字段和 PersonID 字段的空白保存。

基本问题是:如何移动到下一行进行编辑和更新?

【问题讨论】:

    标签: vba ms-access dao


    【解决方案1】:

    您要完成的工作实际上并不完全清楚。
    据我了解,您正试图将 Table2 的前 4 条记录转换为表 Temp 中的列。

    在这里,您为循环通过的每个字段打开rs(3),但您永远不会在该循环中关闭它;您将其关闭在循环之外,甚至可能无法打开...

    所以,首先要将 Set rst(3) = Db.OpenRecordset("Test") 移到所有循环之外。

    那么不清楚您为什么要使用rst(3).Move 0rst(3).Bookmark = rst(3).LastModified
    添加新记录后,您无需再次调用 Edit 或在记录和书签中移动。您需要做的就是确保在复制所有字段数据之后调用rst(3).Update

    Public Function MyFunction()
    Dim Db As DAO.Database
    Dim rst(1 To 3) As DAO.Recordset
    Dim fld As DAO.Field
    Dim fldname, fldtype As String
    Dim PxID As Integer
    Dim Iter, Counter As Integer
    
    Set Db = CurrentDb
    Set rst(1) = Db.OpenRecordset("Table1")
    
    Call PrepTable                       ' Creates table named Test
    
    rst(1).MoveFirst
    Set rst(3) = Db.OpenRecordset("Test")
    Do While Not rst(1).EOF
        PxID = rst(1)!PersonID
        Set rst(2) = Db.OpenRecordset("SELECT * FROM Table2 WHERE PersonID=" & PxID)
    
        If rst(2).RecordCount > 0 Then
            rst(2).MoveLast
            'set limit to 4 records if recordcount > 4
            Iter = IIf(rst(2).RecordCount > 4, 4, rst(2).RecordCount)          
            rst(2).MoveFirst
    
            For Counter = 1 To Iter
                For Each fld In rst(2).Fields
                    If fld.OrdinalPosition = 0 Then
                        fldname = "PersonID"
                    Else
                        fldname = fld.Name & Trim(Str(Counter))
                    End If
    
                    If Not IsNull(fld.Value) Then
                        'create new record on Test only if on new record on Table2
                        If (fldname = "PersonID" And Counter = 1) Then       
                            rst(3).AddNew
                        End If
                        rst(3)(fldname).Value = fld.Value
                    End If
                Next
                If rs(3).EditMode <> dbEditNone Then
                    rst(3).Update
                End If
                rst(2).MoveNext
            Next
        End If
        rst(2).Close
        Set rst(2) = Nothing
        rst(1).MoveNext
    Loop
    rst(3).Close
    rst(1).Close
    Set rst(3) = Nothing
    Set rst(1) = Nothing
    
    Debug.Print "Done."
    Db.TableDefs.Refresh
    DoCmd.OpenTable "Test", acViewNormal
    
    End Function
    

    我并不是说这会起作用,您当然可以清理该代码中的逻辑,但这应该已经使它变得更好了。

    【讨论】:

    • 谢谢@Renaud。是的,我正在尝试转置 4 条记录。在我意识到有回复之前,我实际上已经让它按照我想要的方式工作了。是的,我确实删除了循环外的Set rst(3),而我缺少的是rst(3).Move 0, rst(3).LastModifiedrst(3).Edit 之前的最后一位。感谢您提供.EditMode 代码。我喜欢!
    猜你喜欢
    • 1970-01-01
    • 2014-10-23
    • 2022-11-27
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    相关资源
    最近更新 更多