Subformulier in subformulier in hoofdformulier, requery

Status
Niet open voor verdere reacties.

DaFuzz

Gebruiker
Lid geworden
12 dec 2013
Berichten
27
Goedemiddag dames en heren

Ik hoop zo dat ik het duidelijk weet uit te leggen :)

Ik loop tegen een ietwat vreemd probleem aan, maar dit kan te maken hebben met de opzet van mijn formulieren.
De formulieren heten HCategorie, SCategorie en SSCategorie, welke allen gebaseerd zijn op hun gelijknamige tabellen.
Simpelweg uitgelegd, Hoofd Categorie, Subcategorie en Sub Sub Categorie.

De keuzes die ik maak in het hoofd formulier hebben invloed op de antwoorden die tevoorschijn komen in het Subformulier en zo door naar het Sub Sub formulier.
vb, In hoofdcategorie selecteer ik schilder en in het Subformulier komen alle gerelateerde opmerkingen betreffende de schilder.
Nadat ik de opmerking van de schilder heb aangeklikt, moeten er nieeuwe antwoorden verschijnen in het Sub Sub formulier

De formulieren zitten als volgt in elkaar (Hoofdformulier -> Subformulier)

HCategorie -> SCategorie
SCategorie -> SSCategorie

De formulieren zijn als volgt opgebouwd.
HCategorie - HCategorieID (PK), HCategorie (Tekstveld met benaming)
SCategorie - SCategorieID (PK), SCategorie (Tekstveld met benaming) HCatVal (referentie naar HCategorieID)
SSCategorie - SSCategorieID (PK), SSCategorie (Tekstveld met benaming), CCatVal (Referentie naar CCategorieID)

Het is uiteindelijk de bedoleing dat dit cascading keuzelijsten gaan worden, de eerste twee zijn gelukt, de laatste doet vervelend.

In HCategorie heb ik een invoerveld gemaakt, gebaseerd op HCategorie, HCategorieID heb ik verstopt, omdat dit voor de gebruiker niet interesant is.
Een knopje om een nieuw record aan te kunnen maken en een keuzelijst met alle reeds ingevoerde items uit de tabel HCategorie.

In CCategorie heb ik exact hetzelfde gedaan, maar heb ik ook het veld HCatVal onzichtbaar gemaakt.
Dit formulier heb ik middels de wizard subformulier/rapport toevoegen, ingevoerd in het HCategorie formulier, waarbij HCategorieID hetzelfde moet zijn als HCatVal.
De keuzelijst in SCategorie heb ik geplaatst met de wizard en aangegeven dat hij de een record moet opzoeken op basis van de waarde die is geselecteerd in de keuzelijst.
Daarna heb ik de query voor de keuzelijst iets aangepast naar: SELECT SCategorie.SCategorieID, SCategorie.SCategorie, SCategorie.HCatValue FROM SCategorie WHERE (((SCategorie.HCatValue)=[Formulieren]![HCategorie]![HCategorieID]));
In het HCategorie formulier heb ik in de keuzelijst bij aanklikken de volgende code gebruikt:

Private Sub Keuzelijst3_Click()
Me!SCategorie.Form!Keuzelijst8.Requery
End Sub

Dit om ervoor te zorgen dat als ik iets aanklik in het hoofdformulier, de juiste waarden direct getoond worden in het subformulier.
En dat werkt fantastisch.

Maar, als ik deze stappen herhaal met het SSCategorie formulier en vervolgens het hoofdformulier open, dan krijg een invoer pop up, Parameterwaarde opgeven, Formulieren!Scategorie!SCategorieID
En dat verbaast mij, aangezien het SCategorie formulier wel geopend is (welliswaar als subform, maar toch).

Wie kan mij hier verder mee helpen?
 
Ik heb nogal wat bedenkingen bij jouw methodiek; ik zou die never nooit zo gebruiken. Al was het maar omdat het vele malen simpeler kan. Maar dat is wellicht wat voor later. Je haalt je nu in ieder geval problemen op de hals die m.i. nergens voor nodig zijn. Zelfs met jouw tabellenstructuur kan het een heel stuk simpeler, want wat is het nut van 3 formulieren? Die keuzelijsten kunnen makkelijk op één formulier staan, en dan werkt de afhankelijkheid een stuk eenvoudiger.

De reden dat de tweede keuzelijst wel werkt en de derde niet, is een hele simpele: de tweede keuzelijst gebruik je van het hoofdformulier en de derde keuzelijst (die afhankelijk is van de tweede) gebruik je van een subformulier. En dan krijg je een ander pad. Maar tenzij je extra betaald wordt om het zo ingewikkeld mogelijk te maken, zou ik eerst eens de zaak versimpelen. :)
 
Dank je voor je feedback Octafish

Ik hoor graag hoe dit simpeler kan, want ik ben al een week aan het stoeien en heb al diverse oplossingen geprobeerd, met bovenstaande als laatste oplossing.
Het is de bedoeling dat de gebruiker dus door 3 keuzelijsten heen gaat, die elk informatie tonen gebaseerd op de voorgaande keuzelijst.
Tevens moet er een mogelijkheid komen om een nieuwe record toe te kunnen voegen aan de bestaande keuzelijsten, wederom gebaseerd op de keuze uit de voorgaande keuzelijsten.

Zo moet de gebruiker in staat zijn om bijvoorbeeld categorieen toe te voegen, maar ook in staat zijn om een volledig nieuwe categorie aan te maken.
Het moeilijke denken komt bij mij voornamelijk omdat ik iedere keer het op een andere manier probeer als een oudere manier niet werkt, maar dat is geen garantie dat het simpeler wordt :)
 
Voor het mooie zou je een voorbeeldje moeten plaatsen, dan kunnen we zien wat je nu hebt. Maar je wilt graag weten hoe het simpeler kan, dus dat is een goede start :).
OK, om te beginnen: trek al die keuzelijsten van die subformulieren af, en zet alles op één formulier. Er is, zoals ik al zei, zo op het oog (nogmaals: met de db erbij is het veel beter te beoordelen) geen enkele reden om die keuzelijsten in een apart (sub)formulier te zetten. Zeker niet als de gebruiker op één formulier drie keuzelijsten moet doorlopen. Dan is het gewoon beter om alles op één formulier te zetten.
Als dat is opgelost, kun je de tweede keuzelijst filteren op de eerste, en de derde op de tweede met exact dezelfde techniek. Dus het IDveld (HCategorieID) van de eerste gebruik je om de tweede te filteren (op HCatVal), en het IDveld van de tweede (SCategorieID) gebruik je als filter voor de derde (CCatVal).
Code:
Private Sub Keuzelijst3_Click()
     Me.Keuzelijst8.Requery
End Sub

en
Code:
Private Sub Keuzelijst8_Click()
     Me.Keuzelijst12.Requery
End Sub
Ik zou overigens fatsoenlijke namen gebruiken voor (eigenlijk alles) je keuzelijsten, want alleen op basis van de namen Keuzelijst3 en Keuzelijst8 kan ik niet zien wat de eerste is, en wat de tweede. Maar we hadden al gezien (gezien je subformulieren) dat je niet van makkelijk houdt :D.

Dit is overigens niet de manier waarop ik het zou doen, maar dat komt wellicht later wel aan bod.
Nu nog het 'probleem' van de nieuwe (sub)categorieën toevoegen. Eigenlijk is dat heel simpel, en daar heb je dus ook geen knop(pen) voor nodig: keuzelijsten hebben daar al een voorziening voor :). Namelijk de gebeurtenis <Bij niet in lijst> (<NotInList>). Die gebeurtenis wordt automatisch getriggerd zodra je een niet-bekende waarde invoert en op <Enter> drukt. De keuzelijst ziet dan dat de waarde niet bestaat, en dat start de gebeurtenis <NotInList> en daarmee kun je op twee manieren de ingevoerde tekst toevoegen aan de lijst. Manier 1: gelijk opnemen in de tabel. Manier 2: Een formulier openen dat is gebaseerd op de tabel, daarin de nieuwe categorie toevoegen en terugkeren naar het oorspronkelijke formulier waar je de keuze gelijk kan gebruiken.

Beide manieren hebben voor- en nadelen. Nadeel van de eerste methode: je kunt doorgaans maar één veld vullen (eventueel met een referentieveld erbij). Bij een tabel tCategorie werkt dat prima, want dan heb je vermoedelijk maar één tekstveld, en hooguit één verwijzingsveld. Beide gegevens heb je al in je formulier staan, dus die kun je prima hergebruiken. Anders wordt het als je een Klantnaam via een keuzelijst opzoekt, of een artikel(code) met een beschrijving, leverancier, prijs, verpakkingseenheid etc. In die gevallen moet je, als je een nieuwe klant of artikel wilt toevoegen, dus meerdere gegevens invullen. En dan moet je wel een formulier gebruiken.

In jouw geval is de eerste methode dus prima te gebruiken. Oftewel: je typt een categorie die nog niet bestaat, de gebeurtenis <Bij niet in Lijst> wordt getriggerd, het nieuwe record wordt toegevoegd en je kunt gelijk verder op je formulier. Makkelijker kun je het eigenlijk niet maken!
 
Wederom dank je wel Octafish :)

Ik zal proberen uit te leggen wat ik van plan ben als eindresultaat, in plaats van uit te leggen waar ik mee zit te worstelen.
De database is in porincipe een hele simpele en voornamelijk bedoelt als melding systeem voor een bedrijf.
Op deze manier kunnen zij heel makkelijk opvragen waar bijvoorbeeld de meeste meldingen over worden gedaan.

Het volledige meldingen formulier ziet er als volgt uit.

Melding.JPG

De medewerkers die met dit formulier gaan werken moeten zo spoedig mogelijk in staat zijn om hun meldingen in te kunnen voeren en dan door met de volgende melding.
ZIj hoeven dus niets op te zoeken, enkel maar invoeren
Dit formulier werkt fantastisch, niets meer aan veranderen :)

Speciaal voor de beheerders van deze database, probeer ik een formulier te maken waarbij de 3 categorieen constant afhaneklijk van elkaar zijn en zij in deze zelfde structuur een nieuwe categorie aan kunnen maken.

Cattree.JPG

een voorbeeld hoe ik momenteel een query heb ingesteld:

Cattreeresult.JPG

Voor beide gebruikers heb ik een apart database aangemaakt (master en forms) waar de tabellen in de master staan en het meldings formulier in de Forms.
De beheerders moeten dan in de master kunnen komen om daar eventueel op een simpele manier de gegevens in te kunnen voeren, maar de gewone gebruiker hoort daar niet te komen (te veel moeite om uit te zoeken hoe dit moet met wachtwoorden, dus ik ga van de integriteit van de medewerkers uit)
Reden hiertoe is dat de betreffende gebruikers weinig tot geen kennis hebben van Access en ik ze probeer te verwennen met een soort van kant en klaar product.
En dit formulier is de laatste uitdaging :)
 
Je hebt een prima formulier waarin je alles kan doen. Nu snap ik al helemaal niet waarom je het zo ingewikkeld wilt maken!
Begrijp ik nu uit je verhaal dat je twee backends hebt gemaakt? Dat zal toch niet?
Hou het simpel, en gebruik dezelfde frontend voor alle gebruikers. Doe ik zelf ook. Zelfs de beheerders van de db hoeven niet in de backend te komen, en dat komen ze bij mij dus ook nooit. Het afvangen van wie wat mag doen, leg ik vast in een gebruikerstabel, waarin ik met een cijfer aangeef wat de rechten zijn. Dat doe je door in de tabel een keuzelijst met invoervak te maken met 2 kolommen, en deze rijbron:
PHP:
1;"Beheerder";2;"Superuser";3;"Gebruiker";4;"Gast"
Iets anders mag natuurlijk ook.

Mijn gebruikers moeten inloggen in de database (inlogformulier uiteraard) waarbij de gebruikersnaam als inlog wordt gebruikt. Dus als Jan Klaassen de inlognaam klaas01 heeft, dan is dat ook de inlognaam voor de database.
Bij het inloggen kun je heel simpel afvangen wie de ingelogde gebruiker is en op basis daarvan bepaalde instellingen doorvoeren. Een voorbeeldje:
Code:
    strSQL = "SELECT [medewerkerID], [inlognaam], [medewerker_naam], [rechten], [Actief] FROM tMedewerkers WHERE [Actief] = TRUE AND [Inlognaam] = """ & VBA.Environ("USERNAME") & """" 
    Set rst = CurrentDb.OpenRecordset(strSQL)
    With rst
        If .RecordCount = 1 Then
            TempVars("varMedID") = !MedewerkerID.Value
            TempVars("varMedInlog") = !inlognaam.Value
            TempVars("varMedNaam") = !medewerker_naam.Value
            TempVars("varAccessLevel") = !rechten.Value
            .Close
        Else
            MsgBox "Je hebt geen rechten op deze database, of je inloggegevens zijn niet correct." & vbNewLine _
                & "Neem dit op met de beheerder van de database", vbInformation
            Application.Quit
        End If
    End With
    If TempVars("varAccessLevel").Value < 3 Then Me.cmdInlogscherm.Enabled = True Else: Me.cmdInlogscherm.Enabled = False
Ik gebruik hier overigens ook TempVars variabelen om de instellingen gedurende de hele sessie te kunnen gebruiken. De laatste regel deactiveert een knop op het formulier; die is dus alleen te gebruiken door beheerders en superusers. Dezelfde techniek kun je ook gebruiken om te voorkomen dat gewone gebruikers records toevoegen aan een keuzelijst. Dat recht geef je dan bijvoorbeeld alleen aan beheerders.
Kortom: je formulier lijkt mij prima, de afhankelijkheden zijn daar uitstekend op te maken, en de beveiliging ook. Gewoon gebruiken dus!
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan