From: Salad on
At times I've wished I could have a virtual checkbox to select items for
further action. Maybe you have a bunch of records in a form but only
want to see a report of those you've flagged for display in a report.
(Similar to a multiselect listbox but using a form instead).

I wrote a small app to do that (code below). It's not a class but could
be converted to one. It assumes you have a table/query that has a
primary key. It also assumes the primary key is a longInt (ex:
autonumber). It assumes that the default checkbox value is false but if
you want to, you can set the initial value of the checkbox to True.

Let's say you have a table called Customer with 2 fields; CustomerID,
CustomerName. The app will create a table link and query called
qryCheckTableN (where N is a number) and will contain the customerid,
customername, and a checkbox. This query could now be your recordsource.

It creates a database in the same folder you run the app from called
CheckTable if it doesn't exist. It then finds the next CheckTable to
make. And it creates a table in that database. It then creates a link
and a query in the FE you run it from. The resulting query,
qryCheckTable1, might look like
Select CustomerID, CustomerName, CheckBox From ...

It's a function. So you might do something like this
Dim strQuery As String
strQuery = CTInitialize("CustomerID","Customer") 'checkbox false
or
strQuery = CTInitialize("CustomerID","Customer",True)
so all values of checkbox are true.

If you had a query like
"Select CustomerID, CustomerName From Customer"
and it was save as Query1, you could also do
strQuery = CTInitialize("CustomerID","Query1")

strQuery would then have a value of "qryCheckTable1" or
something similar to point to the query that was created after
running the above code

When ready to unload the form/rpt/etc, enter something like
CTDelete strQuery
to delete the link, query, and table in the external database

This would be best for small data sets as one doesn't want to delay
users from getting to the data.

Here's the code. Copy this into a new module to run.
'**************** Start Of Code **********************
Option Compare Database
Option Explicit
Const TableName = "CheckTable"
Public Function CTInitialize(strPrimaryKey As String, _
strPrimaryTable As String, _
Optional chkSetAsTrue As Variant) As String

'strPrimaryKey is the field name from the main table to link to
'strPrimaryTable is the table/query that holds the primary key
'chkSetAsTrue will set all checkboxes to value supplied
'Useage: strQuery = CTInitialize("Table1", "Table1Key")
' strQuery = CTInitialize("Table1", "Table1Key", True)

Dim dbs As Database
Dim strNewTable As String
Dim strDBS As String

