【问题标题】:Help with Access 2007 validation for a field in a subform based on a query基于查询的子表单中的字段的 Access 2007 验证帮助
【发布时间】:2011-07-12 22:57:21
【问题描述】:

我有一个子表单,它是较大表单的一部分,其中两者都包含 PROJECT_ID 字段。在主窗体中,PROJECT_ID 字段是一个键。在子表单中,用户可以选择为项目分配新代表或更改子表单中的当前项目代表。一个项目可以有多个代表,但是只有一个可以是活动的主要代表。我的问题是我在编写主要标志字段 (ADV_FLAG) 的验证时遇到问题,因为它本质上是基于查询的。谈到 VBA,我有点新手,但我认为这可能是解决我的问题的最佳解决方案。有关如何解决此问题的任何建议或类似代码示例。以下是我目前在 sub_form 的 BeforeUpdate 事件过程中拥有的内容。

Private Sub Form_BeforeUpdate(取消为整数)

'验证项目中的多个活动主节点

‘追加到表 T_Error_Catch 的 project_ID 和一个错误标志为 YES '其中一个项目有多个活动的主节点。

DoCmd.SetWarnings False
DoCmd.OpenQuery "Q_Append_Errors_MultiplePrimaries", acViewNormal, acEdit

'向用户抛出一个对话框错误,表明该项目已经有一个活动的主节点

If ERR_FLAG = "Yes" And ADV_FLAG.Value <> "Secondary" Then

   MsgBox "Project already has an Active Primary.", vbExclamation
   ADV_FLAG.SetFocus
   Cancel = True

End If

‘一旦记录被更正,就截断 T_Error_Catch 表,并且再次只有一个活动的主表

If ERR_FLAG = "Yes" And ADV_FLAG.Value = "Secondary" Then

   DoCmd.SetWarnings False
   DoCmd.OpenQuery "Clear T_Error_Catch", acViewNormal, acEdit

End If

结束子

【问题讨论】:

    标签: ms-access


    【解决方案1】:

    您正在使用更新前的表单来验证现有记录中的 ADV_FLAG 值。我认为您还需要处理新记录...以防止用户添加新代表作为已分配主要代表的 PROJECT_ID 的主要代表。您可以在插入之前为表单添加一个过程来处理它。

    但是,与其等到用户完成所有字段后再验证 ADV_FLAG,不如在 ADV_FLAG 控件的更新后事件中进行验证。更新后过程将同时处理记录更新和插入。

    但也许更容易实现的是子窗体上的命令按钮,它使当前代表成为当前 PROJECT_ID 的唯一主要对象。按钮的点击事件可以使用如下代码:

        Dim strSql As String
        Dim db As DAO.Database
    
    On Error GoTo ErrorHandler
    
        strSql = "UPDATE YourTable SET ADV_FLAG = 'Secondary' WHERE PROJECT_ID = " & _
            Me.txtPROJECT_ID & ";"
        Debug.Print strSql
        Set db = CurrentDb
        db.Execute strSql, dbFailOnError
        Me.txtADV_FLAG = "Primary"
    
    ExitHere:
        On Error GoTo 0
        Debug.Print "RecordsAffected: " & db.RecordsAffected
        Set db = Nothing
        Exit Sub
    
    ErrorHandler:
        'your error handler code here '
    

    我假设您的子表单有一个名为 txtPROJECT_ID 的文本框控件绑定到 PROJECT_ID 字段,另一个名为 txtADV_FLG 绑定到 ADV_FLAG 字段。根据需要更改这些名称以匹配您的数据控件。

    使用这种方法,用户实际上不需要直接编辑 txtADV_FLG 中的值(因为命令按钮会进行所需的任何更改)。因此,在 txtADV_FLG 的属性表中,您可以设置 Enabled = No,也可以设置 Locked = Yes。

    Debug.Print 行用于帮助您解决问题。他们会将信息打印到即时窗口。 (您可以使用 Ctrl+g 键盘快捷键转到即时窗口。)在您正确运行代码后,您可以禁用或删除 Debug.Print 语句。或者让它们保持原样......您不会受到任何重大的性能影响。

    请注意,我使用了db.Execute strSql, dbFailOnError 而不是DoCmd.SetWarnings FalseDoCmd.OpenQuery。我从不设置警告关闭。如果你这样做了,你必须记得之后再次打开 SetWarnings。您的代码不包含DoCmd.SetWarnings True。因此,如果不启用 SetWarnings,您可能会隐藏重要信息。不要那样做!

    【讨论】:

    • 非常感谢!!这非常有效,感谢您对 SetWarnings 的建议。以后绝对不会这样做了。非常感谢!
    【解决方案2】:

    试图遵循@HansUp 的解决方案,我的眼睛呆滞,我确信这是正确的。相反,我将提供一个使用模式设计来避免以代码方式编写大量代码的答案。

    我不得不多次这样做——您有一个 N:1 表,但您希望将其中一条记录指定为 PRIMARY。

    首先,您设置 N:1 表。

    然后,您将一个字段添加到主表(1 侧),并将记录的 PK 值存储在您想要作为主记录的 N 表中。

    例如,假设您有 tblInventory 和 tblImage,它们有一个 ImageID PK 和一个 InventoryID FK。

    要将其中一个设置为主图像,您需要将 MainImageID 字段添加到 tblInventory,并使用组合框对其进行编辑,该组合框列出了 tblImage 中与 tblImage 中的该 InventoryID 连接的图像。当然,您必须重新查询 Inventory 表单的 OnCurrent 事件中的组合框。

    这里有一个示例 UI:

    在该实现中,图像列表有一个用于 TOP 的复选框,但它不可编辑(这是一个糟糕的 UI,因为从外观上看不清楚它不能在那里更改),但用户认为它相当迅速地。当然没有必要在那里显示检查,或者使用相同的控件来指示 TOP 项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 1970-01-01
      • 2011-12-31
      相关资源
      最近更新 更多