如何强制更新Access组合框?

时间:2013-08-22 10:06:56

标签: ms-access access-vba ms-access-2010

在编写表单时,是否有一种我忽略的技术?

我有一对级联组合。

  1. ComboSource过滤ComboInformation中可供选择的选项

  2. ComboInformation设置表格中必填字段的内容

  3. ComboSource的rowsource是:

    SELECT tblSource.SourceID, tblSource.Source
    FROM tblSource
    ORDER BY tblSource.Source;
    

    ComboInformation的rowsource是:

    SELECT tblInformation.InformationID, tblInformation.SourceID, tblInformation.InformationSelector
    FROM tblInformation
    WHERE (((tblInformation.SourceID)=[ComboSource])) OR ((([ComboSource]) Is Null))
    ORDER BY tblInformation.InformationSelector;
    

    在ComboSource中选择一个值会导致ComboInformation的.Listcount为零。用户可以选择在ComboInformation中键入新值,并提示在链接到Source表中的ComboSource条目的Information表中创建相关项,或者他们可以选择导航回ComboSource以选择不同的Source。

    当用户编辑现有记录并将ComboSource更改为没有关联信息记录的值时,就会出现问题。在ComboSource的After_Update事件中,我有以下代码,旨在更新ComboInformation以反映新的源并强制用户为ComboInformation选择一个新值(否则他们可以使用旧的Information值保存记录而不会意识到它)。

    Me.ComboInformation.Requery 'Reflect the current source
    
    'Set a default value for ComboInformation
    If Me.ComboInformation.ListCount > 0 Then
         Me.ComboInformation.DefaultValue = Me.InformationTitle.ItemData(0)
    Else
         On Error Resume Next 'Ignore inevitable error
         Me.ComboInformation.DefaultValue = Null
         On Error GoTo PROC_ERR 'restore normal error handling
    End If
    
    'Force the user to update Information by setting content to "" -- if this isn't done, the
    'record can be saved with the 'previous value of Information and the user may not realise 
    'they haven't made any change
    
    ComboInformation.SetFocus
    
    If Not Me.NewRecord Then
         If Me.ComboInformation.ListCount = 0 Then
              'Clear info to force it to be updated
              On Error Resume Next 'Ignore inevitable error
              ComboInformation.Text = "" 'Set it to an invalid value
              ComboInformation= Null
              On Error GoTo PROC_ERR
          Else
              ComboInformation= ComboInformation.DefaultValue 'set it to a valid value
              End If
          End If
    End If
    

    如果用户选择了没有有效信息选择的源,然后选择为Information创建新值,则没问题。但是,如果他们决定导航回ComboSource,他们会收到一条错误消息,坚持要求他们完成ComboInformation,而这是他们无法做到的。他们可以撤消他们为恢复到之前状态所做的更改,但这不是对错误消息的直观响应,告诉他们完成ComboInformation。

    当ComboInformation无效时,是否有办法允许他们导航回ComboSource;或者在保存没有此问题的记录之前,在更新ComboSource后强制他们更新ComboInformation的其他方法是什么?

    有关错误消息的更新:我可以在Form_Error中捕获它,尽管在那里没有生成错误消息 - 堆栈中没有其他过程。错误消息是与信息表中的信息字段关联的消息(验证规则:不是空;验证文本;每个证据都必须来自一条信息)

    进一步更新:我可以处理Form_OnError中的错误(3316),但有时我不想忽略“有效错误”......

    到目前为止尝试的其他事情:

    刷新页面没有帮助。

    演示数据库

    有一个数据库可以在https://s3-eu-west-1.amazonaws.com/genquiry/test.accdb

    上演示问题

    打开数据库中唯一的表单,将Source设置为S3并尝试导航回Source以选择其他值。

3 个答案:

答案 0 :(得分:0)

我认为我的最后一条消息很有意思。不要绑定信息组合,而是在Source字段的AfterUpdate事件中动态设置它的控制源。当在表设计中设置“Is Not Null”验证时,您正试图用NULL强制填充绑定字段。如果你解开它,你应该可以让它工作。

答案 1 :(得分:0)

一种可能性:

如果我在ComboInformation.Listcount = 0时将ComboInformation和ComboInformation.DefaultValue设置为-1而不是Null,则可以避免在用户导航回ComboSource时触发表验证规则(Is Not Null)。但是,它仍然是一个无效值(因为它破坏了表之间的数据完整性),并且阻止用户退出表单或保存记录,直到输入有效值(通过为Source选择不同的值或在表中创建值)信息列表)。

它有效,但它不是一个优雅的解决方案,依赖于-1始终是链接信息表中自动生成的InformationID字段的无效值,我认为这不是一个安全的假设...

但是,如果我稍微修改方法以找到最低的现有InformationID字段(调用此LOWID)然后使用LOWID-1设置ComboInformation,这也有效,并且总是在其使用期间产生无效值

答案 2 :(得分:0)

您是否必须清除更新后的第二个组合框?我写了一个快速测试,它似乎自动清除它。

我认为问题不在于组合框是否被绑定,而是在你可能有项目之前将焦点设置在组合框中,或者知道用户是否想要向其添加项目,这可能是在他们进入之前完成。

Private Sub cboSource.AfterUpdate()
    cboInformation.Requery

    ' if the combobox doesn't refresh to be empty or have a default after the 
    ' requery check the row source for information. 
    ' This way you don't have to focus the second combo box and run into problems
    ' when you leave it
    Dim db as DAO.database
    Dim rs as DAO.recordset

    Set db = CurrentDB()
    Set rs = db.OpenRecordset("SELECT tblInformation.InformationID, 
                     tblInformation.SourceID, tblInformation.InformationSelector
                     FROM tblInformation
                     WHERE (((tblInformation.SourceID)= " & ComboSource.value & "))  
                     OR (((" & ComboSource.value & " ) Is Null))
                     ORDER BY tblInformation.InformationSelector")

    If rs.recordcount <> 0 then
        cboInformation.SetFocus
    Else
        ' Set and empty value for the combobox so they can't accidentally save the
        ' record with an old value.
        ' Prompt them to either select a new value that has records or create a 
        ' new one here
    End If

    rs.close
    db.close
    Set rs = nothing
    Set db = nothing
end Sub