如何在执行DELETE查询后更新子表单?

时间:2015-07-15 14:07:14

标签: vba ms-access access-vba

我有一个表单myForm,其中包含一个子表单mySubformmySubform中的记录与myForm的记录来源有多对一关系,正如预期的那样,mySubformmyCombo中有一个组合框,其值为链接到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

2 个答案:

答案 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后端使用dbSeeChangesdb.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有关,在以编程方式删除整个记录之前,保存对不可为空(或可为空,两者都工作正常)列的内容的更改。但究竟如何,我不知道并会欣赏输入。