Reputation: 789
I'm new to Microsoft Access and would like to create a ListBox (or ListView) with checkboxes, however I can't find any native way for doing so.
My intention is to display a list of values and have some of the values checked depending on what value is selected in a ComboBox on the form.
Please note that I'm needing such a control for a form and not a table (for which there's this "multivalued lookup field"). (Besides if there's a way to create a subform with a table with just the multivalue-column that reacts to what's selected in the ComboBox.)
An ordinary list box with the "Multi Select" property set to "Simple" doesn't display checkboxes.
I also can't see the "ListStyle" property described here.
Maybe it's somehow possible to display two columns in the ListBox of which the first is rendered as checkbox?
Upvotes: 6
Views: 25870
Reputation: 789
So got it working now with the help of Andre's answer:
First, as the ListView is dependent on the currently selected item of a table I'm populating it via the Form_Current event of the table. (Simply by Call Forms.Item("MainForm").PopulateListView
)
Here's the working PopulateListView method (note that you need to reference Microsoft Windows Common Controls 6.0 first):
Public Sub PopulateListView()
On Error GoTo ErrorHandler
Dim intToCount As Integer
Dim intCount1 As Integer
Dim intCount2 As Integer
Dim intToCount2 As Integer
Dim intCount12 As Integer
Dim intCount22 As Integer
Dim NewLine As Object
Dim db As Database
Dim rs As Recordset
Dim colNew As Object
Dim s As String
' Clear the ListView control.
Forms![MainForm].[SubForm].Form.[ctlListView].ListItems.Clear
Forms![MainForm].[SubForm].Form.[ctlListView].ColumnHeaders.Clear
' Set Variables.
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT A, B, IsChecked . . .")
' Set Column Headers.
Set colNew = Forms![MainForm].[SubForm].Form.[ctlListView].ColumnHeaders.Add(, , "A", 2000)
Set colNew = Forms![MainForm].[SubForm].Form.[ctlListView].ColumnHeaders.Add(, , "B", 4000)
' Set Total Records Counter.
rs.MoveLast
intToCount = rs.RecordCount
rs.MoveFirst
' Loop through recordset and add Items to the control. Twice as a workaround to sort by checkbox.
For intCount1 = 1 To intToCount
If (rs(2).value = 1) Then
If IsNumeric(rs(0)) Then
s = Trim(Str(rs(0).value))
Else
s = Trim(rs(0).value)
End If
Set NewLine = Forms![MainForm].[SubForm].Form.[ctlListView].ListItems.Add(, , s)
If IsNull(rs(1)) Then
NewLine.ListSubItems.Add Text:=""
Else
NewLine.ListSubItems.Add Text:=rs(1).value
End If
NewLine.Checked = True
End If
rs.MoveNext
Next intCount1
' Set Total Records Counter.
rs.MoveLast
intToCount2 = rs.RecordCount
rs.MoveFirst
For intCount12 = 1 To intToCount2
If (rs(2).value = 0) Then
If IsNumeric(rs(0)) Then
s = Trim(Str(rs(0).value))
Else
s = Trim(rs(0).value)
End If
Set NewLine = Forms![MainForm].[SubForm].Form.[ctlListView].ListItems.Add(, , s)
If IsNull(rs(1)) Then
NewLine.ListSubItems.Add Text:=""
Else
NewLine.ListSubItems.Add Text:=rs(1).value
End If
End If
rs.MoveNext
Next intCount12
Exit Sub
ErrorHandler:
' Err 3021 = no current record. Err 2455 = happens at necessary first call of method and couldn't catch in code.
If Err = 91 Or Err = 3021 Or Err = 2455 Then
Resume Next
Else
If Err <> 94 Then
' Otherwise display the error message.
MsgBox "Error: " & Err.Number & Chr(13) & Chr(10) & Err.Description & vbCrLf & "(PopulateListView)"
End If
End If
End Sub
Then for saving I'm using this:
For Each Item In Forms![MainForm].[SubForm].Form.[ctlListView].Object.ListItems
If Item.Checked = True Then
'Use Item here
End If
Next
Upvotes: 1
Reputation: 27634
You can use the ListView
control. It is located under ActiveX Controls, the full name is Microsoft ListView Control, version 6.0
.
It has a separate set of properties: right-click -> ListViewCtrl object -> Properties, in there is the Checkboxes
property.
To fill the listview with data, see e.g. ACC: Sample Function to Fill a ListView Control
More info: Using the ListView Control
Edit
To comfortably work with the Listview object model, set a reference to Microsoft Windows Common Controls 6.0
= C:\Windows\SysWOW64\MSCOMCTL.OCX
on my Windows7 64bit.
Edit 2
I use a TreeView with checkboxes. Each Node
has a Checked
property, that checks or unchecks its checkbox. Where the Treeview has Nodes, the Listview has ListItems, but they have a Checked
property too.
Simplified code for Treeview (without hierarchies):
Dim oTree As TreeView
Dim oNode As Node
Dim RS As Recordset
Set oTree = Me.myTreeView.Object
oTree.Nodes.Clear
Set RS = DB.OpenRecordset("My query to fill the treeview")
Do While Not RS.EOF
Set oNode = oTree.Nodes.Add(key:=RS!foo, Text:=RS!bar)
oNode.Checked = (RS!someValue > 0)
RS.MoveNext
Loop
RS.Close
Upvotes: 7
Reputation: 55806
You can't modify a listbox of Access like that, but you can customize a subform in datasheet view to mimic such a listbox.
To display more or less fixed values, create a small local table to be bound by the form and fill it with the values you need.
Upvotes: 2