strDBS = CurrentDb.Name
strDBS = Left(strDBS, InStrRev(strDBS, "\")) & TableName & ".mdb"

'make the database if needed
If Dir(strDBS) = "" Then MakeNewDatabase strDBS

Set dbs = OpenDatabase(strDBS)

'delete tables from the temp database if they are older than 6 days
DelCheckTables dbs

'get name to hold the check table
strNewTable = NewCheckName(dbs)

'now make the new CheckTable?
MakeNewTable dbs, strPrimaryKey, strNewTable

'now link the new table
DoCmd.TransferDatabase acLink, "Microsoft Access", strDBS, _
acTable, strNewTable, strNewTable

dbs.Close
Set dbs = Nothing

'now appendrecs
AppendRecs strPrimaryKey, strNewTable, strPrimaryTable, _
IIf(IsMissing(chkSetAsTrue), False, True)


'now join the two tables together by making a query
CreateCheckTableQuery strPrimaryKey, strNewTable, strPrimaryTable

'return the new query that contains the main table with checkboxes
CTInitialize = "qry" & strNewTable
End Function

Private Sub MakeNewDatabase(strNewDatabase As String)
'this creates a new database called CHECKTABLE in the
'current FE folder
Dim strDBS As String
Dim dbsNew As Database
Dim wrkDefault As Workspace

'Get default Workspace.
Set wrkDefault = DBEngine.Workspaces(0)

' Create a new database
Set dbsNew = wrkDefault.CreateDatabase(strNewDatabase, _
dbLangGeneral)
dbsNew.Close
Set dbsNew = Nothing
End Sub

Private Sub MakeNewTable(dbs As Database, strKey As String, strNewTable)
'this makes a new checktable
Dim tdf As TableDef
Dim fld As Field
Dim prp As Property

'create the new table.
Set tdf = dbs.CreateTableDef(strNewTable)

With tdf
'the new table will always contain 2 fields;
'the key's field name and the checkbox field
.Fields.Append .CreateField(strKey, dbLong)
.Fields.Append .CreateField("CheckYesNo", dbBoolean)


'add the new table to the database
dbs.TableDefs.Append tdf

Set fld = tdf.Fields("CheckYesNo")

Set prp = fld.CreateProperty("DisplayControl", _
dbInteger, acCheckBox)
fld.Properties.Append prp

End With
End Sub

Private Sub DelCheckTables(dbs As Database)
Dim dbsCurrent As Database
Dim tdf As TableDef
Dim strTable As String

Set dbsCurrent = CurrentDb

strTable = TableName
'delete the links of unnecessary files in this database
For Each tdf In dbsCurrent.TableDefs
If Left(tdf.Name, 10) = TableName Then
If CDate(Format(tdf.DateCreated, "mm/dd/yyyy")) <= Date - 7 Then
DoCmd.DeleteObject acTable, tdf.Name
End If
End If
Next

'delete the tables of unnecessary files
For Each tdf In dbs.TableDefs
If Left(tdf.Name, 10) = TableName Then
If CDate(Format(tdf.DateCreated, _
"mm/dd/yyyy")) <= Date - 7 Then
DoCmd.DeleteObject acTable, tdf.Name
End If
End If
Next
End Sub

Private Function NewCheckName(dbs As Database) As String
Dim intCheck As Integer
Dim tdf As TableDef

Do While True
On Error GoTo 0
On Error Resume Next
intCheck = intCheck + 1
Set tdf = dbs.TableDefs(TableName & intCheck)
If Err.Number > 0 Then
NewCheckName = TableName & intCheck
Exit Do
End If
Loop
End Function

Private Sub AppendRecs(strPrimaryKey As String, strNewTable As String, _
strPrimaryTable As String, bln As Boolean)
'append the record key from primary table into CheckTableX
Dim strSQL As String
strSQL = "INSERT INTO " & strNewTable & _
"(" & strPrimaryKey & ", CheckYesNo) SELECT " & _
strPrimaryTable & "." & strPrimaryKey & ", " & bln & _
" From " & strPrimaryTable
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
End Sub

Private Sub CreateCheckTableQuery(strPrimaryKey As String, _
strNewTable As String, strPrimaryTable As String)
Dim dbs As Database
Dim qdf As QueryDef
Dim strSQL As String
strSQL = "Select " & strPrimaryTable & ".* , " & _
strNewTable & ".CheckYesNo " & _
"From " & strPrimaryTable & " Inner Join " & _
strNewTable & " On " & _
strPrimaryTable & "." & strPrimaryKey & " = " & _
strNewTable & "." & strPrimaryKey

Set dbs = CurrentDb
Set qdf = dbs.CreateQueryDef("qry" & strNewTable, strSQL)

dbs.Close
Set dbs = Nothing
End Sub

Public Sub CTDelete(strQuery As String)
'remove the CheckTable link and query from currentdb
'Useage: strQuery = InitializeIt("Table1", "Table1Key")
' CTDelete (strQuery)
Dim tdf As TableDef
Dim strDBS As String
Dim strSQL As String

DoCmd.DeleteObject acQuery, strQuery
DoCmd.DeleteObject acTable, Mid(strQuery, 4)

strDBS = CurrentDb.Name
strDBS = Left(strDBS, InStrRev(strDBS, "\")) & TableName & ".mdb"

strSQL = "DROP TABLE " & strDBS & "." & Mid(strQuery, 4)
DoCmd.RunSQL strSQL

End Sub
'**************** End Of Code **********************
From: Marshall Barton on
That's pretty elaborate and should cover all kinds of
situations. Personally, the few times I needed that kind of
thing, I used Albert's Multi Select example at:
http://www.members.shaw.ca/AlbertKallal/msaccess/msaccess.html
--
Marsh


Salad wrote:
>At times I've wished I could have a virtual checkbox to select items for
>further action. Maybe you have a bunch of records in a form but only
>want to see a report of those you've flagged for display in a report.
>(Similar to a multiselect listbox but using a form instead).
>
>I wrote a small app to do that (code below). It's not a class but could
>be converted to one. It assumes you have a table/query that has a
>primary key. It also assumes the primary key is a longInt (ex:
>autonumber). It assumes that the default checkbox value is false but if
>you want to, you can set the initial value of the checkbox to True.
>
>Let's say you have a table called Customer with 2 fields; CustomerID,
>CustomerName. The app will create a table link and query called
>qryCheckTableN (where N is a number) and will contain the customerid,
>customername, and a checkbox. This query could now be your recordsource.
>
>It creates a database in the same folder you run the app from called
>CheckTable if it doesn't exist. It then finds the next CheckTable to
>make. And it creates a table in that database. It then creates a link
>and a query in the FE you run it from. The resulting query,
>qryCheckTable1, might look like
> Select CustomerID, CustomerName, CheckBox From ...
>
>It's a function. So you might do something like this
> Dim strQuery As String
> strQuery = CTInitialize("CustomerID","Customer") 'checkbox false
> or
> strQuery = CTInitialize("CustomerID","Customer",True)
> so all values of checkbox are true.
>
> If you had a query like
> "Select CustomerID, CustomerName From Customer"
> and it was save as Query1, you could also do
> strQuery = CTInitialize("CustomerID","Query1")
>
> strQuery would then have a value of "qryCheckTable1" or
> something similar to point to the query that was created after
> running the above code
>
> When ready to unload the form/rpt/etc, enter something like
> CTDelete strQuery
> to delete the link, query, and table in the external database
>
>This would be best for small data sets as one doesn't want to delay
>users from getting to the data.
>
>Here's the code. Copy this into a new module to run.
>'**************** Start Of Code **********************
>Option Compare Database
>Option Explicit
>Const TableName = "CheckTable"
>Public Function CTInitialize(strPrimaryKey As String, _
> strPrimaryTable As String, _
> Optional chkSetAsTrue As Variant) As String
>
> 'strPrimaryKey is the field name from the main table to link to
> 'strPrimaryTable is the table/query that holds the primary key
> 'chkSetAsTrue will set all checkboxes to value supplied
> 'Useage: strQuery = CTInitialize("Table1", "Table1Key")
> ' strQuery = CTInitialize("Table1", "Table1Key", True)
>
> Dim dbs As Database
> Dim strNewTable As String
> Dim strDBS As String
>
> strDBS = CurrentDb.Name
> strDBS = Left(strDBS, InStrRev(strDBS, "\")) & TableName & ".mdb"
>
> 'make the database if needed
> If Dir(strDBS) = "" Then MakeNewDatabase strDBS
>
> Set dbs = OpenDatabase(strDBS)
>
> 'delete tables from the temp database if they are older than 6 days
> DelCheckTables dbs
>
> 'get name to hold the check table
> strNewTable = NewCheckName(dbs)
>
> 'now make the new CheckTable?
> MakeNewTable dbs, strPrimaryKey, strNewTable
>
> 'now link the new table
> DoCmd.TransferDatabase acLink, "Microsoft Access", strDBS, _
> acTable, strNewTable, strNewTable
>
> dbs.Close
> Set dbs = Nothing
>
> 'now appendrecs
> AppendRecs strPrimaryKey, strNewTable, strPrimaryTable, _
> IIf(IsMissing(chkSetAsTrue), False, True)
>
>
> 'now join the two tables together by making a query
> CreateCheckTableQuery strPrimaryKey, strNewTable, strPrimaryTable
>
> 'return the new query that contains the main table with checkboxes
> CTInitialize = "qry" & strNewTable
>End Function
>
>Private Sub MakeNewDatabase(strNewDatabase As String)
> 'this creates a new database called CHECKTABLE in the
> 'current FE folder
> Dim strDBS As String
> Dim dbsNew As Database
> Dim wrkDefault As Workspace
>
> 'Get default Workspace.
> Set wrkDefault = DBEngine.Workspaces(0)
>
> ' Create a new database
> Set dbsNew = wrkDefault.CreateDatabase(strNewDatabase, _
> dbLangGeneral)
> dbsNew.Close
> Set dbsNew = Nothing
>End Sub
>
>Private Sub MakeNewTable(dbs As Database, strKey As String, strNewTable)
> 'this makes a new checktable
> Dim tdf As TableDef
> Dim fld As Field
> Dim prp As Property
>
> 'create the new table.
> Set tdf = dbs.CreateTableDef(strNewTable)
>
> With tdf
> 'the new table will always contain 2 fields;
> 'the key's field name and the checkbox field
> .Fields.Append .CreateField(strKey, dbLong)
> .Fields.Append .CreateField("CheckYesNo", dbBoolean)
>
>
> 'add the new table to the database
> dbs.TableDefs.Append tdf
>
> Set fld = tdf.Fields("CheckYesNo")
>
> Set prp = fld.CreateProperty("DisplayControl", _
> dbInteger, acCheckBox)
> fld.Properties.Append prp
>
> End With
>End Sub
>
>Private Sub DelCheckTables(dbs As Database)
> Dim dbsCurrent As Database
> Dim tdf As TableDef
> Dim strTable As String
>
> Set dbsCurrent = CurrentDb
>
> strTable = TableName
> 'delete the links of unnecessary files in this database
> For Each tdf In dbsCurrent.TableDefs
> If Left(tdf.Name, 10) = TableName Then
> If CDate(Format(tdf.DateCreated, "mm/dd/yyyy")) <= Date - 7 Then
> DoCmd.DeleteObject acTable, tdf.Name
> End If
> End If
> Next
>
> 'delete the tables of unnecessary files
> For Each tdf In dbs.TableDefs
> If Left(tdf.Name, 10) = TableName Then
> If CDate(Format(tdf.DateCreated, _
> "mm/dd/yyyy")) <= Date - 7 Then
> DoCmd.DeleteObject acTable, tdf.Name
> End If
> End If
> Next
>End Sub
>
>Private Function NewCheckName(dbs As Database) As String
> Dim intCheck As Integer
> Dim tdf As TableDef
>
> Do While True
> On Error GoTo 0
> On Error Resume Next
> intCheck = intCheck + 1
> Set tdf = dbs.TableDefs(TableName & intCheck)
> If Err.Number > 0 Then
> NewCheckName = TableName & intCheck
> Exit Do
> End If
> Loop
>End Function
>
>Private Sub AppendRecs(strPrimaryKey As String, strNewTable As String, _
> strPrimaryTable As String, bln As Boolean)
> 'append the record key from primary table into CheckTableX
> Dim strSQL As String
> strSQL = "INSERT INTO " & strNewTable & _
> "(" & strPrimaryKey & ", CheckYesNo) SELECT " & _
> strPrimaryTable & "." & strPrimaryKey & ", " & bln & _
> " From " & strPrimaryTable
> DoCmd.SetWarnings False
> DoCmd.RunSQL strSQL
> DoCmd.SetWarnings True
>End Sub
>
>Private Sub CreateCheckTableQuery(strPrimaryKey As String, _
> strNewTable As String, strPrimaryTable As String)
> Dim dbs As Database
> Dim qdf As QueryDef
> Dim strSQL As String
> strSQL = "Select " & strPrimaryTable & ".* , " & _
> strNewTable & ".CheckYesNo " & _
> "From " & strPrimaryTable & " Inner Join " & _
> strNewTable & " On " & _
> strPrimaryTable & "." & strPrimaryKey & " = " & _
> strNewTable & "." & strPrimaryKey
>
> Set dbs = CurrentDb
> Set qdf = dbs.CreateQueryDef("qry" & strNewTable, strSQL)
>
> dbs.Close
> Set dbs = Nothing
>End Sub
>
>Public Sub CTDelete(strQuery As String)
> 'remove the CheckTable link and query from currentdb
> 'Useage: strQuery = InitializeIt("Table1", "Table1Key")
> ' CTDelete (strQuery)
> Dim tdf As TableDef
> Dim strDBS As String
> Dim strSQL As String
>
> DoCmd.DeleteObject acQuery, strQuery
> DoCmd.DeleteObject acTable, Mid(strQuery, 4)
>
> strDBS = CurrentDb.Name
> strDBS = Left(strDBS, InStrRev(strDBS, "\")) & TableName & ".mdb"
>
> strSQL = "DROP TABLE " & strDBS & "." & Mid(strQuery, 4)
> DoCmd.RunSQL strSQL
>
>End Sub
>'**************** End Of Code **********************

From: Albert D. Kallal on
"Marshall Barton" <marshbarton(a)wowway.com> wrote in message
news:i13m061r3e7ldnck2lhkanh5cauu4855i0(a)4ax.com...
> That's pretty elaborate and should cover all kinds of
> situations. Personally, the few times I needed that kind of
> thing, I used Albert's Multi Select example at:
> http://www.members.shaw.ca/AlbertKallal/msaccess/msaccess.html
> --
> Marsh
>

Thanks Marsh.

My example works with un-bound boxes and the whole thing is run by less then
10 lines of VBA code.


--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
pleaseNOOSpamKallal(a)msn.com


From: Lars Brownies on
That's very nice. I noticed that there's a slight delay in making the
checkbox selections visible. Also, because of the requery, all selections
blink for a moment when you do a checkbox selection. I tried docmd.echo but
that doesn't help. Is there another way to solve that problem?

Lars

"Albert D. Kallal" <PleaseNOOOsPAMmkallal(a)msn.com> schreef in bericht
news:06GOn.92885$_84.36110(a)newsfe18.iad...
> "Marshall Barton" <marshbarton(a)wowway.com> wrote in message
> news:i13m061r3e7ldnck2lhkanh5cauu4855i0(a)4ax.com...
>> That's pretty elaborate and should cover all kinds of
>> situations. Personally, the few times I needed that kind of
>> thing, I used Albert's Multi Select example at:
>> http://www.members.shaw.ca/AlbertKallal/msaccess/msaccess.html
>> --
>> Marsh
>>
>
> Thanks Marsh.
>
> My example works with un-bound boxes and the whole thing is run by less
> then 10 lines of VBA code.
>
>
> --
> Albert D. Kallal (Access MVP)
> Edmonton, Alberta Canada
> pleaseNOOSpamKallal(a)msn.com
>
>
From: Salad on
Albert D. Kallal wrote:
> "Marshall Barton" <marshbarton(a)wowway.com> wrote in message
> news:i13m061r3e7ldnck2lhkanh5cauu4855i0(a)4ax.com...
>
>> That's pretty elaborate and should cover all kinds of
>> situations. Personally, the few times I needed that kind of
>> thing, I used Albert's Multi Select example at:
>> http://www.members.shaw.ca/AlbertKallal/msaccess/msaccess.html
>> --
>> Marsh
>>
>
> Thanks Marsh.
>
> My example works with un-bound boxes and the whole thing is run by less
> then 10 lines of VBA code.
>
>
I hadn't seen anyone discusss something like a virtual checkbox b4 so I
wrote my little app and posted it. I was hoping there'd be an
alternative to it so I was pleased that Marshall pointed me towards yours.

The reason both of us did it is because it doesn't exist in Access and
there is/was a need to have something like it for some reason. I have
to admit your's is much simpler than mine and I remain impressed. And
it does use less code. But if code were an issue we'd all be using
abacuses.

I made a copy of your form. I added the line
Dim strQuery As String
under Option Explicit and under Form Open
strQuery = CTInitialize("ContactID", "Contacts")
Me.RecordSource = strQuery
and under Form__Close
Me.RecordSource = ""
CTDelete (strQuery)
Just like I don't worry about how much code there is in the background
to run Access, I'm not worried about the amount of code to run the above.

I then did a
? CTInitialize("ContactID","Contacts")
to get a record source and added my checkbox and removed yours then
cleared out the recordsource and ran.

As Lars noted, in your example there is a slight delay when
selecting/deselecting a checkbox and there is some blinking from the
requery. If those didn't exist I would use your solution. I did not
notice any difference in the loading of the form. I also have to look
at both the developer and user experience, the user experience the
ultimate arbiter, and will use my method.

I'm glad there is a solution regardless. It would be nice if SQL
provided us with a virtual checkbox as I'm sure there'd be instances
where such a feature would be handy, not just within Access, but
displaying data in other front ends.