delete-probleem

Status
Niet open voor verdere reacties.

so10070

Gebruiker
Lid geworden
4 feb 2014
Berichten
419
Twee tabellen A en B in relatie (1 op veel) met elkaar. Worden op één formulier getoond. Wanneer de gebruiker het scherm wil sluiten (de handeling stopzetten zonder te bewaren) zijn er drie mogelijkheden.
1. de gebruiker heeft nog niets ingevuld
2. de gebruiker heeft enkel in het deel "parent" gegevens ingevuld
3. de gebruiker heeft eveneens in het deel "child" gegevens ingevuld
Ik probeer deze handelingen te beheersen met de commando's "Me.Recordset.Delete" en "DoCmd.RunCommand acCmdDeleteRecord". Maar aangezien hier ook een subformulier gekoppeld is, loopt het nogal chaotisch en werkt mijn oplossing niet. Als ik het formulier sluit met de eigenschap "acSaveNo" blijkt het record toch in de tabel bewaard te zijn. "Me.Recordset.Delete" geeft een fout "Geen record gevonden", hoewel het record wel bewaard is. Ik kan dan via het commando "DoCmd.RunCommand acCmdDeleteRecord" dit record wel verwijderen. Access geeft dan zelfs eerst een waarschuwing. Dus het record is aangemaakt. Waarom wordt het dan niet verwijderd met het commando "Me.Recordset.Delete"? Ik begrijp het hier niet goed. Hieronder mijn klungelachtige code. :(

Code:
Private Sub cmbAnnuleer_Click()
    On Error GoTo foutafhandeling
    
    Me.Recordset.Delete
    Me.SFsubfrmNieuwAccount.Form.Recordset.Delete

    DoCmd.Close acForm, "frmNieuwAccount", acSaveNo
    Exit Sub

GeenRecordGevonden:
    DoCmd.RunCommand acCmdDeleteRecord
    DoCmd.Close acForm, "frmNieuwAccount", acSaveNo
    Exit Sub
    
foutafhandeling:
    If Err.Number = 3021 Then
        Resume GeenRecordGevonden
    Else
        DoCmd.Close acForm, "frmNieuwAccount", acSaveNo
    End If
End Sub
 
Als ik het formulier sluit met de eigenschap "acSaveNo" blijkt het record toch in de tabel bewaard te zijn.
Je bent niet de eerste, zeker niet de enige en met grote zekerheid absoluut niet de laatste die niet snapt wat acSaveNo (en acSaveYes) doet. Bij deze: die commando's gebruik je als je met VBA een formulier opent in de bewerkingsmodus, iets aanpast (plek van een label bijvoorbeeld) en het formulier daarna sluit. Het commando heeft dus helemaal niets te maken met het al dan niet bewaren van een record als je het formulier opent in Formulierweergave. Mijn tip: gebruik die opties dus niet, want a) doen ze niks, en b) zet je jezelf op het verkeerde spoor.
En Me.Recordset.Delete? Wat denk je dat dat doet? Een recordset is de complete tabel.... Die wil je dus echt niet verwijderen!

Als je overigens in de relatie de optie <Gerelateerde records trapsgewijs verwijderen> aanzet, is het voldoende om het hoofdrecord te verwijderen.
 
Laatst bewerkt:
Als ik de optie <Gerelateerde records trapsgewijs verwijderen> lost dit niet veel op aangezien er trapsgewijs nog andere tabellen verbonden zijn. Ik heb gemerkt dat er altijd een record aangemaakt wordt, ofschoon de melding "er is geen record dat gewist kan worden" met de opdracht <Docmd.Runcommand acCmdDeleteRecord> of met de opdracht <Me.Recordset.Delete> verschijnt. Als de cursor in het subformulier staat is het record in het parent-groep blijkbaar aangemaakt en te wissen, maar is het record in het subformulier niet te wissen, maar toch aangemaakt. Dat begrijp ik niet! Ook begrijp ik het verschil niet tussen de twee commando's: <Dcmd.RunCommand acCmdDeleteRecord> en <Me.Recordset.Delete>. De tweede zou ook alle records in de databank wissen, maar dat doet ze niet. Deze opdracht vraagt soms om 1 record te wissen. Het is en beetje fuzzy voor mij op dit moment.
 
Als ik de optie <Gerelateerde records trapsgewijs verwijderen> lost dit niet veel op aangezien er trapsgewijs nog andere tabellen verbonden zijn.
Dan moet je de verwijderoptie in die tabellen ook aan zetten. Overigens mág je helemaal geen records verwijderen uit een tabel die in een keten zit; je zou dan die keten verbreken. Dat is nu net de hele essentie van Relaties! Voorkomen dat noodzakelijke records verdwijnen :).

