0

编码表单时是否有我忽略的技术?

我有一对级联组合。

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

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

ComboSource 的行源是:

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

ComboInformation 的行源是:

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 中键入新值并提示在信息表中创建与源表中的 ComboSource 条目链接的相关项,或者他们可以选择导航回 ComboSource 以选择不同的源。

当用户编辑现有记录并将 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 以选择不同的值。

4

3 回答 3

0

我想我的最后一条消息有点击中它。与其绑定 Information 组合,不如在 Source 字段的 AfterUpdate 事件中动态设置它的 Control Source。当表设计中设置了“非空”验证时,您正试图用 NULL 强制填充绑定字段。如果你解绑它,你应该能够让它工作。

于 2013-08-23T12:57:51.357 回答
0

一种可能:

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

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

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

于 2013-08-23T16:34:36.813 回答
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
于 2013-08-23T19:43:25.553 回答