2016-08-21 1 views
0

아래 질문을 보았습니다. 게시 된 답변이 저에게 맞지 않는 것처럼 보입니다. 내 쿼리는 본질적으로 동일하지만 정교하게 다룰 것입니다.Access 2012에서 중복 레코드 방지

나는 다음과 같이 정보의 테이블을 갱신하는 형태가 있습니다

Forename 
Surname 
EmailAddress 

또한 필드의 기본값 설정에서 = 날짜()를 통해 자동으로 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

+0

멀티 컬럼 인덱스가 어떤 의미인지 확신 할 수 없으므로 사용자 친화적 인 프론트 엔드를 깨끗하게 정리하지 않아도됩니까? 사용자에게 표시하지 않겠다는 팝업 경고가 표시됩니까? – Slai

+0

필드를 기본 키로 추가하거나 다중 열 인덱스를 설정하십시오. 중복이 추가 될 때 생성되는 오류 번호를 잡아 내거나, 'DCount'와 같은 것을 수행하여 존재하는 레코드의 수를 결정하고, 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