afterupdate leaves gaps in primary key

喜你入骨 提交于 2019-12-06 10:35:42
Constablebrew

You should not be assigning any significance to the autonumber field's value. Autonumbers allow you to define unique values for each row, and in doing so they are not guaranteed to be sequential. I strongly suggest you only use the autonumber field to identify unique records, not as some sort of counter or human-readable value.

Now, with that out of the way, if you need each record to really have a sequential value, then what you need to do is

  1. Create a separate table that has just one row, one column that holds the next value in the sequence.
  2. Whenever a record is saved from the data entry form, you exclusively lock that counter table, preventing any other users from reading or writing to it.
  3. Retrieve the current value from the counter table and use that in your new dataentry record.
  4. Update the value in the counter table to increment to the next value.

Microsoft provides a function that makes it easy to exclusively lock a table: DAOOpenTableExclusive(), which can be found here.

You can use the code found here to create a counter table.

If you have the Record Source for a form set, the entry of any bound control will cause the any AutoNumber field to be populated. If the user abandons or doesn't enter all the required information, then that auto number is skipped.

To avoid this you could do the saving of the record yourself. Lets say you have the following table defined:

And the following form created:

With the following code behind:

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

The form opens with the Save Record button disabled. The Save Record button is only enabled after all fields are entered. When the Save Record is pressed the record is saved via the DoCmd.RunSQL command.

I set the format of the controls on the form to correspond with the data required. This insures that the data entered is checked for validity.

By using this method the only way that an AutoNumber field will be used and not have had a record saved against it is if the INSERT SQL is invalid. Which should never happen since it is being checked beforehand.

You can use the max function to determine the maximum value from the column in the table and just add one just before saving it.

EDIT: To let this work in a multiuser environment, set the fields 'Indexed to' Yes (No Duplicates).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!