【问题标题】:MS Access sub-subform data entryMS Access 子表单数据输入
【发布时间】:2014-12-02 19:52:09
【问题描述】:

我正在构建一个通信/任务记录系统,用于记录传入的通信并根据它们分配任务。

我的数据库有一个笔记系统,这样用户就可以对各种各样的事情做笔记——例如。客户记录可能有一条注释,上面写着“该客户总是订购自己的窗框玻璃”。这一切都是通过一个“Notes”表处理的,该表有一个PrimaryNoteTableID,它链接到一个静态查找表,该表标识了注释适用的主表,还有一个PrimaryTablePK字段,用于存储该记录的PK它适用的表。

为了避免损坏,建议将备注字段保留在自己的表中,并与其父表 (see here) 保持 1:1 的关系,这就是我所做的。

当添加新的通信和任务时,用户通常会想要添加以下内容:

  • 通讯对象的详细信息。
  • 通信的主题。
  • 所需操作的类型和该操作的截止日期。
  • 附有已讨论内容等详细信息的注释。

考虑到这一点,我有:

tblCommTaskLog 带有字段CommDateActionRequiredTypeID(FK)ActionDeadlineDaysCommAccountID(FK)

tblNote 与:NoteID(PK)PrimaryNoteTableID(FK)PrimaryTablePK(FK)EnteredByUserID(FK)EntryDate

tblNoteTextNoteTextID(PK)NoteID(FK)NoteText(Memo)

其中一些是其他表的外键,应该是不言自明的。

基本上我遇到的问题是这三个表格的输入表格。我发现子表单的 Access 处理可能非常愚蠢,例如:

  • 如果您想使用子表单或子表单的子表单,您会被锁定以某种方式显示内容。
  • Access 会在您单击保存之前保存记录。它还将记录保存在子表单中,这些记录无法通过表单代码中的简单“me.undo”处理,导致您必须在子表单中找到记录并使用代码将其删除。
  • 子表单以愚蠢的方式行事,因为它们分配自动编号 PK 并在子表单和主表单之间的链接中选择这些。

我只想在一个表单上包含来自 tblCommTaskLogNoteText 字段的字段,以便用户填写来自 tblCommTaskLog 的详细信息(ActionRequired 等)和注释文本,点击“保存”按钮,然后通过代码正确保存项目,例如:

  • tblCommTaskLog 中创建了一条新记录,例如72 的 PK(自动编号)。
  • tblNote 中创建了一条新记录,其中PrimaryNoteTableID 对应于4,对应于tblCommTaskLogPrimaryTablePK 对应72 和PK NoteID,例如422(自动编号)。
  • tblNoteText 中创建了一条新记录,其中NoteID 为422。

我认为我需要一个主表单,其中包含来自tblCommTask 的字段和一个未绑定的文本字段来获取NoteText 的输入。我只是不知道如何在 tblNote 中创建新记录,从该字段中获取 AutonumberPK 并将其插入到 tblNoteText 的 FK 中,以便所有内容都与正确的 FK 正确链接在一起。我可以使用 SQL INSERT 然后在 Autonumber 字段上使用 SELECT TOP 来执行此操作吗?使用 Recordsets 和 Lastmodified 这样做会更好吗?还有其他我没有想到的方法吗?

【问题讨论】:

  • 你有多少个主表?为什么不为每个 [customers, users, xxx, asdb] 使用注释表,这样您就可以强制执行简单的 1:m 关系??
  • 目前有 11 个表需要存储关于它们的注释。我确定这是做事的最佳方式here
  • 我不将便笺(备忘录类型)存储在自己的表中,并且多年来没有遭受数据库损坏的困扰。还有其他更重要的事情,例如拆分 FE / BE。

标签: sql database forms vba ms-access


【解决方案1】:

@whatEvil:

您仍然可以将其设为 1:M。如果允许您更改主表,请更改它们并添加

  1. 新列 pk_guid:字符串 (38)。 (如果不使用 {},也可以是 36)
  2. 添加插入前触发器以自动为每条新记录添加 GUID。
  3. 类似于:对于插入前的每一行设置 pk_guid = get_uuid()

在你的 tbl_note 中只有

  1. Note_id : pk
  2. origin_guid : string(38) fK
  3. 注意事项:
  4. add_by
  5. .....

现在您可以简单地强制执行 1:M 关系。 GUID 是“全球唯一标识符”。您的所有主表都会生成一个唯一键,您可以在任何阶段简单地加入它们,而无需考虑它属于哪个表或如何保存父表名称。

当然,您需要一个自定义函数来获取 GUID:使用此代码创建一个

Public Function GET_UUID() As String
    With CreateObject("Scriptlet.TypeLib")
        GET_UUID = VBA.Left(.GUID, 38)
    End With
End Function

编辑: 这个想法是在每个主表(GUID/UUID)中都有一个全局唯一 ID。然后它将用于加入您的主表和注释表。注意:您需要向每个主表添加触发器(在插入之前)以生成 GUID。另请注意,MS 访问将其称为 DataMacro(检查您的版本是否支持 datamacro) 更多关于 datamacro 的信息:https://support.office.com/en-ca/article/Create-a-data-macro-b1b94bca-4f17-47ad-a66d-f296ef834200?ui=en-US&rs=en-CA&ad=CA

为什么会这样? 当前您的主表正在生成自动编号,一个或多个表可能具有相同的 ID 号。毕竟,自动编号仅在整个表中是唯一的,而不是在整个数据库中。为了避免重复,您正在添加另一个键(表标识键)来标识外键属于哪个主表。这听起来不错,除非您对主表进行了一次错误的更新,并且注释 ID 的值错误。

通过使用 GUID,无论有多少主表参与,您都可以简单地维护 1:m 关系。此外,如果您的应用程序增长并需要整个数据库中真正的唯一 ID,我个人也喜欢使用 GUID 的想法。这完全取决于你想走哪条路,我只是解释了一种方法..

【讨论】:

  • 这不是让我的整个数据库不必要地复杂化了吗?如果我这样做,我将不得不在我的每一个表单中处理 BeforeUpdate 事件,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多