Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access afterupdate在主键中留下空白_Ms Access_Vba_Ms Access 2010 - Fatal编程技术网

Ms access afterupdate在主键中留下空白

Ms access afterupdate在主键中留下空白,ms-access,vba,ms-access-2010,Ms Access,Vba,Ms Access 2010,我正在开发一个access数据库,其中包含一些仅用于数据输入的表单。问题是,当我打开这些表单时,access会在基础表中创建一个新条目,包括增加基础表的自动编号主键,并且即使用户选择不在数据库中创建记录,自动编号也会保持增加。这意味着,由于用户总是在不提交更改的情况下打开和关闭表单,因此实际表中的自动编号序列中存在间隙 我在beforeupdate方法中使用以下代码允许用户丢弃错误数据: Private Sub Form_BeforeUpdate(Cancel As Integer) '

我正在开发一个access数据库,其中包含一些仅用于数据输入的表单。问题是,当我打开这些表单时,access会在基础表中创建一个新条目,包括增加基础表的自动编号主键,并且即使用户选择不在数据库中创建记录,自动编号也会保持增加。这意味着,由于用户总是在不提交更改的情况下打开和关闭表单,因此实际表中的自动编号序列中存在间隙

我在beforeupdate方法中使用以下代码允许用户丢弃错误数据:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    'Provide the user with the option to save/undo
    'changes made to the record in the form
    If MsgBox("Data has been entered into this form." _
        & vbCrLf & vbCrLf & "Do you want to save this data?" _
        , vbYesNo, "Changes Made...") = vbYes Then
            DoCmd.Save
    Else
        DoCmd.RunCommand acCmdUndo
    End If
End Sub  
我本想使用beforeinsert事件,但在使用beforeinsert时打开表单时遇到问题


有人能告诉我如何设置,使这些间隙不会在自动编号值序列中产生吗?此数据库将由10个并发用户使用。

您不应为“自动编号”字段的值分配任何意义。自动编号允许您为每一行定义唯一的值,这样做并不保证它们是连续的。我建议您只使用“自动编号”字段来标识唯一记录,而不是作为某种计数器或人类可读值

现在,如果你需要每条记录都有一个连续的值,那么你需要做的就是

  • 创建一个单独的表,该表只有一行,一列包含序列中的下一个值
  • 无论何时从数据输入表单保存记录,都会以独占方式锁定该计数器表,防止任何其他用户读取或写入该表
  • 从计数器表中检索当前值,并在新的数据条目记录中使用该值
  • 更新计数器表中的值以增加到下一个值
  • Microsoft提供了一个函数,可以方便地以独占方式锁定表:
    DAOOpenTableExclusive()
    ,可以找到该函数


    可以使用找到的代码创建计数器表

    如果您有表单集的记录源,则任何绑定控件的条目都将导致填充any
    AutoNumber
    字段。如果用户放弃或未输入所有必需的信息,则跳过该自动编号

    为了避免这种情况,您可以自己保存记录。假设定义了下表:

    并创建以下表单:

    隐藏以下代码:

    Private Sub cmdClose_Click()
      DoCmd.Close
    End Sub
    
    
    Private Sub cmdSave_Click()
      DoCmd.SetWarnings False
      DoCmd.RunSQL "INSERT INTO z_TestTable (DueDate, " & _
                                            "DateReceived, " & _
                                            "Terms, " & _
                                            "ECOFee, " & _
                                            "Classification) " & _
                                   "VALUES (#" & txtDueDate & "#, " & _
                                           "#" & txtDateReceived & "#, " & _
                                           "'" & txtTerms & "', " & _
                                           txtECOFee & ", " & _
                                           "'" & txtClassification & "')"
      MsgBox ("RECORD SAVED")
    End Sub
    
    Private Sub txtClassification_AfterUpdate()
      funCheckForRequiredFields
    End Sub
    
    
    Private Sub txtDateReceived_AfterUpdate()
      funCheckForRequiredFields
    End Sub
    
    
    Private Sub txtDueDate_AfterUpdate()
      funCheckForRequiredFields
    End Sub
    
    
    Private Sub txtECOFee_AfterUpdate()
      funCheckForRequiredFields
    End Sub
    
    
    Private Sub txtTerms_AfterUpdate()
      funCheckForRequiredFields
    End Sub
    
    
    Function funCheckForRequiredFields()
      Dim NotComplete As Boolean
      NotComplete = False
    
      If (IsNull(txtDueDate)) Then NotComplete = True
      If (IsNull(txtDateReceived)) Then NotComplete = True
      If (IsNull(txtECOFee)) Then NotComplete = True
      If (IsNull(txtClassification)) Then NotComplete = True
      If (IsNull(txtTerms)) Then NotComplete = True
    
      If (NotComplete) Then _
        cmdSave.Enabled = False Else _
        cmdSave.Enabled = True
    End Function
    
    表单打开时,保存记录按钮被禁用。只有在输入所有字段后,才会启用保存记录按钮。按下保存记录时,通过
    DoCmd.RunSQL
    命令保存记录

    我将表单上控件的格式设置为与所需的数据相对应。这可确保检查输入的数据的有效性


    通过使用此方法,只有在INSERT SQL无效的情况下,才会使用自动编号字段,并且不会对其保存记录。这是不应该发生的,因为它是预先检查的。

    您可以使用max函数从表中的列中确定最大值,并在保存前添加一个值

    编辑:
    要在多用户环境中执行此操作,请将字段“索引”设置为“是”(无重复)。

    您不必使用未绑定表单来获取OP要查找的内容。是的,这是解决问题的一种方法,但我认为这是最后的选择,而不是第一个选择。Constablebrew的帖子以更好的方式解决了这个问题。不要担心自动编号中的空白,如果您确实关心它,就不要使用自动编号。如果同时打开多个用户或可能多个记录,则可能会出现重复。这将是您回答中的一个重要疏忽。这两者是相辅相成的。再加上你的答案,我认为你的答案是最简单的解决方案。还应该提到,必须捕获抛出的错误(这是什么错误?)并循环,直到保存成功。