Avatar billede bbkdk Seniormester
23. september 2014 - 11:23 Der er 13 kommentarer og
2 løsninger

Meddelelsesboks ved dublerede værdier

Jeg har en tabel "Tblsystem", hvor der er en sammensat nøgle, bestående af felterne "Identifikation" og "System".
Når jeg forsøger at oprette en post, der vil give en dubleret værdi i den sammensatte nøgle, får jeg den sædvanlige fejltekst.
For at komme videre, er det nødvendigt at lukke ned med de sædvanlige lidt kryptiske tekster til følge.

Det er svært for brugerne at forstå, hvad de skal gøre.

Men hvordan skal den VBA se ud, der ved udgang af feltet "System" tester, om der allerede er en post, der indeholder den samme sammensatte nøgle, skriver en medelelsesboks med en forståelig tekst hvis det er tilfældet, og derefter giver brugeren mulighed for at komme videre.

Det er vist noget med DCount og Me.undo, men hvorledes skal hele VBA'en lige se ud?
Avatar billede fdata Forsker
23. september 2014 - 13:51 #1
I feltets FørOpdatering hændelse lægger du noget i retning af:

Iif Not IsNull(DLookUp("ID","Tblsystem","Identifikation=" & Me.IDentifikation & " AND System=" & Me.System)) Then
  Msgbox "Posten findes allerede"
  Cancel=True
EndIf

(ikke testet)
Avatar billede bbkdk Seniormester
23. september 2014 - 15:13 #2
Det virker ikke helt, selvom jeg godt kan se meningen med formlen.

Jeg har forsøgt denne afart, hvor der er flyttet lidt på lighedstegnene m.v.:

If Not IsNull(DLookup("SystemID", "Tblsystem", "Identifikation" = Me.Identifikation And "System" = Me.System)) Then
  MsgBox "Posten findes allerede"
  Cancel = True

Men ved udgang fra feltet sker der intet. Først når posten forlades, kommer den sædvanlige meddelelse om, at der er dublerede poster.
Avatar billede fdata Forsker
23. september 2014 - 16:46 #3
Ooops. Den går ikke. Lighedstegnene skal indenfor anførselstegnene. Når Access afkoder udtrykket, bliver det f.eks.:
"HVOR Identifikation=" ... og så værdien af Identifikation.

Jeg glemte:
Hvis Identifikation og/eller System skal du lige huske ' omkring værdierne. Altså:
Iif Not IsNull(DLookUp("ID","Tblsystem","Identifikation='" & Me.IDentifikation & "' AND System='" & Me.System & "'")) Then ...
Avatar billede terry Ekspert
23. september 2014 - 18:24 #4
Use the forms Error event

Private Sub Form_Error(DataErr As Integer, Response As Integer)
    Const conDuplicateKey = 3022
    Dim strMsg As String

    If DataErr = conDuplicateKey Then
        Response = acDataErrContinue
        strMsg = "Duplicate Key ...."
        MsgBox strMsg
    End If
   
End Sub
Avatar billede fdata Forsker
23. september 2014 - 22:51 #5
>>Terry
Hm. Virker det?
Fejlmeddelelsen skal komme allerede ved indtastningen i feltet og ikke når posten forsøges opdateret.
Avatar billede terry Ekspert
24. september 2014 - 09:09 #6
Depends what you mean by "virker det"

If the check MUST be made after leaving the system field then it will only work if that field is the last and an attempt to write the record to the table occurs.

On the other hand, if we want to inform the user that a duplicate key was entered and let the user alter that.

"Det er svært for brugerne at forstå, hvad de skal gøre."

Then this works just fine, quite easy to alter message and set focus on one of the key fields.

Checking just the System field isnt a good idea, you know as well as I do that at some stage the user will enter system first and then Identifikation, then the error will occur again.
Avatar billede bbkdk Seniormester
24. september 2014 - 10:24 #7
Tak for svar til jer begge to.

Jeg skal lige understrege, at System-formularen er en underformular, hvor der er en sammenst nøgle, nemlig af posterne "Identifikation" og "System".

Jeg er totalt mystificeret.

Når jeg anvender fdatas løsningsforslag, får jeg en fejltekst, når der oprettes en dubleret post - Return without GoSub. Men hvis jeg starter med et gå ind i designvisning, og derfra åbne VBA-editoren og, uden at ændre noget, derefter går ind i formularvisning, og forsøger at oprette en dubleret post, virker det perfekt.
Der bliver ikke oprettet en post, og markøren stiller sig i feltet "System".
Så kan man vælge at gå til en anden oprettet post, eller at oprette en korrekt System-post.
Jeg har ændret "Cancel=True" til "Me.Undo".
Når jeg så går ud af systemet og direkte ind i formularvisning, kommer fejlteksten "Return without GoSub" igen.

