Combobox event listener - vba

I'm trying to use the solution given to this issue : Programmatically create event listener in VBA in my particular case :
I programmatically create comboboxes. What I would like to do is to programmatically create a single textbox with a precise label or several texboxes with as many labels next to the generated comboboxes depending on their values.
Here is the code I use to programmatically create those comboboxes :
Set listBoxB1 = Frame1.Controls.Add("Forms.ComboBox.1")
With listBoxB1
.Name = "list" & i
.Height = 15
.Width = 100
.Left = 70
.Top = 10 * i * 3
.AddItem "NUM"
.AddItem "LIST"
End With
So I want that when the user choses the value LIST, a single textbox is displayed next to the combobox with a label and when he or she uses the value NUM, 6 textboxes are created next to the combobox and aligned with it horizontally.
I actually want that the display changes automatically when the user changes the value of the combobox, it would be helpful if you can give some indications about that.
Can you please tell me how I can adapt the solution in the link above to my case, because I'm very new to VBA and don't exactly know how to do that, I have tried to implement the code given but failed.

It really is somewhat involved. This question discusses it: Assign on-click VBA function to a dynamically created button on Excel Userform . The accepted answer contains a trick that I have used many, many times. Create all the controls you will ever need ahead of time (there is only a finite amount of real estate on a form so in practice this will be a reasonably small number) and make them visible (or hide them) dynamically as you need them by controlling the .visible property. It is even possible to have 1 control sit on top of another in the design view with only 1 visible at run time. The visible one at run time will receive the events.

Related

Conditional visibility on MS Access Form - how to write in VBA or Macro

