阻止Access 2013中的重复记录

时间:2016-08-21 19:50:16

标签: vba ms-access duplicates

我看了下面的问题,这正是我想要做的事情,但是发布的答案对我来说似乎不起作用。我的查询基本相同,但我会详细说明。

我有一个表格,用以下内容更新信息表:

Forename
Surname
EmailAddress

数据库还会通过字段的默认值设置中的= Date()自动添加DateEntered,并且有一个名为CPDEAID的主键自动编号。

我将以下代码添加到表单

Private Sub Form_BeforeUpdate(Cancel As Integer)
    Set rst = Me.RecordsetClone
    rst.FindFirst "[CPDEAID] <> " & Me.CPDEAID & " AND [Forename] = " & Me.Forename & " AND [Surname] = " & Me.Surname & " AND [EmailAddress] = " & Me.EmailAddress
    If Not rst.NoMatch Then
        Cancel = True
        If MsgBox("This person already exists; would you like to go to the existing record?", vbYesNo) = vbYes Then
            Me.Undo
            DoCmd.SearchForRecord , , acFirst, "[CPDEAID] = " & rst("CPDEAID")
        End If
    End If
    rst.Close
End Sub

但是,这似乎不起作用。我可以让我的数据库不创建重复记录的唯一方法是通过创建一个多列索引 - 但这有点乱,因为我想要一个干净的“用户友好”前端。

我在这里错过了一些非常简单的事情吗?

Prevent Duplicate Records, Query Before Creating New Records

1 个答案:

答案 0 :(得分:0)

它可能不起作用,因为在rst.FindFirst中您构建了一个比较文本列的SQL字符串,但是您不在参数周围使用单引号。

但是你不应该用用户输入这样做,因为这会冒SQL注入的风险。

相反,使用如here所示的参数查询,或在标准模块中使用这样的实用程序函数:

' DLookupPar: Look up a value with a parameterized query
' The first 3 parameters are identical to DLookup, but in Criteria you can use parameters.
' Then add the exact number of parameters as following arguments, in the exact order as used in <Criteria>
'
' Sample call:
' varUserID = DLookupPar("UserID", "tUsers", "Username = [parUser] AND [Password] = [parPassword]", Me!Username, "aPassword")
'
Public Function DLookupPar(Expr As String, Domain As String, Criteria As String, ParamArray arParams() As Variant) As Variant

    Dim db As DAO.Database
    Dim qd As DAO.QueryDef
    Dim rs As DAO.Recordset
    Dim strSelect As String
    Dim i As Long

    strSelect = "SELECT " & Expr & " FROM " & Domain & " WHERE " & Criteria
    'Debug.Print strSelect

    Set db = CurrentDb
    ' Create temporary querydef (no name) and set all parameters from arParams
    Set qd = db.CreateQueryDef("", strSelect)
    For i = LBound(arParams) To UBound(arParams)
        qd.Parameters(i) = arParams(i)
    Next i

    Set rs = qd.OpenRecordset(dbOpenSnapshot)
    If Not rs.EOF Then
        ' Return the first and only column
        DLookupPar = rs(0)
    Else
        DLookupPar = Null
    End If
    rs.Close

End Function

并在您的表单中使用它:

Dim ID As Long
Dim rs As Recordset

ID = Nz(DLookupPar("CPDEAID", "yourTable", _
    "[CPDEAID] <> [parCPDEAID] AND [Forename] = [parForename] AND [Surname] = [parSurname] AND [EmailAddress] = [parEmailAddress]", _
    Me.CPDEAID, Me.Forename, Me.Surname, Me.EmailAddress), 0)

If ID > 0 Then
    ' MsgBox etc
    Set rs = Me.RecordsetClone
    rs.FindFirst "[CPDEAID] = " & ID
    Me.Bookmark = rs.Bookmark
    rs.Close
End If