Als de cursor in het subformulier staat is het record in het parent-groep blijkbaar aangemaakt en te wissen, maar is het record in het subformulier niet te wissen, maar toch aangemaakt.
Als een subformulier correct is gekoppeld aan het hoofdformulier (Sub- en Hoofdveld zijn gekoppeld) dan maakt Access automatisch op basis van het record in het hoofdformulier een record aan in het subformulier, dat klopt. Als er onder het subformulier waarin je een nieuw record maakt ook gekoppelde tabellen hangen, dan is het (bij een nieuw record) onmogelik dat daar al data in staat. Het verwijderen van het hoofdrecord (inclusief het subrecord) zou dus geen enkele invloed mogen hebben op de records die onder de subtabel hangen. Vandaar ook mijn eerdere tip om ook de gekoppelde tabellen op dezelfde manier te gebruiken.
Maar ik vermoed dat je zo'n ingewikkelde constructie hebt bedacht dat een antwoord alleen op basis van je vraag niet gaat lukken. Ergo: we hebben een db nodig...
 
En die heb je hier neergezet. Ongebruikelijk, maar niet onoverkomelijk ;)
 
Ik snap de link niet helemaal tussen het inlogformulier en de tabel [tblWerkgroepCGS]. Ik zie dat er wel een koppelveld is ([GebruikerID]) maar wat doe je met het formulier?
 
Voor elke medewerker die zich voor de eerste keer aanmeldt, worden zijn of haar personalia in de tabel [tblWerkgroepCGS] weggeschreven. Het is de bedoeling dat er op de tabel [tblWerkgroepCGS] een filter gezet wordt zodat elke medewerker enkel de voor hem ingevoerde gegevens kan invoeren, bekijken en wijzigen. Door dit zo te doen kan de medewerker na zich aangemeld te hebben direct inloggen. De "Beheerder data" heeft toegang tot alle records van de tabel [tblWerkgroepCGS].
 
Maar dat verklaart nog steeds niet waarom je 2 tabellen hebt voor in essentie dezelfde zaken... Alles wat je nu opnoemt kan namelijk zonder 1 probleem in één tabel. Dus waarom 2?
 
Dat zou in principe kunnen, maar er zijn nu twee soorten (op administrator na) gebruikers die met deze gegevens aan de slag gaan, nl. medewerkers en beheerders. Medewerkers kunnen enkel de door henzelf ingevoerde gegevens bijwerken en bekijken. De beheerders, daarentegen, kunnen enkel de records bekijken en op vraag van de medewerkers wijzigen. Als er enkel met de medewerkers gewerkt zou worden, zou alles in één tabel gevat kunnen worden. Maar aangezien er drie (met administrator bij) soorten gebruikers zijn, waarvan twee soorten (medewerkers en beheerders) het pakket intensief gaan gebruiken en hun relatie tot de tabel [tblWerkgroepCGS] anders is (records aanmaken/wijzigen/bekijken (medewerkers) en geen records aanmaken (beheerders)), is het best deze gegevens te splitsen over twee tabellen, zo dacht ik toch ....?
 
Dat zie je toch verkeerd (vind ik). Gegevens sla je op in tabellen op basis van hun entiteit. Oftwel: wat is het? En een persoon is, in welke hoedanigheid dan ook, een persoon. Dus is dat 1 tabel. Dat je verschillende personen verschillende rechten geeft is logisch, maar dat doe je dan ook. Gebruikers (en zelfs niet beheerders) horen niet in tabellen te grutten, dus voor de UI gebruik je formulieren. En die kun je perfect inrichten voor elke groep gebruikers. Ik zou dan, als gebruikers bepaalde velden niet mogen zien en beheerders wel, die op een apart tabblad zetten. Je kunt, kortom, alles afschermen op de manier zoals je het hebben wilt. En toch alles (veel beter beheersbaar) in één tabel opslaan.
 
Je hebt gelijk, verdere normalisatie leidt tot één tabel voor alle gebruikers, onafhankelijk van de toegangsrechten. Heb mijn applicatie in die zin ook aangepast. De "Annuleer"-knop werkt nu prima met het commando: DoCmd.RunCommand acCmdDeleteRecord. Ik doe dit nu als volgt:
1. Het formulier "frmNieuwAccount" open ik met het commando "DoCmd.OpenForm "frmNieuwAccount", , , , acFormAdd, acDialog"
2. Om te voorkomen dat de gebruiker nieuwe records kan blijven aanmaken, plaats ik het commando ".AllowAdditions = False" in de gebeurtenis "Bij laden" van het formulier "frmNieuwAccount"
3. Om de foutmelding "Kan record niet verwijderen omdat het niet bestaat" te vermijden zet ik onder de knop "Ongedaan maken" eveneens het commando ".AllowAdditions = True".

Alles werkt nu prima.:d
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan