I’m developing a DB application via MS Access 2010.
I have added an unbound, binary checkbox to a report with the purpose that a user can choose one of two record sources (queries), for two variations of the report.
The checkbox Control Source property is blank and the Triple State is set to No.
However, upon opening the report,
the checkbox is permanently greyed out, no matter haw many times it is clicked!
Also, upon each single click on the checkbox, my_checkbox_Click() fires twice with its value toggling between Null and True!
The Null value seems to be interpreted as False which might be OK if the event didn't double-fire on each single click.
How do I get my checkbox to both appear properly -- as a binary checkbox, toggling between yes and no -- and function correctly, firing _Click() only once per click?
If it's a known issue with no solution, which is the best button type as a workaround?
My code:
Private Sub Report_Load()
Debug.Print vbCrLf & "Report_Load"
Me.my_chk.Value = False
set_data_source
End Sub
Private Sub my_chk_Click()
Debug.Print vbCrLf & "my_chk_Click"
set_data_source
End Sub
Private Sub set_data_source()
Debug.Print vbCrLf & "set_data_source"
Debug.Print "Me.my_chk.Value", Me.my_chk.Value
Debug.Print "Me.my_chk.ControlSource ", Me.my_chk.ControlSource
Debug.Print "Me.my_chk.TripleState ", Me.my_chk.TripleState
Me.RecordSource = IIf(Me.my_chk.Value, "my_yes_qry", "my_no_qry")
Me.Requery
Debug.Print "Me.RecordSource", Me.RecordSource
End Sub
Immediate window:
Report_Load
set_data_source
Me.my_chk.Value False
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_no_qry
' click once on checkbox
my_chk_Click
set_data_source
Me.my_chk.Value Null
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_no_qry
my_chk_Click
set_data_source
Me.my_chk.Value -1
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_yes_qry
' click once on checkbox
my_chk_Click
set_data_source
Me.my_chk.Value Null
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_no_qry
my_chk_Click
set_data_source
Me.my_chk.Value -1
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_yes_qry
The only good news is that the Requery after a RecordSource changes does correctly (if all-too-briefly) affect the data.
Another thing, even though my checkbox doesn't have an AfterUpdate listed under Events, if I replace the above my_checkbox_Click() handler with
Private Sub my_chk_AfterUpdate()
Debug.Print vbCrLf & "my_chk_AfterUpdate"
set_data_source
End Sub
I get
Report_Load
set_data_source
Me.my_chk.Value False
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_no_qry
' click once on checkbox
my_chk_AfterUpdate
set_data_source
Me.my_chk.Value -1
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_yes_qry
' click once on checkbox
my_chk_AfterUpdate
set_data_source
Me.my_chk.Value -1
Me.my_chk.ControlSource
Me.my_chk.TripleState False
Me.RecordSource my_yes_qry
which, as you can see, doesn't work either because now, even though AfterUpdate fires once per click, the checkbox value doesn't change!
Over at access-programmers.co.uk/forums
there was a suggestion (regarding a form, not a report) to use fancy coding
Nz(Me.my_chk = True, False)
which I tried but it had no difference in outcome.
Are you sure a checkbox on a report can be checked as it can in a form? I'm not! But an interesting possibility can be found here.
In the case of a form, it's grayed out because it is unbound and the value isn't set. The solution is to make a form variable and set to that. When the form is loaded, set the variable to False and set the checkbox to the variable. In the AfterUpdate() event of the checkbox, use the value of the control to set the variable. Then run set_data_source. You will probably want to run set_data_source also when the form loads.
Option Explicit
Dim booSourceUsual as boolean
Private Sub MyForm_Load()
booSourceUsual = False
Me!my_chk.Value = booSourceUsual
Call set_data_source
End Sub
Private Sub my_chk_AfterUpdate()
booSourceUsual = Me!my_chk.Value
Call set_data_source
End Sub
Related
I have a form in MS Access with multiple checkboxes which I want to use to fill up one textbox. If one of the checkboxes gets unchecked, I want its value to be deleted from the textbox without deleting other values. I'm new at using Access and coding in VBA (been reading ebooks for the past 3 weeks) and although I've tried to do research online it's been difficult for me to find the right code.
This is what I have so far:
First code found
Private Sub cb_click()
If Me.cb1 = True Then
Me.txtComentarios.Value = "INACTIVO;"
Else
Me.txtComentarios.Value = Null
End If
End Sub
Second code found
Private Sub cb2_Click()
If Me.cb2 = -1 Then
Me.[txtComentarios] = [txtComentarios] & "DISCREPANCIA"
Else
Me.[txtComentarios] = ""
End If
Exit Sub
End Sub
Also I would like for the checkboxes to fill the textbox in the same order the chechboxes are displayed.
Ex.
cb1; cb2; cb3
If, cb2 gets unchecked and its value gets deleted, I should have "cb1; cb3" but if I re-check cb2 I should get "cb1; cb2; cb3" again.
I just hope someone could guide me in. Thank you in advance.
Luz
You don't need events for each checkbox. Just create one procedure, which creates full text depending on checkboxes state and puts this text to the textbox. To call this function after each click on checkbox set After Update property of all checkboxes to =MyFunctionToUpdateTextbox instead of [Event Procedure]
Private Function MyFunctionToUpdateTextbox()
Dim strText As String
If Me.cb1 = True Then
strText = strText & "INACTIVO;"
End If
If Me.cb2 = True Then
strText = strText & "DISCREPANCIA;"
End If
If Me.cb3 = True Then
strText = strText & "Text for cb3"
End If
Me.txtComentarios = strText
End Function
For various reasons, I want to set up a custom button on my forms to save the current record. I use a navigation form and want to trigger the same process (integrity-checks, user input etc.) whenever the entry is saved, thus whenever the user presses the "save"-button or switches to another form. The user will conditionally be asked to confirm the process and is thus able to cancel it as well.
Everything is running smoothly with one really odd and annoying exception: Whenever I click the save button on a new record and prompt a message within the "BeforeUpdate" event, I receive
RTE 3021 ("no current record")
Without the MsgBox, everything is fine. Even more strange:
When I trigger the save process by switching to another form using the navigation form (or simply press "outside" the form used for data entry), everything is fine as well.
Here is a minimalistic example (similar results with DoCmd.Save, Requery or acCmdSaveRecord):
Private Sub vt_save_Click()
Me.Dirty = False
End Sub
Private Form_BeforeUpdate(Cancel As Integer)
Cancel = True
MsgBox "Test"
End Sub
Any ideas? I simply can't wrap my head around that error.
You could maybe try to run a query using the values in the form while checking if the record exists or not.
Is there a primary key on the table? if so, the primary key will be your focal point.
Private Sub vt_Save_Click()
dim rst as DAO>Recordset
Dim strSQL as String
Dim strID as string
strID = me.YourPrimaryKeyField
strSQL = "SELECT * " & _
"FROM YourTableName " & _
"WHERE (((YourTableName.YourFieldName) =" & me.PrimaryKeyField & "));"
set rst = currentdb.openrecordset(strsql)
if rst.recordcount = 0 then
currentdb.execute "INSERT INTO YourTableName ( List All Fields to Add ) " & _
"SELECT List All Field controls with values to add;"
End IF
'Anything else you want the code to do from here
EndCode:
If not rst is nothing then
rst.close
set rst = nothing
End IF
End Sub
Repeat this process for the Form_LostFocus() event. If you want to make it easier, make this code a module and call within both event triggers on your form.
If this doesn't work please let me know and I will be happy to further assist.
The most straight forward and reasonable solution is to use an Error Handler - which I ignored so far tenaciously.
Private Sub save_Click()
On Error GoTo Err_Handler
Me.Dirty = False
Exit_Here:
Exit Sub
Err_Handler:
If Err.Number = 2101 Then
'ignore or message
Else
MsgBox Err.Description
End If
Resume Exit_Here
End Sub
Never tried UserForm checkboxes before so I don't even know how to point to the Checkboxes in a Userform.
This is what I have at the moment....and I know, I know, it is completely wrong. Please help?
Private Sub Step1_Confirm_Click()
Dim i As Byte
Dim Done As Boolean
For i = 1 To 4
If Step1_(i).value = True Then
Done = True
End If
Next i
If Not Done = True Then
MsgBox "Please make sure you have done all"
End If
End Sub
Basically I have:
A Userform called IOSP_Acc_R_Approval_Step1
4 checkboxes called Step1_1; Step1_2; Step1_3; Step1_4
A button called Step1_Confirm
I want the button to show Error, if not all checkboxes are checked - meaning that all checkboxes have to be checked....(in case my English is too bad to convey my meaning)
Try the code below (explanations inside the code as comments):
Private Sub Step1_Confirm_Click()
Dim i As Long
Dim Ctrl As Control
' loop through all user_form control
For Each Ctrl In IOSP_Acc_R_Approval.Controls
If TypeName(Ctrl) = "CheckBox" Then ' check if control type is Check-Box
If Ctrl.Value = True Then ' check if check-box is checked
i = i + 1
End If
End If
Next Ctrl
If i < 4 Then ' not all 4 check-boxes are checked
MsgBox "Please make sure you have done all"
End If
End Sub
You can do this by:
assume that all checkboxes are checked by setting a flag to True
iterate the checkboxes and if one is not checked set the flag to False and exit
at the end of the loop, if all checkboxes were checked then the flag is still True
You can refer to the checkboxes dynamically by using the Me.Controls collection and pass in the name of the checkbox like "Step1_" & i.
Example code:
Option Explicit
Private Sub Step1_Confirm_Click()
Dim i As Long '<-- use Long, not Byte
Dim blnResult As Boolean
' set a flag to assume that it is true that all checkboxes are checked
blnResult = True
' get the value of each check box
For i = 1 To 4
If Me.Controls("Step1_" & i).Value = False Then
blnResult = False
Exit For '<-- skip loop if at least one box not checked
End If
Next i
' check the value of the flag
If blnResult = False Then
MsgBox "Please make sure you have done all"
Else
' all boxes checked ...
MsgBox "All checked"
End If
End Sub
Done=true
For i = 1 To 4
Done = Done*Step1_(i).value
Next i
if done `then`
msgbox "All checkboxes are checked"
end if
I have the below VBA code in access to enable/disable a text box.
When the code is executed the tonnes textbox remains disabled.
Am I missing an additional property?
Private Sub EnableTonnes()
Dim sCode As String
sCode ="xx"
' set default values for tonnes enabled and locked properties
Tonnes.enabled = False
Tonnes.Locked = True
If sCode = "xx" Then
' enable tonnes field
Tonnes.enabled = True
Tonnes.Locked = False
End If
End Sub
Your code looks ok. TextBox properties are set in form design mode and can only be permanently changed in form design mode. You do some sophisticated coding to open the form in design mode, change the properties and then save the form... or do it manually. You will always be able to use your code to control those properties at runtime.
Option Compare Database
Option Explicit
Private Sub cmdGo_Click()
Dim sCode As String
sCode = "xx"
' set default values for tonnes enabled and locked properties
txtTonnes.Enabled = False
txtTonnes.Locked = True
If sCode = "xx" Then
' enable tonnes field
txtTonnes.Enabled = True
txtTonnes.Locked = False
End If
MsgBox txtTonnes.Name & " Enabled status is " & txtTonnes.Enabled
MsgBox txtTonnes.Name & " Locked status is " & txtTonnes.Locked
End Sub
Private Sub Form_Load()
MsgBox txtTonnes.Name & " Enabled status is " & txtTonnes.Enabled
MsgBox txtTonnes.Name & " Locked status is " & txtTonnes.Locked
End Sub
Is there a way to pass a checkbox value from a userform? I've seen it done when the checkbox is on the worksheet but I haven't been able to get it to work when it comes from my userform.
I have several repeating if statements and the only difference between them is the name of the checkbox. I'm sure there's a simple fix that I just haven't found yet. Any help is appreciated.
Edit: included code
If LockboxCheckBox.Value = True Then
If IsEmpty(wsInput.Cells(emptyRow, productCol)) Then
wsInput.Cells(emptyRow, productCol).Value = LockboxCheckBox.Caption
Else: wsInput.Cells(emptyRow, productCol).Value = wsInput.Cells(emptyRow, productCol).Value & ", " & LockboxCheckBox.Caption
End If
End If
I want to make this a small subroutine and need to pass the checkbox.value as well as the checkbox.caption to it when I call it.
The following code example demonstrates how to pass a Checkbox control on a UserForm to another procedure, get the checkbox's value and caption, and do something with them.
Note that I choose to pass the checkbox, rather than the value and caption as two parameters, as this will reduce the amount of code you need to type.
Private Sub btnOK_Click()
Dim chk As MSForms.CheckBox
Set chk = Me.CheckBox1
ProcessCheckBox chk
ProcessCheckBox Me.CheckBox2
End Sub
Sub ProcessCheckBox(chk As MSForms.CheckBox)
Dim chkVal As Boolean
Dim chkCap As String
chkVal = chk.value
chkCap = chk.Caption
If chkVal = True Then
Debug.Print chkCap & " is true"
Else
Debug.Print chkCap & " is false"
End If
End Sub