Så Terry - det perfekte ved fdatas forslag er, at den giver mulighed for at forlade posten uden videre (når det altså virker).

Så vidt jeg kan se, giver dit forslag en perfekt fejlmeddelse, men så eksisterer problemet med at forlade den fejlagtigt oprettede post stadig.

Det er så 2 muligheder - Enten af ændre feltet "System" til en ikke anvendt indtastning, eller at lukke systemet på den hårde måde, dvs. ved ikke at gemme posten.

Så skal dit forslag ikke kombineres med en videre udbygning, således at man undgår den næste fejlmeddelelse, hvis brugeren så ikke vil oprette en post - "En primær nøgle kan ikke indeholde en Null Værdi"
Avatar billede terry Ekspert
24. september 2014 - 11:03 #8
Så vidt jeg kan se, giver dit forslag en perfekt fejlmeddelse, men så eksisterer problemet med at forlade den fejlagtigt oprettede post stadig.

Not sure what you mean.
Why do you want to leave the record if there is an error?

Are you saying you don't want to continue creating the record?

Press ESC on return
Avatar billede terry Ekspert
24. september 2014 - 11:07 #9
If you want to give the user the opportunity to undo (remove) record then


Private Sub Form_Error(DataErr As Integer, Response As Integer)
    Const conDuplicateKey = 3022
    Dim strMsg As String

    If DataErr = conDuplicateKey Then
        Response = acDataErrContinue
        strMsg = "Duplicate Key ....Undo record?"
       
       
        If MsgBox(strMsg, vbYesNo) = vbYes Then Me.Undo
       
    End If
   
   
End Sub
Avatar billede bbkdk Seniormester
24. september 2014 - 11:55 #10
Hej Terry

Det virker perfekt - men hvad er årsagen til, at den ikke allerede tester, når der skrives en dubleret værdi i feltet System?

Men dit forslag giver så til gengæld brugeren mulighed for at vælge Nej, hvorefter der kan vælges et andet system, uden at slette de indtastede tal.

Jeg venter lige med at give points, til fdata eventuelt er vendt tilbage.
Avatar billede terry Ekspert
24. september 2014 - 12:17 #11
Until the record gets written to the table then there is no duplicate key. You are allowed to change any of the fields, also both of the fields in the primary key, and until you try and write it into the table then it doesn't exist.
Avatar billede fdata Forsker
24. september 2014 - 21:55 #12
Så er jeg tilbage.

Det lækre ved mit forslag er netop at dublettjekket sker allerede ved indtastningen i de to felter.
... og ja, tjekket skal naturligvis ligge i begge felter:

Private Sub Identifikation_BeforeUpdate(Cancel As Integer)
  If Not IsNull(DLookup("ID", "Tblsystem", "Identifikation='" & Me.Identifikation & "' AND System='" & Me.System & "'")) Then
    MsgBox "Dublet"
    Cancel = True
  End If
End Sub

Private Sub System_BeforeUpdate(Cancel As Integer)
  If Not IsNull(DLookup("ID", "Tblsystem", "Identifikation='" & Me.Identifikation & "' AND System='" & Me.System & "'")) Then
    MsgBox "Dublet"
    Cancel = True
  End If
End Sub
Avatar billede bbkdk Seniormester
25. september 2014 - 08:25 #13
Hej Begge

Nu virker begge forslag perfekte.

fdata - I dit forslag skal feltet "identifikation" trækkes ind i underformularen (og eventuelt skjules), ellers virker det ikke. Og jeg erstatter stadig Cancel=True med Me.Undo, men det er måske en smagssag.

Så jeg kan vælge begge løsninger og har derfor fordelt points ligeligt.

Og så en rigtig god ting ved det jeg har lært - alle der arbejder med Access har vel på et tidspunkt forsøgt at oprette dublerede poster og det giver virkeligt meget besvær hver gang, med mystiske fejltekster og hvad ved jeg.

Så jeres hjælp i dette spørgsmål vil helt sikker bevirke, at jeg vil anvende jeres løsninger rigtigt meget.
Avatar billede terry Ekspert
25. september 2014 - 08:43 #14
Great you found a solution and at the same time learnt something.

and thansk for the points
Avatar billede fdata Forsker
25. september 2014 - 15:09 #15
Bare for at runde pænt af:
  Cancel=True fortryder kun indtastning i det aktuelle felt.
  Me.Undo fortryder alle indtastninger i posten.
Du ved bedst, hvilken hændelse der giver mest mening i dit tilfælde.

Takker for point ;O)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester