Formulier voor koppeltabel

Status
Niet open voor verdere reacties.

Matjes

Gebruiker
Lid geworden
21 jun 2016
Berichten
76
In een Access database heb ik een veel-op-veel relatie tussen een tblProducten en tblOpties. Deze veel-op-veel relatie is tot stand gebracht met een koppeltabel.

Nu zit ik denken om een hoofdformulier te maken op basis van tblProducten en een subformulier in gegevensbladweergave waarin alle opties worden weergegeven uit tblOpties. Middels een checkbox bij elke optie dient dan een optie te worden toegevoegd, of indien unchecked te worden verwijderd in de koppeltabel. Wanneer het formulier weer geopend wordt dan dient bij het gekozen product dan ook weer automatisch de checkboxes te worden aangevinkt op basis van de gegevens zoals vastgelegd in de koppeltabel.

Bovenstaande zou ik graag in VBA willen maken maar ik ben nog op zoek naar de grote lijnen hoe ik dit het beste kan gaan maken.

Tips en suggesties of voorbeelden zijn dus zeer welkom :thumb:
 
Het verhaal was duidelijk tot deze zin verscheen:
Bovenstaande zou ik graag in VBA willen maken maar ik ben nog op zoek naar de grote lijnen hoe ik dit het beste kan gaan maken.
Waarom?
 
Waarom, tja, omdat ik denk dat het zonder VBA niet is te realiseren. Maar als er een eenvoudiger oplossing mogelijk is zonder VBA is dat natuurlijk ook prima :)
 
Met subformulieren kun je het helemaal zonder VBA doen, dus ik zie niet in waarom je het anders zou willen doen.
 
Ik zie nog niet in hoe ik dat met checkboxes zou moeten maken :shocked:

Als ik dan de koppeltabel heb met bijvoorbeeld:

ProductID - OptieID
1 - 123
1 - 193
1 - 13
2 - 123

hoe krijg ik dan de OptieID toegevoegd en verwijderd bij het ProductID bij respectievelijk selecteren en deselecteren van de checkbox, evenals het verwijderen het ProductID van de betreffende regel?
 
Laatst bewerkt:
Je wilt iets dat gewoon met standaard functionaliteit is te maken. Kwestie van in je tabel Producten een veld met meerdere waarden toevoegen, daar je opties tabel aan hangen en klaar is-tie. En ja, ik ben een groot tegenstander van dit type veld :). Maar in jouw geval is het de slimste optie. Die koppeltabel slaat namelijk nergens op, omdat het geen koppeltabel ís. Normaal gesproken maar je, als je al een koppeltabel gebruikt, voor elke optie een apart record aan. Dus een apparaat met 12 opties, heeft in de koppeltabel 12 records. Die opties kies je met een keuzelijst in het formulier. Dus je ziet een hoofdformulier en een subformulier met daarin de toegevoegde optie-records. Dat derde formulier met alle opties gebruik je dus niet. Nergens voor nodig, alleen maar ballast op je formulier.
Als je, zoals jij blijkbaar wilt, eerst op je gemakje alle opties kunt aanvinken voordat de records worden aangemaakt, ja, dan moet je programmeren. Dat dan wel. Dan nog zou ik voor je optielijst een keuzelijst gebruiken waarop je meerdere opties kunt aanklikken, en geen formulier met selectievakjes.
 
De reden dat alle mogelijk opties weergeven moeten worden en niet vanuit een keuzelijst gekozen moeten worden is het aantal aanwezige opties. Orde grote 100 opties waarvan er afhankelijk van het product circa 30% van gekozen kunnen worden. Dan is het voor de gebruiker 'gebruikersvriendelijker' om deze aan te vinken dan deze vanuit een ellenlange keuzelijst te kiezen.

Ik zit dus zelf te denken aan VBA met bijvoorbeeld een recordset en Do While loop.

Dan per optie bekijken of deze al voorkomt bij het productID en daarmee de checkbox op true zetten.

Mutaties voor opties kunnen dan middels het wijzigen van de checkboxes doorgevoerd worden. Sluiten van het formulier is dan alle records met het productID verwijderen in de koppeltabel. Vervolgens voor alle geselecteerde checkboxes weer een record per optie aanmaken.

Is dit een goede oplossing?


Ander idee is twee subformulieren:

1 links met de gekozen opties bij het product
1 rechts met alle nog niet gekozen opties bij het product

Dan met selecteren en knop links of rechts de optie 'overzetten', (of met dubbelklik).

Hier zit nog wel enige VBA uitdaging aan voor mij :)
 
Laatst bewerkt:
Het volgende heb ik er van gemaakt.

Hoofdformulier met Product en daaronder een subformulier Eisen welke gebaseerd is op een Query met alle mogelijke eisen.

Bij het laden van het formulier Product eerst bepalen met een SQL welke eisen al aan het product gekoppeld zijn. Hier een recordset van maken en middels een Do While de records in tabel Eisen markeren (transfer). Het subformulier laat dan alle eisen zien en degene welke al gekoppeld zijn aan het product, daarvan zijn de checkboxes op True gezet:

Code:
Private Sub Form_Load()
On Error GoTo ErrorHandler

Dim rs As DAO.Recordset
Dim strSQL As String

strSQL = "SELECT tblSD_Subtype.SD_SubtypeID, tblVE_Eis.EisID, tblEis.Transfer " _
        & "FROM tblEis INNER JOIN (tblSD_Subtype INNER JOIN tblVE_Eis " _
        & "ON tblSD_Subtype.SD_SubtypeID = tblVE_Eis.SD_SubtypeID) " _
        & "ON tblEis.EisID = tblVE_Eis.EisID " _
        & "WHERE (((tblSD_Subtype.SD_SubtypeID)= " & [SD_SubtypeID] & "));"

Set rs = CurrentDb.OpenRecordset(strSQL)

Debug.Print strSQL
Debug.Print [SD_SubtypeID]

    With rs
        If Not .BOF And Not .EOF Then
            .MoveLast
            .MoveFirst
            
            Do While (Not .EOF)
            rs.Edit
            !Transfer = True
            .Update
            
            Debug.Print rs.Fields("EisID")
            
            .MoveNext
            
            Loop
            
        End If
        
        .Close
    End With
    
Exit_Procedure:
    
    Set rs = Nothing
    Exit Sub
    
ErrorHandler:
        
        MsgBox " & Err.Number & ", " & Error Description"
        Resume Exit_Procedure

End Sub



Dan kan middels de checkbox op het subformulier een eis gekoppeld of ontkoppeld worden van het product:

Code:
Private Sub chkTransfer_Click()

On Error GoTo Error_Handler
Dim strSQL As String

    If Me.chkTransfer = True Then
            
            strSQL = "INSERT INTO tblVE_Eis ( EisID, SD_SubtypeID )" _
            & "SELECT " & Me.txtEisID & ", " & Me.Parent!SD_SubtypeID & ";"

            DoCmd.SetWarnings False
            DoCmd.RunSQL strSQL
            Me.Refresh
    Else
            strSQL = "Delete tblVE_Eis.SD_SubtypeID, tblVE_Eis.EisID " _
            & "FROM tblVE_Eis " _
            & "WHERE (((tblVE_Eis.SD_SubtypeID)= " & Me.Parent!SD_SubtypeID & ") AND ((tblVE_Eis.EisID)= " & Me.txtEisID & "));"
    
            DoCmd.SetWarnings False
            DoCmd.RunSQL strSQL
            Me.Refresh
    End If


Bij het sluiten van het formulier worden alle checkboxes in tabel Eisen weer op False gezet:

Code:
Private Sub Form_Close()
Dim rs As DAO.Recordset
Dim strSQL As String

strSQL = "SELECT tblEis.EisID, tblEis.Transfer " _
        & "FROM tblEis;"

Set rs = CurrentDb.OpenRecordset(strSQL)

Debug.Print strSQL

    With rs
        If Not .BOF And Not .EOF Then
            .MoveLast
            .MoveFirst
            
            Do While (Not .EOF)
                If !Transfer = True Then
                    .Edit
                    !Transfer = False
                    .Update
                End If
                     
            .MoveNext
            
            Loop
            
        End If
        
        .Close
    End With
    
Exit_Procedure:
    
    Set rs = Nothing
    Exit Sub
    
ErrorHandler:
        
    MsgBox " & Err.Number & ", " & Error Description"
    Resume Exit_Procedure

End Sub

Dit allemaal werkt prima. Nadeel is wel dat ik een extra veld chkTransfer heb moeten maken in tabel Eisen. Kan ik dit nog voorkomen?
 
Niet als je eerst de selecties wilt kunnen maken; die moet je nu eenmaal ergens opslaan. Overigens kun je voor de selectie natuurlijk een tijdelijke tabel maken, die je dan in één keer overzet. Maar dat neemt niks af van het feit dat je nu eenmaal een veld (of record) nodig hebt met de selectie.
Dat gezegd hebbende: je kunt natuurlijk ook een variabele gebruiken waarin je de geselecteerde records opneemt. En die (matrix) variabele gebruik je dan later om de records toe te voegen. Dan heb je geen extra velden nodig, maar loop je wel het risico dat als de computer uitvalt tijdens het selecteren, je opnieuw kunt beginnen. Dat heeft een tabel niet.
Overigens kan je code nog wel netter... :).
 
Octafish bedankt voor het aandragen van de andere oplossingen. Ik denk dat ik het voorlopig maar bij deze oplossing houd.

Als je nog tips hebt hoe ik de code netter kan schrijven dan hoor ik deze graag. Ben dan ook benieuwd hoe een pro deze code zou schrijven ;)
 
Nou, je laatste code bijvoorbeeld kan met 2 regels:
Code:
    strSQL = "UPDATE tblEis SET Transfer = False;
    CurrentDb.Execute strSQL, dbFailOnError
:D.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan