我有一个表单myForm,其中包含一个子表单mySubform
。 mySubform
中的记录与myForm
的记录来源有多对一关系,正如预期的那样,mySubform
,myCombo
中有一个组合框,其值为链接到mySubform
记录源的其中一列。
通过删除mySubform
中的当前值,我一直难以删除myCombo
中的记录。我已将下面的代码放在OnChange
myCombo
事件之下(在尝试了许多不同的替代方案之后)。
请注意,我已经简化了删除查询,并且实际的后端工作正常(SQL Server)。但是,执行删除操作后,执行到达Me.Requery
时出现此错误:
错误3162您试图将Null值分配给不是Variant数据类型的变量。
此外,在让degugger跳过Me.Requery
并返回表单后,删除的记录会在该特定记录的每个组合框和文本框中显示“#DELETED”,并且mySubform
不是任何记录超越这一点。
我查找了很多资源并尝试了不同的语句,而不是Me.Requery,但到目前为止还没有。非常感谢帮助。
Private Sub myCombo_Change()
If IsNull(Me.myCombo.Text) Or Me.myCombo.Text = vbNullString Then
Dim strSql As String
strSql = "DELETE FROM mySubformRecordSource WHERE PrimaryKeyColumn= " & theCurrentPrimaryKeyValueForTheValueIn_MyCombo
CurrentDb.Execute strSql
Me.Requery
End If
End Sub
答案 0 :(得分:1)
没有选择使用过的游标等我认为解决方案可能只是简单地重新查询"父表单由子表单的代码调用。
但是我在过去的项目中也发现了类似的情况(对不起,我不再使用VBA)并且requery命令是在子窗体上完成的,但是从主窗体代码完成,类似这样的东西:
If local_procedures.deleteContratto(anagrafica_id_par, servizio_id_par) = OK Then
Me.subfrm_contratti_frm_anagrafica.Requery
...
在这种情况下,你可以委托父表单来调用子表单的更新过程和更新逻辑(.Requery
),例如通过subForm上的事件监听父节点。
为了完整起见,我开始暗示游标,因为我认为它是记录集之间这种同步失败的根本原因,父表单和子表单一。
关于在SQL Server后端使用dbSeeChanges
和db.Execute
以及生成的默认游标,有很多建议。
这是一个代码片段,其中从子节点引发自定义事件以从父节点捕获,该父节点被委托执行有关子节点的代码。
这种模式并没有打破父子/一对多逻辑,假设父母的决定权比儿童多。
' in mySubform
' assuming theCurrentPrimaryKeyValueForTheValueIn_MyCombo is a Long ID
Public Event DeleteRequest(record_ID As Long)
Private Sub myCombo_Change()
If IsNull(Me.myCombo.Text) Or Me.myCombo.Text = vbNullString Then
RaiseEvent DeleteRequest(theCurrentPrimaryKeyValueForTheValueIn_MyCombo)
End If
End Sub
' in myForm
Private WithEvents frmMySubform As Form__mySubform
' you could have more instances of mySubform concerning different issues or subrecords and manage each one correctly ...
Private WithEvents frmMySubform2nd As Form__mySubform
Private Sub frmMySubform_DeleteRequest(record_ID As Long)
Dim strSql As String
strSql = "DELETE FROM mySubformRecordSource WHERE PrimaryKeyColumn= " & record_ID
CurrentDb.Execute strSql
With Me.frmMySubform.Form
.Requery
' ...
end With
End Sub
Private Sub frmMySubform2nd_DeleteRequest(record_ID As Long)
Dim strSql As String
strSql = "DELETE FROM my2ndSubformRecordSource WHERE PrimaryKeyColumn= " & record_ID
CurrentDb.Execute strSql
With Me.frmMySubform2nd.Form
.Requery
' ...
end With
End Sub
答案 1 :(得分:0)
我在阅读本讨论后把Me.Dirty = False解决了这个问题: Editing Record issues in Access / SQL (Write Conflict)
Private Sub myCombo_Change()
If IsNull(Me.myCombo.Text) Or Me.myCombo.Text = vbNullString Then
Me.Dirty = False
Dim strSql As String
strSql = "DELETE FROM mySubformRecordSource WHERE PrimaryKeyColumn= " & theCurrentPrimaryKeyValueForTheValueIn_MyCombo
CurrentDb.Execute strSql
Me.Requery
End If
End Sub
表单和子表单现在完美无缺,但我仍然不太了解解决方案背后的完整逻辑。它与Me.Dirty = False有关,在以编程方式删除整个记录之前,保存对不可为空(或可为空,两者都工作正常)列的内容的更改。但究竟如何,我不知道并会欣赏输入。