vba 遍历记录集中的字段,而另一个记录集不是 EOF
vba loop through fields in recordset while another recordset is not EOF
我正在为访问数据库 (Access 2010) 编写一些代码,需要将非空字段从 table 提取到另一个(tbl_TempProducts 到 tbl_BrandsStocked)。在执行此操作时,需要将包含我想要 'copy and paste' 的字段的行拆分为另一个 table 的各个行。 tbl_TempProducts 中记录的第一个值应该用作 tbl_BrandsStocked 中每个新记录的第一个值,只要被传输的值与我们从中传输的记录在同一记录中。我想在 tbl_BrandsStocked 中为 tbl_TempProducts 中的每第 7 个字段创建一条新记录。
请参阅提供的图表HERE
代码有效,但 'pastes' 代码进入目标 table 的顺序不正确。
第一次写的不够清楚还请见谅post!
如果需要,我会 post 更多信息.. :)
请看下面的代码:
Private Sub btnTransfer_Click()
Dim dbs As DAO.Database
Dim temp As DAO.Recordset
Dim bStocked As DAO.Recordset
Dim fld As DAO.Field
Dim AutoID As String
Dim Product As String
Dim varProd As String
Dim PackSize As String
Dim priceType As String
Dim casesSold As String
Dim accountNumber As Integer
Dim firstRun As Boolean
Dim counter As Integer
Set dbs = CurrentDb
Set temp = dbs.OpenRecordset("SELECT * FROM tbl_TempProducts WHERE id IS NOT NULL")
Set bStocked = dbs.OpenRecordset("SELECT * FROM tbl_BrandsStocked")
counter = 0
firstRun = True
temp.MoveFirst
Do While temp.EOF = False
For Each fld In temp.Fields
If fld.Name <> "" Then
If counter = 1 Then
AutoID = Nz(fld.value, "")
If AutoID <> "" Then
AutoID = Nz(fld.value, "")
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
If accountNumber <> AutoID Then
On Error Resume Next
accountNumber = AutoID
End If
Else
counter = counter - 1
End If
ElseIf counter = 2 Then
Product = Nz(fld.value, "")
If Product <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Brand = Product
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 3 Then
varProduct = Nz(fld.value, "")
If varProduct <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Variation = varProduct
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 4 Then
PackSize = Nz(fld.value, "")
If PackSize <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!PackSize = PackSize
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 5 Then
priceType = Nz(fld.value, "")
If priceType <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked![RRP-PMP] = priceType
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 6 Then
casesSold = Nz(fld.value, "")
If casesSold <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!CPW = casesSold
bStocked.upDate
Else
counter = counter - 1
End If
End If
End If
counter = counter + 1
If counter >= 7 Then
counter = 2
bStocked.AddNew
bStocked!AccountNo = accountNumber
bStocked.upDate
End If
Next
temp.MoveNext
counter = 0
firstRun = True
Loop
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM [tbl_BrandsStocked] WHERE [Brand] Is null"
DoCmd.SetWarnings True
Set dbs = Nothing
Set temp = Nothing
Set bStocked = Nothing
Set fld = Nothing
End Sub
除了发布样本数据外,您还应该检查您的代码:
- 您从
counter = 0
开始,但没有针对此的案例,因此第一个字段将始终被忽略。故意的?
firstRun
已设置但从未使用
- 而不是所有
bStocked.MoveLast, .Edit, .Update
你应该在 bStocked 中有一个你写入的当前记录。这将使您的代码更具可读性。
编辑
我建议这样的结构:
strValue = Nz(fld.value, "")
If strValue <> "" Then
Select Case counter
Case 1: accountNumber = Val(strValue) ' add error handling!
bStocked.AddNew
bStocked!AccountNo = accountNumber
Case 2: bStocked!Brand = strValue ' Product
Case 3: bStocked!Variation = strValue ' varProduct
' etc 4..6
End Select
counter = counter + 1
If counter >= 7 Then
bStocked.upDate ' save new record
bStocked.AddNew
bStocked!AccountNo = accountNumber
counter = 2
End If
Else
' For an empty field you simply move to the next field
End If
Next fld
' save last record
bStocked.upDate
我现在已经解决了这个问题。我在目标 table 中得到错误值的主要原因是没有必要使用 "accountNumber" 变量。相反,我在遍历代码时使用 "AutoID" 变量值作为目标 table 上的第一个字段。
非常简单的修复,但不幸的是它确实花了我一段时间,因此发帖的原因是我需要一双额外的眼睛!
工作代码:
Private Sub btnTransfer_Click()
Dim dbs As DAO.Database
Dim temp As DAO.Recordset
Dim bStocked As DAO.Recordset
Dim fld As DAO.Field
Dim AutoID As String
Dim Product As String
Dim varProd As String
Dim PackSize As String
Dim priceType As String
Dim casesSold As String
Dim accountNumber As Integer
Dim counter As Integer
Set dbs = CurrentDb
Set temp = dbs.OpenRecordset("SELECT * FROM tbl_TempProducts WHERE id IS NOT NULL")
Set bStocked = dbs.OpenRecordset("SELECT * FROM tbl_BrandsStocked")
counter = 0
firstRun = True
accountNumber = 0
AutoID = 0
temp.MoveFirst
Do While temp.EOF = False
For Each fld In temp.Fields
If fld.Name <> "" Then
If counter = 1 Then
AutoID = Nz(fld.value, "")
If AutoID <> "" Then
AutoID = Nz(fld.value, "")
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 2 Then
Product = Nz(fld.value, "")
If Product <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Brand = Product
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 3 Then
varProduct = Nz(fld.value, "")
If varProduct <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Variation = varProduct
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 4 Then
PackSize = Nz(fld.value, "")
If PackSize <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!PackSize = PackSize
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 5 Then
priceType = Nz(fld.value, "")
If priceType <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked![RRP-PMP] = priceType
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 6 Then
casesSold = Nz(fld.value, "")
If casesSold <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!CPW = casesSold
bStocked.upDate
Else
counter = counter - 1
End If
End If
End If
counter = counter + 1
If counter >= 7 Then
counter = 2
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
End If
Next
temp.MoveNext
counter = 0
Loop
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM [tbl_BrandsStocked] WHERE [Brand] Is null"
DoCmd.SetWarnings True
Set dbs = Nothing
Set temp = Nothing
Set bStocked = Nothing
Set fld = Nothing
End Sub
我正在为访问数据库 (Access 2010) 编写一些代码,需要将非空字段从 table 提取到另一个(tbl_TempProducts 到 tbl_BrandsStocked)。在执行此操作时,需要将包含我想要 'copy and paste' 的字段的行拆分为另一个 table 的各个行。 tbl_TempProducts 中记录的第一个值应该用作 tbl_BrandsStocked 中每个新记录的第一个值,只要被传输的值与我们从中传输的记录在同一记录中。我想在 tbl_BrandsStocked 中为 tbl_TempProducts 中的每第 7 个字段创建一条新记录。
请参阅提供的图表HERE
代码有效,但 'pastes' 代码进入目标 table 的顺序不正确。
第一次写的不够清楚还请见谅post!
如果需要,我会 post 更多信息.. :)
请看下面的代码:
Private Sub btnTransfer_Click()
Dim dbs As DAO.Database
Dim temp As DAO.Recordset
Dim bStocked As DAO.Recordset
Dim fld As DAO.Field
Dim AutoID As String
Dim Product As String
Dim varProd As String
Dim PackSize As String
Dim priceType As String
Dim casesSold As String
Dim accountNumber As Integer
Dim firstRun As Boolean
Dim counter As Integer
Set dbs = CurrentDb
Set temp = dbs.OpenRecordset("SELECT * FROM tbl_TempProducts WHERE id IS NOT NULL")
Set bStocked = dbs.OpenRecordset("SELECT * FROM tbl_BrandsStocked")
counter = 0
firstRun = True
temp.MoveFirst
Do While temp.EOF = False
For Each fld In temp.Fields
If fld.Name <> "" Then
If counter = 1 Then
AutoID = Nz(fld.value, "")
If AutoID <> "" Then
AutoID = Nz(fld.value, "")
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
If accountNumber <> AutoID Then
On Error Resume Next
accountNumber = AutoID
End If
Else
counter = counter - 1
End If
ElseIf counter = 2 Then
Product = Nz(fld.value, "")
If Product <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Brand = Product
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 3 Then
varProduct = Nz(fld.value, "")
If varProduct <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Variation = varProduct
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 4 Then
PackSize = Nz(fld.value, "")
If PackSize <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!PackSize = PackSize
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 5 Then
priceType = Nz(fld.value, "")
If priceType <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked![RRP-PMP] = priceType
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 6 Then
casesSold = Nz(fld.value, "")
If casesSold <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!CPW = casesSold
bStocked.upDate
Else
counter = counter - 1
End If
End If
End If
counter = counter + 1
If counter >= 7 Then
counter = 2
bStocked.AddNew
bStocked!AccountNo = accountNumber
bStocked.upDate
End If
Next
temp.MoveNext
counter = 0
firstRun = True
Loop
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM [tbl_BrandsStocked] WHERE [Brand] Is null"
DoCmd.SetWarnings True
Set dbs = Nothing
Set temp = Nothing
Set bStocked = Nothing
Set fld = Nothing
End Sub
除了发布样本数据外,您还应该检查您的代码:
- 您从
counter = 0
开始,但没有针对此的案例,因此第一个字段将始终被忽略。故意的? firstRun
已设置但从未使用- 而不是所有
bStocked.MoveLast, .Edit, .Update
你应该在 bStocked 中有一个你写入的当前记录。这将使您的代码更具可读性。
编辑
我建议这样的结构:
strValue = Nz(fld.value, "")
If strValue <> "" Then
Select Case counter
Case 1: accountNumber = Val(strValue) ' add error handling!
bStocked.AddNew
bStocked!AccountNo = accountNumber
Case 2: bStocked!Brand = strValue ' Product
Case 3: bStocked!Variation = strValue ' varProduct
' etc 4..6
End Select
counter = counter + 1
If counter >= 7 Then
bStocked.upDate ' save new record
bStocked.AddNew
bStocked!AccountNo = accountNumber
counter = 2
End If
Else
' For an empty field you simply move to the next field
End If
Next fld
' save last record
bStocked.upDate
我现在已经解决了这个问题。我在目标 table 中得到错误值的主要原因是没有必要使用 "accountNumber" 变量。相反,我在遍历代码时使用 "AutoID" 变量值作为目标 table 上的第一个字段。
非常简单的修复,但不幸的是它确实花了我一段时间,因此发帖的原因是我需要一双额外的眼睛!
工作代码:
Private Sub btnTransfer_Click()
Dim dbs As DAO.Database
Dim temp As DAO.Recordset
Dim bStocked As DAO.Recordset
Dim fld As DAO.Field
Dim AutoID As String
Dim Product As String
Dim varProd As String
Dim PackSize As String
Dim priceType As String
Dim casesSold As String
Dim accountNumber As Integer
Dim counter As Integer
Set dbs = CurrentDb
Set temp = dbs.OpenRecordset("SELECT * FROM tbl_TempProducts WHERE id IS NOT NULL")
Set bStocked = dbs.OpenRecordset("SELECT * FROM tbl_BrandsStocked")
counter = 0
firstRun = True
accountNumber = 0
AutoID = 0
temp.MoveFirst
Do While temp.EOF = False
For Each fld In temp.Fields
If fld.Name <> "" Then
If counter = 1 Then
AutoID = Nz(fld.value, "")
If AutoID <> "" Then
AutoID = Nz(fld.value, "")
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 2 Then
Product = Nz(fld.value, "")
If Product <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Brand = Product
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 3 Then
varProduct = Nz(fld.value, "")
If varProduct <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!Variation = varProduct
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 4 Then
PackSize = Nz(fld.value, "")
If PackSize <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!PackSize = PackSize
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 5 Then
priceType = Nz(fld.value, "")
If priceType <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked![RRP-PMP] = priceType
bStocked.upDate
Else
counter = counter - 1
End If
ElseIf counter = 6 Then
casesSold = Nz(fld.value, "")
If casesSold <> "" Then
bStocked.MoveLast
bStocked.Edit
bStocked!CPW = casesSold
bStocked.upDate
Else
counter = counter - 1
End If
End If
End If
counter = counter + 1
If counter >= 7 Then
counter = 2
bStocked.AddNew
bStocked!AccountNo = AutoID
bStocked.upDate
End If
Next
temp.MoveNext
counter = 0
Loop
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM [tbl_BrandsStocked] WHERE [Brand] Is null"
DoCmd.SetWarnings True
Set dbs = Nothing
Set temp = Nothing
Set bStocked = Nothing
Set fld = Nothing
End Sub