I have some very (very) basic MS Access knowledge. I'm trying to expand a bit into either VBA or macros as I'd like to put in some conditional visibility for my form. Basically, I have a checkbox. If it's checked, I want three or four more fields to pop up. Someone was able to point me to a basic VBA formula of if (this checkbox) = true then, (fieldx).visible = true, else, (fieldx).visibility = false, end if.
But I'm so new to this that I need more help and explanation. I tried putting it in but couldn't get it to work (no error message, just nothing changed at all).
Specific questions:
-Does this formula seem right?
-If I want multiple fields to be visible, can I combine them into one formula or should I create a new "if" statement for all?
-Where do I enter this code? I'm running the Office 365 version. For all I know, I'm not even putting it in the right place.
-How do I determine the field names to replace the (this checkbox) and (fieldx) in the formula? I tried entering the name I title the fields as, but with the spaces in the name I got an error message, and without the spaces nothing happened. Is there a specific naming convention to turn the field names into formula-appropriate titles? Is the name listed somewhere?
-Once I get the formula entered, is there something I have to do to get it to run/take effect? I tried saving, closing and reopening with no changes.
-Is this the best way to go about this?
If there's anything else you think I should know, I would love to hear it - but please keep in mind I'm very new to this so if you could keep it at "dummy" or ELI5 levels of explanation, I'd appreciate it!
after creating a form with 4 textboxes and a checkbox put the form in design mode (lower right corner has design mode selected, select a textbox and hit property sheet on the ribbon (or f4).
On the property sheet note the visible property. set the visible property to false. Now the textbox will be invisible when the form starts.
Tip you can select all the textboxes at the same time and set their properties all at once.
Every control on the form and even the various parts of the form have properties you can set and play with. For instance you can give any name you want to any control. On the property sheet go to the other tab and set the name property.
Tip: choose a name you you will remember without having to look it up and describes the controls function.
Next select the checkbox (not the checkbox's label). On the property sheet go to the event tab and select the on click event. hit the ellipsis and choose code builder. Access is Event Driven. We want the textboxes to appear when the checkbox is selected so we put that code in the checkbox click event.
after choosing code builder we get the code window where we can browse among all the events for all our forms. for now all you should see is something like:
Private Sub mycheckbox_Click()
End Sub
So insert some code to handle the checkboxes like:
Private Sub mycheckbox_Click()
If mycheckbox = True Then
txtbox1.Visible = True
txtbox2.Visible = True
txtbox3.Visible = True
txtbox4.Visible = True
Else
txtbox1.Visible = False
txtbox2.Visible = False
txtbox3.Visible = False
txtbox4.Visible = False
End If
End Sub
now when the checkbox is not checked no textboxes are visible.
but when the checkbox is checked they appear

Number Picker in Access / VBA

I am trying to put a number picker in a form in MS Access 2007. Here's an example of what I am trying to make:
I cannot find this in the default form controls, and have tried to make one myself using a listbox. Listboxes can be modified to look just like the number picker above, however the arrows only change the view, of the list, and not the actual selection (that is the value). For example, with the list box, if I have it range from 1 to 3, and default at 1 - when I change it to 2 via the arrows, the value of the listbox does not change, and is still one.
Does anyone know how to get a number picker in Access?
So you want to create a list of numbers and allow users to change the value displayed (AND stored as the control's value) using up and down arrows, such that they select the next or previous in the list.
I would suggest creating a text box and two buttons. Populate an array with the list of values. When a button is clicked it would:
A. Find the position in the array of any value already entered into the text box (eg loaded from a database)
B. Get the next or previous item from the array.
The array is populated as required (probably when the form is opened).
If you just need to allow the user to enter a whole integer number (ie a number spinner) you would do as follows:
Create one using a (locked) textbox and two buttons. Just add a textbox (name it something like txtValue) and two buttons (btnUp and btnDown), then add code like this to the Click event of those buttons:
Private Sub btnUp_Click()
Me.txtValue = Nz(Me.txtValue, 0) + 1
End Sub
Private Sub btnDown_Click()
Me.txtValue = Nz(Me.txtValue, 0) - 1
End Sub
You could add if statements to limit the data being entered
Or you can use a 3rd party control.
http://www.fmsinc.com/microsoftaccess/controls/components/spin-button/index.html
There are probably more, but be aware that using these sorts of controls in Access is unsupported, and there is no guarantee moving forward that they will work in Access. You're far better off using the native methods described earlier.

Combobox_Change function for combobox's created with .Controls.add function*

Let me start by saying that I have searched far and wide for hours before answering this question.
Situation (all working) -
User is to specify the number of apples in a basket
Example - user specifies 2 apples. This creates two pages within a multipage with comboboxes and textbox's.
The combobox's are populated with a database of apple names. The user chooses one.
Desired:
When a user chooses an apple from the combobox I would like the textbox's on that multipage to populate with the apples characteristics. In other words I need my code to fire any time a user selects an apple from this combobox. This is not a combobox created from the toolbar, so I cant seem to use "private sub Combobox_Change".
Below is the code that I use to create the combobox:
Set ComboBoxL = MultiPage1.Pages(pgCount).Controls.Add("Forms.combobox.1", _
"ComboBoxL" & pgCount)
With ComboBoxL
.Top = 1 * FromTop
.Left = LeftDist
.List = Sheets("TestLightList").Range("A1:A100").Value
This is the code that I use to pull the value into the textbox, it works in testing (just running it in another part of the code) but doesnt work when needed because I dont know how to tell VBA to fire it off when the user selects an item from the combobox above
userform2!textboxC1.Value = Application.index(Range("'TestLightList'!$A$2:$E$500"), _
Application.Match(userform2!ComboBoxL1.Value, Range( _
"'TestLightList'!$A$2:$A$500"), 0), 2)
Note that in this snippit of code im working off of the first combobox. The formula creates a series of them in numerical order.
Thank you!

How to pass the value (true/false) of checkboxes created run-time on a userform

I am trying to create a number of checkboxes on a UserForm after reading all the non-empty rows in an excel sheet. That means these checkboxes have to be created in run-time. I also want to put a CommandButton on the UserForm. What I want is that once the user presses this CommandButton, the code should be able to send to a subroutine the information on which checkboxes are checked and what their names are.
Could anyone help me with problem.
Instead of trying to dynamically create checkboxes on a userform (which I'm not even sure is possible) consider using a listbox with a ListStyle of fmListStyleOption and with MultiSelect turned on with fmMultiSelectMulti
Populate the Listbox using the AddItem Method
For i = 0 to 9
Me.lbxDivisions.AddItem
Me.lbxDivisions.List(i) = "Checkbox " & format(i)
Next i
And determine which items are checked via the Selected property:
For i = 0 To lbxDivisions.ListCount - 1
If lbxDivisions.Selected(i) Then
MsgBox "Item " & Format(i) & " is selected and has value " & lbxDivisions.List(i)
End If
Next i
You can programmatically add form controls (check boxes, listboxes, etc) to userforms. From within the form's code module,
Me.Controls.Add "Forms.CheckBox.1", "CheckBox1", True)
From any other code module, just reference the form by name, instead of Me, e.g.,
MyUserForm.Controls.Add "Forms.CheckBox.1", "CheckBox1", True)
Personally I would favor using a more dynamic control (like a list box or combobox) unless your task absolutely requires you to use check boxes. With dynamic controls you need to manage their size, location relative to other controls, resize the userform (if necessary), etc., and although it's kind of possible to add event handling to these controls (see here), that's really limited (e.g., if you expect you need to add 10 check boxes each of which do a different thing, you need to pre-write 10 check box subroutines. If you create 11 check boxes but only 10 pre-written routines, the last check box won't do anything. It would be easier to just create all the check boxes when designing the form, and then programmatically set them to Visible=True or Visible=False as circumstance requires.
So, I'd favor using a dynamic control like a listbox or combobox, but it is possible to add form controls like checkboxes at run-time, if you must.

Multiple Text Box and Lookups

I am currently trying to improve on an Access Database VBA that I have inherited from my predecessor at work. I have come unstuck on a particular form.
I have a form that at the moment is just a large form containing 32 individual textbox, with the same code behind each but it is the same code repeated for each textbox with just the references to the text box changing in each.
Private Sub Cand_No2_AfterUpdate()
Cand_Name2 = DLookup("[Name]", "[qryExamAbsences]", "[Cand_No] = Cand_No2")
End Sub
Then once the button is pressed
If Not IsNull([Cand_Name1]) Then
Rope = Rope & " Or Cand_No = " & [Cand_No1]
End If
(The If statement is contained in the button mousedown event.)
Occurs for each text box which then filters a report that is printed for office use. There are many problems with this but the major one I am trying to solve is that there is an upper limit to the number of entries, if I need to filter more than 32 I would need to delete the text and start again as it were.
Is there a way of combining all this into a single section of code which will create text boxes when needed?
EDIT.
I have found a way to give the impression to the user that the text boxes are being created after each entry which has improved the form from a user standpoint (no longer having 32 textboxes or having to scroll down to the Print Button.) however this still hasn't solved the issue of messy code as I have had to repeat the extra code for each box again, it also leaves me with the maximum of 32 entries still.
The new code is as follows:
If Not IsNull(Cand_Name1.value) Then
Cand_No2.Visible = True
Cand_Name2.Visible = True
cmdPrint.Top = 2500
cmdPrint.Left = 2500
DoCmd.MoveSize 1440, 2201, , 4000
Else
Cand_No2.Visible = False
Cand_Name2.Visible = False
cmdPrint.Top = 2000
DoCmd.MoveSize 1440, 2201, , 3500
End If
Essentially makes the next text box visible and moves the print button down to make room for the new text boxes. It also expands the window.
Could you not just have 2 text boxes, one for CAND_NO and another for CAND_NAME and then beside those two boxes place an ADD CAND_NO button.
Create a list box that would list every CAND_NO / CAND_NAME after they press the add button so they can see what they've added so far. Then loop through your list box to build your rope string or have your rope string either a global variable on the form and build it as they add numbers or stored in a hidden text box storing the value as they add numbers if you don't like global.