I am a web developer by trade.
Ocassionaly, it's necessary to demonstrate a certain UI pattern for getting users access to data outside of your comfort zone. I've recently acquired a new mentoree, and he's very comfortable inside of the Access VBA environment. Not so much with VB.Net or C#, and certainly not on the web. Sigh, his time may yet come.
I'm trying to get him to learn some more generalized patterns for working with data in different formats. Trees, Many to Many, Quad-Trees, etc. Freeing the mind so to speak.
We're using this data-schema to represent a many to many relationship.

This is useful, because you can model things like Users and Roles. ala the ASP.Net Role Management system.

In this case, our "series" are actually Members. The same concept applies.
The reason we're discussing this, is because a database we work with has a new requirement. Only display certain series to users which are in a certain group. The "series" happens to be the domain object, and the roles are going to be fixed as NT Security groups. which the users are already members of. (Technically, some aren't they're just going to be anonymous, which is the security group BUILTIN\EVERYONE)
Killer, so how to do this inside Access?
Here's the form I came up with.

I've used some bogus data here, because we're working in a different database. It's pretty clear what's happening though.
The control on the left is an Access.istBox, bound to the Series Table. This allows us to get the SeriesID by examining the Value property of the SeriesListBox. This is going to be Null when the ListBox.ListIndex = -1.
The control on the right is a MSComctlLib.TreeCtrl.2. This control has an interesting feature called Checkboxes which "Returns/sets a value which determines if the control displays a checkbox next to each item in the tree."
This is horribly useful, because it allows us to treat the single control as a List of Checkbox Nodes... handy.

Essentially this is what's going to happen.
1. The form will load, and the Series Binding will happen automagically, due to the control's design-time definition.
2. We want to clear the TreeView of all nodes it might have.
Dim tree As TreeView
Set tree = uxTreeViewRoles.Object
tree.Nodes.Clear
3. We want to populate the TreeView with a list of possible Roles from the appropriate table, keeping track of which node is which ID.
Dim tree As TreeView
Dim n As Node
Set tree = uxTreeViewRoles.Object
Dim rstRole As DAO.Recordset
Set rstRole = CurrentDb.OpenRecordset("Select RoleID, Name FROM Roles;")
rstRole.MoveFirst
Do While Not rstRole.EOF
Set n = tree.Nodes.Add(, , , rstRole!Name) ' short for rstRole.Fields("Name").Value
n.Tag = rstRole!RoleID
n.Checked = False
rstRole.MoveNext
Loop
4. Every time a Series is selected from the ListBox, we'll do two things.
4.1. Clear the checkboxes in the TreeView.
Dim tree As TreeView
Set tree = uxTreeViewRoles.Object
Dim n As Node
For Each n In tree.Nodes
n.Checked = False
Next
4.2 Update the checkboxes to represent the Roles which are available for the series
Dim intSeriesID As Integer
intSeriesID = uxListSeries.Value
' Tools, References, Microsoft Scripting Runtime
Dim dRoles ' This will store the Roles we find when we query the SeriesRoles table
Set dRoles = CreateObject("Scripting.Dictionary")
Dim tree As TreeView
Set tree = uxTreeViewRoles.Object
' Add RoleIDs from the SeriesRoles table
Dim rstSeriesRoles As DAO.Recordset
Set rstSeriesRoles = CurrentDb.OpenRecordset("SELECT SeriesID, RoleID FROM SeriesRoles WHERE SeriesID=" & intSeriesID)
' No Records
If (rstSeriesRoles.BOF = True Or rstSeriesRoles.EOF = True) Then Exit Sub ' Easy, no Roles exist for this seriesID
rstSeriesRoles.MoveFirst
Do While Not rstSeriesRoles.EOF
dRoles.Add CStr(rstSeriesRoles!RoleID), CStr(rstSeriesRoles!SeriesID) ' Add this role to the Roles dictionary, we'll use it in a minute.
rstSeriesRoles.MoveNext
Loop
Dim n As Node
For Each n In tree.Nodes
If (dRoles.Exists(CStr(n.Tag))) Then ' The role was found when we looked at the SeriesRole table.
n.Checked = True
Else
n.Checked = False
End If
Next 'n
5. All that's left now, is to handle what happens when one of those checkboxes is clicked on.
Dim nRoleID, nSeriesID As Integer
Dim n As Node
Set n = Node
nRoleID = n.Tag
nSeriesID = uxListSeries.Value
Select Case n.Checked
Case True
' Add a row to the join table
Access.CurrentDb.Execute _
"INSERT INTO SeriesRoles (SeriesID,RoleID) " & _
"VALUES (" & nSeriesID & "," & nRoleID & ")"
Case False
Access.CurrentDb.Execute _
"DELETE FROM SeriesRoles " & _
"WHERE (" & _
"SeriesID=" & nSeriesID & _
" AND RoleID=" & nRoleID & ")"
End Select
And that's a wrap.
Still, I wonder what I could have done with VSTO, instead of VBA...