Recordset编辑并更新错误的记录

时间:2013-09-06 06:52:58

标签: vba ms-access dao

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

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

表1包含10条记录。此函数在Test表上正确创建10条记录。但是,只更新了第一条记录(导致新数据覆盖旧记录)。除了表Test的自动编号字段和PersonID字段外,最后9条记录为空白。

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

1 个答案:

答案 0 :(得分: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

我不是说这会起作用,你当然可以清理代码中的逻辑,但这应该会让它变得更好。