【问题标题】:MS Access: Looping through subform records causes Error '3021'MS Access:循环子表单记录会导致错误“3021”
【发布时间】:2017-12-12 02:42:57
【问题描述】:

我有一个主窗体和一个显示多条记录的子窗体。在主表单上选中复选框时,我希望更新子表单上的所有“BoxLblTime”和“Material Arrived”字段。这是单击复选框时执行的 vba 代码:

Private Sub MaterialArrived_chkbx_Click()
   Dim temp As Variant
   Dim tempString As String
   Dim ctl As Control

   'If checkbox is checked
   If Forms("JOBS Form").Controls("MaterialArrived_chkbx").Value < 0 Then

      Dim rs As Object
      'Get records of subform
      Set rs = Forms("JOBS Form").[Order Form].Form.Recordset
      'Loop until end
      Do While Not rs.EOF
        rs.Edit
        'Update the two fields
        rs![Material arrived] = True
        rs!BoxLblTime = Now()
        rs.Update
      rs.MoveNext
      Loop
      Set rs = Nothing   
   End If
End Sub

使用此代码时有一些异常行为:

1) 当主窗体上的复选框被选中时,子窗体中的两个字段都会更新。但是如果我取消选中子表单上的复选框,然后重新选中主表单复选框,则子表单复选框保持未选中状态。

2) 当主窗体上的复选框被选中时,两个字段都会更新。但是,如果我取消选中子表单上的复选框,移动到一组新的子表单记录(下一个或后面),然后选中主表单复选框,我会收到错误:'3021' No current record。

为什么会出现这种异常行为?

编辑: 这是我使用更新查询方法的代码:

Private Sub MaterialArrived_chkbx_Click()
   If Forms("JOBS Form").Controls("MaterialArrived_chkbx").Value < 0 Then

      With CurrentDb().QueryDefs("Update Orders")
         .Parameters("[Material Arrived]").Value = True
         .Parameters("[BoxLblTime]").Value = Now()
         .Execute dbFailOnError
      End With
      Forms("JOBS Form").Form.Requery
   End If
End Sub

但我收到“未在集合中找到项目”错误。

【问题讨论】:

  • 应该使用 RecordsetClone。甚至不必声明记录集对象变量。
  • 我认为只有在我不想更改记录时才应该使用它?但我想更新记录。
  • 哎呀,没错,对不起,无视。

标签: vba forms ms-access checkbox


【解决方案1】:

我会建议另一种方法。

创建一个更新查询并传递一个布尔参数,指示材料到达值。

'Call update query
Private Sub MaterialArrived_chkbx_Click()
    With CurrentDb().QueryDefs("Update Orders")
        .Parameters("[prmMaterialArrived]").Value = Me.MaterialArrived_chkbx.Value
        .Parameters("[prmID]").Value = Me!ID
        .Execute dbFailOnError
    End With
    Me.[Order Form].Form.Requery
End Sub


'SQL
PARAMETERS [prmMaterialArrived] Bit, [prmID] Long;
UPDATE T
SET T.[Material arrived] = [prmMaterialArrived], T.BoxLblTime = Now()
WHERE (((T.ID)=[prmID]));

【讨论】:

  • 我会试试这个,然后告诉你进展如何。
  • 我创建了更新查询,添加了两个字段,然后在您的示例代码中替换了正确的名称,但是第一个参数(Material Arrived)出现了“Item not found in collection” .
  • 你检查过字段名吗?能把更新的SQL和代码贴出来看看吗?
  • 我将其添加到问题中
  • 这是不正确的:.Parameters("[Material Arrived]") 您需要添加参数名称,如我的答案所示,而不是字段名称。这也适用于其他参数。布尔值(True/False)也被传递给查询,因此当您选中它时,它将将该字段更新为 True,而当您取消选中它时,它将更新为 false。你不需要检查`If .Value
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 2013-07-10
相关资源
最近更新 更多