Can someone help me with the validation of a checkbox in an Access form? - vba

I have problems with the validation of an Access form, and more precisely with a checkbox, since Access tells me that the object does not support that property or that method.
My code to carry out the verification, evaluates each control of the form, and if its value is empty or null, it paints the background color of it orange, and if it is corrected, it returns it to white.
Since the checkbox object does not share the BackColor property with the textbox or combobox, I tried to use BorderColor, which is common to all three.
My code:
Private Sub ValidarCampos()
Dim FormActivo As Form
Dim control As control
Set FormActivo = Forms(0)
ValidaCampos = True
For Each control In FormActivo.Controls
If (control.ControlType = 109 Or control.ControlType = 111 Or control.ControlType = 106) And control.Visible = True And control.Enabled = True Then 'Revisar el 106 (checkbox)
If control.ControlType = 106 Then
valor = control.TripleState
Else
valor = Trim(control.Value)
End If
Debug.Print valor
'If (valor = "" Or IsNull(valor)) And control.Tag = "*" Then
If (valor = "" Or IsNull(valor)) Then
control.BorderColor = VBA.RGB(237, 125, 49)
'MsgBox "No puede dejar nulo el campo " & control.Name, vbInformation, tiTulo
If FormActivo.Controls(control.Name).Enabled = True Then
FormActivo.Controls(control.Name).SetFocus
End If
ValidaCampos = False
'Exit Function
Exit Sub
Else
control.BackColor = VBA.vbWhite
End If
End If
Next
End Sub
Clarification:
The problem occurs with the "Enabled" property of the checkbox
When it evaluates to the checkbox, Access tells me that the object does not support that property or method.

I've had trouble with the access checkbox not working properly twice before. You can get around the checkbox by turning a label into a synthetic checkbox. This also gets you the back color property. I got the outline of the solution from Fred here: http://www.justskins.com/forums/changing-check-box-colour-171415.html
put a label and a checkbox on a form. set the checkbox visible property to false. resize the label and set the label.border property to solid to make the label look like a checkbox. Set the label font to wingdings. then here is the code.
'in form codebehind
Private Sub labelthatlookslikeacheckbox_Click()
If Me.invisiblecheckbox.Value = -1 Then
Me.invisiblecheckbox.Value = 0
Me.labelthatlookslikeacheckbox.Caption = ""
Else
If IsNull(Me.invisiblecheckbox.Value) Then
Me.invisiblecheckbox.Value = -1
Me.labelthatlookslikeacheckbox.Caption = Chr(254)
Else
Me.invisiblecheckbox.Value = Null
Me.labelthatlookslikeacheckbox.Caption = Chr(110)
End If
End If
Me.Refresh 'update display
End Sub
'in a module
Private Sub ValidarCampos()
Dim FormActivo As Form
Dim control As control
Set FormActivo = Forms(0)
ValidaCampos = True
For Each control In FormActivo.Controls
If (control.ControlType = acCheckBox) Then
If (control.Name = "invisiblecheckbox") And IsNull(control.Value) Then
FormActivo.Controls("labelthatlookslikeacheckbox").BackColor = VBA.RGB(237, 125, 49)
Else
FormActivo.Controls("labelthatlookslikeacheckbox").BackColor = vbWhite
End If
'HANDLE OTHER CHECKBOXES HERE
'if going generic one solution is to use a checkbox and label naming convention then parse control.name
Else
If (control.ControlType = acTextBox Or control.ControlType = acComboBox) Then
'labels don't have an enabled control so we only test textboxes and comboboxes
If control.Visible = True And control.Enabled = True Then
valor = Trim(control.Value)
Debug.Print valor
If (valor = "" Or IsNull(valor)) Then
control.BackColor = VBA.RGB(237, 125, 49)
If FormActivo.Controls(control.Name).Enabled = True Then
FormActivo.Controls(control.Name).SetFocus
End If
ValidaCampos = False
Else
control.BackColor = VBA.vbWhite
End If
End If
End If
End If
Next 'control
End Sub
Top checkbox is the label:
Without Text highlighted :

Related

How to send focus to a text box of a VBA form during its initialization/activate event?

I have a VBA form in Corel. Behaving exactly like a similar one in Excel...
Initially, when the form initialize event used to contain only some lines of code, the simple ending line me.txtCsv.Setfocus used to send the focus on it. I mean, it appeared being in edit mode with the cursor blinking inside.
After a period of time, after the application became complex, I am not able to send the focus to the text box in discussion.
I know that Activate event goes last and I also have in it the line me.txtCsv.Setfocus. But without expected result. Inside the Initialization event code I inserted that line Debug.Print Me.ActiveControl.Name & " - 1", changing 1 in 2, 3 up to 6 in many places, including the last line and all the time the name of the text box in discussion (txtCsv) appears in Immediate Window.
So, the control in discussion is the activate one, but the cursor is not inside it when the form is loaded.
TabStop is set to True. I set the TabIndex to 0.
The control is enabled and not blocked. I have created a new simple form with three text boxes and it works well.
I mean the text box which I want to send the focus, has the focus when the form is loaded, keeping a similar code in its Initialize or Activate events.
I compared all properties of the two forms and all text box controls and they are the same...
When I send the focus from another control on the form, the text box in discussion receives it.
It does not receive the focus (anymore) only when the form is shown, the focus being sent by Initialize or Activate evens.
Events code:
Private Sub UserForm_Activate()
Me.txtCsv.SetFocus
End Sub
Private Sub UserForm_Initialize()
Dim P As Printer, i As Long, NrImp As Long, prDefault As String, strJustEngr As String
Dim Printers() As String, n As Long, s As String, boolFound As Boolean
Dim strEng As String, MEngr As Variant, m As Variant, el As Variant, defSize As String
Dim strDropbox As String
boolOpt = True: boolFound = False
Me.cbPrinters.Clear
If Me.chkNewStyle.Value = True Then boolNewStyle = True
prDefault = Application.Printers.Default.Name
strEng = GetSetting(ECA_K, ECA_set, ECA_Engr, "No settings...")
If strEng <> "No settings..." Then
boolSelectedEngravers = True ' only adding engraver is possible...
MEngr = Split(strEng, "|")
'Incarcare in combo:
Me.cbPrinters.Clear
For Each el In MEngr
m = Split(el, ":")
Me.cbPrinters.AddItem m(0)
If m(0) = prDefault Then
boolFound = True
defSize = m(1)
End If
Next
Me.cbPrinters.Value = Me.cbPrinters.List(0)
With Me.btChoosePrinters
.Caption = "Add an Engraver"
.ControlTipText = "Add another Engraver(must be installed)"
End With
Me.btEliminatePrinters.Enabled = True
Me.lblPrinters.Caption = "Engravers: "
Me.cbPrinters.ControlTipText = "Select Engraver to be used!"
Else
Printers = GetPrinterFullNames()
For n = LBound(Printers) To UBound(Printers)
Me.cbPrinters.AddItem Printers(n)
If Printers(n) = prDefault Then boolFound = True
Next n
boolSelectedEngravers = False
End If
Debug.Print Me.ActiveControl.Name & " - 1"
If boolFound Then
Me.cbPrinters.Value = prDefault
Else
Me.lblStatus.Caption = "The default printer (""" & prDefault & """) is not a laser Engraver..."
End If
If GetSetting(ECA_K, ECA_set, "LowRAM", "No settings...") <> "No settings..." Then
boolLowRAM = CBool(GetSetting(ECA_K, ECA_set, "LowRAM", "No settings..."))
End If
If boolLowRAM = True Then
Me.chkLowRAM.Value = True
Else
Me.chkLowRAM.Value = False
End If
Debug.Print Me.ActiveControl.Name & " - 2"
'Direct engrave setting:
Dim strDirectEngrave As String
strDirectEngrave = GetSetting(ECA_K, ECA_set, ECA_Direct_Engrave, "Nothing")
If strDirectEngrave <> "Nothing" Then
Me.chkDirectEngrave.Value = CBool(strDirectEngrave)
If CBool(strDirectEngrave) = True Then
boolDirectEngrave = True
Else
boolDirectEngrave = False
End If
End If
'_______________________________________
strJustEngr = GetSetting(ECA_K, ECA_set, ECA_Just_Engrave, "Nothing")
If strJustEngr <> "Nothing" Then
'Application.EventsEnabled = False
boolChangeEngr = True
Me.chkJustEngrave.Value = CBool(strJustEngr)
boolChangeEngr = False
'Application.EventsEnabled = True
If CBool(strJustEngr) = True Then
Me.chkDirectEngrave.Enabled = True
boolJustEngrave = True
Me.frLocFoldPath.Enabled = True
Else
Me.frLocFoldPath.Enabled = False
Me.chkDirectEngrave.Enabled = False
End If
End If
Debug.Print Me.ActiveControl.Name & " - 3"
If boolSelectedEngravers Then
Application.EventsEnabled = False
Me.btGo.ForeColor = RGB(45, 105, 7)
Me.txtCsv.BackColor = RGB(153, 255, 51)
Me.btGo.Enabled = False
Me.txtCsv.SetFocus
Application.EventsEnabled = True
End If
strDropbox = GetSetting(ECA_K, ECA_set, ECA_Dropbox, "No value")
If strDropbox <> "No value" Then
If CBool(strDropbox) = True Then
Me.chkDropbox.Value = True
End If
End If
AllRefresh
Me.chkCloseDoc.Value = True
Me.txtCsv.SetFocus
Debug.Print Me.ActiveControl.Name & " - 4"
End Sub
Private Sub AllRefresh()
Application.Optimization = False
Application.EventsEnabled = True
If Documents.Count > 0 Then
ActiveWindow.Refresh
ActiveDocument.PreserveSelection = True
End If
Application.Refresh
End Sub
Is there something else, crossing your mind, to be tested?
In the meantime I did some more tests, respectively:
I created a new project (.GMS file) and I imported the form in discussion.I started commenting all the Initialize event code, except the last two code lines.
It didn't set the focus! Commenting everything, letting only the Activate event code, it worked.
I started to un-comment lines in Initialize event code and I found a line not allowing the focus to be sent to that text box.
Setting the value of the combo: Me.cbPrinters.Value = Me.cbPrinters.List(0), moving it in the Activate event code, before the part pointing to txtCSV, worked well.
Now, I tried to do the same in the original form and it does not work...
The above question has been solved by Disabling followed by Enabling of the text box in discussion, but only doing that in Form Activate event. It did not work in Initialize event...
Private Sub UserForm_Activate()
Me.txtCsv.Disable: Me.txtCsv.Enable
Me.txtCsv.SetFocus
End Sub

VBA - Argument not optional error ! Trying to set the enabled property of a Listbox based on the Selected Value of another Listbox

I have a form named as NoForm which has two List-boxes named as No_ListBox1 and No_ListBox4.
By Default, the Property of No_ListBox4 is set to be enabled = false
when No_ListBox1 value is "yes", , the Property of No_ListBox4 is set to be enabled = true
When it is "No", it stays as enabled = false. But here comes the Problem, I am not able to deselect the selected values in No_ListBox4 when the user changes it back to "No" in No_ListBox1.
Kindly Share your thoughts.
But,
This is the Code,
Private Sub No_ListBox1_Click()
SelectNext = NoForm.No_ListBox1.Value
If SelectNext = "Yes" Then
NoForm.No_ListBox4.Enabled = True
End If
If SelectNext = "No" Then
NoForm.No_ListBox4.Enabled = False
If NoForm.No_ListBox4.Selected = True Then
NoForm.No_ListBox4.Selected = False
End If
End If
Try this:
Private Sub No_ListBox1_Click()
With Me
If .No_ListBox1.Value = "Yes" Then
.No_ListBox4.Enabled = True
Else
With .No_ListBox4
.Selected(.ListIndex) = False
.Enabled = False
End With
End If
End With
End Sub
The solution is to flip your logic around. Deselect the items first, then disable the control.

How to create expandable/retractable form MS Access 2013 VBA?

I am creating a data entry form for one of my database tables. For one of the sections, I have the text field with ONLY the caption: "Description 1" showing. If the Description 1 textbox is filled out by the user, I want it to show the Description 2 textbox. If the user fills out the Description 2 textbox, the Description 3 textbox will show up and so on up to 10 Description textboxes. Is there a way to hide the extra text boxes kind of like when you fill out the information while creating a macro? For example when you click Create --> Macro, there is only a dropdown box for you to select an action. If you choose Open Form and hit enter, 6 more text boxes with captions appear.
Is there a way to get that kind of functionality in a form? Also, in the Macro builder, it dynamically rearranges the page for you, can this also be done with the form?
Follow these steps:
Mark the visible property as false
Add OnChange event for each textbox.
Write the VBA code to determine if the next control will be showed or hide. Note, the Me!FormControlItem.Text is accessible only if the control is focused.
There is the 3 functions for each control.
Private Sub text1_Change()
If Not Trim(Me!text1.Text) = "" Then
Me!Text2.Visible = True
Me!Label2.Visible = True
ElseIf Not Trim(Me!Text2) = "" Then
Me!Text2.Visible = True
Me!Label2.Visible = True
Else
Me!Text2.Visible = False
Me!Label2.Visible = False
End If
End Sub
Private Sub Text2_Change()
If Not Trim(Me!Text2.Text) = "" Then
Me!Text3.Visible = True
Me!Label3.Visible = True
ElseIf Not Trim(Me!Text3) = "" Then
Me!Text3.Visible = True
Me!Label3.Visible = True
Else
Me!Text3.Visible = False
Me!Label3.Visible = False
End If
End Sub
Private Sub Text3_Change()
If Not Trim(Me!Text3.Text) = "" Then
Me!Text4.Visible = True
Me!Label4.Visible = True
ElseIf Not Trim(Me!Text4) = "" Then
Me!Text4.Visible = True
Me!Label4.Visible = True
Else
Me!Text4.Visible = False
Me!Label4.Visible = False
End If
End Sub
Enjoy!

Clear fields from a form except 1 object (access VBA)

I have a form in Access and i try to make a button that clears the total form.
it works but not for 1 field because in the database that field has NOT NULL given to it.
this is my form: http://i.stack.imgur.com/j7EOI.png
When i pres on the button [Leeg Velden]
then this vba code will be running:
Private Sub btnLeegVelden_Click()
Dim object As Object
For Each object In Screen.ActiveForm
If Name(object) = "ibvoorraad" Then
Me.ibvoorraad.Value = "0"
Else
If TypeName(object) = "TextBox" Then object.Value = ""
End If
Next object
btnArtikelToevoegen.Enabled = True
End Sub
How can i add some code that will clear all the field but in the field "Voorraad" it needs to set it to 0 instead of empty.
You need to access the .Name property of the object in your if statement rather than using the function Name().
Try this instead:
Private Sub btnLeegVelden_Click()
Dim object As Object
For Each object In Screen.ActiveForm
If object.Name = "ibvoorraad" Then
Me.ibvoorraad.Value = "0"
Else
If TypeName(object) = "TextBox" Then object.Value = ""
End If
Next object
btnArtikelToevoegen.Enabled = True
End Sub
Here is what I would do: reference as Controls:
Dim ctl As Control
For Each ctl In Me.Controls
If ctl.Name = "ibvoorraad" Then
Me.ibvoorraad.Value = "0"
Else
If ctl.ControlType = acTextBox Then
ctl = ""
End If
End If
Next ctl
btnArtikelToevoegen.Enabled = True
I would set a default value for any controls that cannot be null then use the following code
Dim ctL As Access.Control
For Each ctL In Me.Controls
If ctL.ControlType = acTextBox Then
ctL= ctL.DefaultValue
End If
Next

Creating Permanent Textbox on an Excel Userform

So I am creating a tool and user guide for my client. I am attempting to integrate the user guide into Excel in the form of a Userform. My first attempt was to insert these as images of the word document, however, if the user guide is ever updated that could mean a lot of work for anyone to update the userform as well. So I was looking to see if I could have a button for the user to click that would clear the userform and recreate it dynamically any time the User Guide is updated. My issue is that when I run my code the textboxes I create which contain the text from the user guide disappear after the userform is closed.
Do I have to have a set number of textboxes or can this be dynamic in the case that the user ever adds a new section to the user guide? Can I create textboxes that stay on the userform once it is closed?
My code is below:
For i = 1 To totPara
If wrdDoc.Paragraphs(i).Style = wrdDoc.Styles("Heading 1") Or wrdDoc.Paragraphs(i).Style = wrdDoc.Styles("Heading 2") Then
headerCtr = headerCtr + 1
If headerCtr = 2 Then
labelCtr = labelCtr + 1
Set tempTxt = Nothing
Set tempTxt = userGuide.Controls.Add("Forms.TextBox.1", "Test" & labelCtr, True)
With tempTxt
.Height = 276
.Width = 288
.Top = 54
.Left = 42
.MultiLine = True
End With
tempTxt.Text = wrdDoc.Paragraphs(i).Range.Text & Chr(13)
ElseIf headerCtr > 2 Then
Exit For
End If
ElseIf labelCtr <> 0 Then
tempTxt.Text = tempTxt.Text & wrdDoc.Paragraphs(i).Range.Text & Chr(13)
End If
Next i
For right now I set it to create a new textbox only when headerCtr is equal to 2 for testing but eventually I would like to create a new textbox for each of the 9 sections.
Thank you in advance for any help.
You have the option Hide the userform instead of Close the userform. When it is hidden the textboxes can still be accessed from the calling form.
Dim frm1 As frmMainInput
Set frm1 = New frmMainInput
frm1.tbProjectNumber.Value = iProject_Number
frm1.txtDocsInUse.Text = sDocsInUse
frm1.Show
If frm1.Proceed = False Then
GoTo Local_Exit
End If
iProject_Number = CInt(frm1.tbProjectNumber.Value)
Eventually call frm.close and set frm = Nothing
In the UserForm:
Private Sub cmdCancel_Click()
Proceed = False
Me.Hide
End Sub
Private Sub cmdOK_Click()
Proceed = True
Me.Hide
End Sub
No clue about the refreshing images etc.c