我有以下代码来遍历两个表并将它们合并到一个新表中:
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条记录为空白。
基本问题是:如何移动到下一行进行编辑和更新?
答案 0 :(得分:1)
你想要完成的事情并不完全清楚
根据我的理解,您正试图将Table2
的前4个记录转换为表Temp
中的列。
在这里,您为每个循环的字段打开rs(3)
,但是您永远不会在该循环中关闭它;你把它关在环外面,在一个甚至可能都没有打开的水平......
所以,首先要将Set rst(3) = Db.OpenRecordset("Test")
移到所有循环之外。
然后不清楚为什么要使用rst(3).Move 0
和rst(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
我不是说这会起作用,你当然可以清理代码中的逻辑,但这应该会让它变得更好。