Adding multiple userform controls at runtime - vba

I have created a userform with a static label to instruct the user to check certain part numbers. The form will also have a static button to submit the input. However, I need the checkboxes to be made at runtime since it won't be certain how many checkboxes there will be every time the form is shown. There would be a max of twelve boxes, but most of the time only one or two boxes would be needed and I'd prefer to show only what's needed instead of having blank checkboxes. I've made a for loop to add the boxes.
Currently I can add one checkbox to the form, but in the record I'm working with there are supposed to be three. Everything that I am seeing online about dynamically adding controls mainly pertains to adding events to the controls, but I don't need events, just the controls. Can anyone see what I need to add/change in my code:
Private WithEvents chkbox As MSForms.CheckBox
Private Sub UserForm_Activate()
For i = 1 To 12
If PNArray(i) Like "A*" And ChangeArray(i) = "New Part Number:" Then
With Me.Controls
Set chkbox = .Add("Forms.checkbox.1", "chkbox" & i, True)
With chkbox
.Width = 108
.Height = 18
.Top = 30 * i
.Left = 54
.Caption = PNArray(i)
End With
End With
End If
Next i
End Sub
Thanks

After some researching, the problem is .Top=30*i. You multiply always by index of array, when you want all checkboxes same distance. You need another variable to do that. Try like this:
Dim ZZ As Byte ' count of checkboxes
ZZ = 0
For i = 1 To 12
If PNArray(i) Like "A*" And ChangeArray(i) = "New Part Number:" Then
ZZ = ZZ + 1 'we increase count of checkboxes
With Me.Controls
Set chkbox = .Add("Forms.checkbox.1", "chkbox" & i, True)
With chkbox
.Width = 108
.Height = 18
.Top = 30 * ZZ 'we position the chekbox according to its rank (first one, second one, third one, and so on).
.Left = 54
.Caption = PNArray(i)
End With
End With
End If
Next i
With this code, it does not matter how many checkboxes you have. It will add them in the right position, in a "podium" style

Related

VBa - Userform show same combobox on two pages

So I have a multipage where I want the same button to show on both pages. I could place it outside but the border from the multipage is so ugly so I tried to place everything on the pages. Unfortunately you can't name the items (such as the combobox) with the same name. Is there a workaround to remove the borders and just show the page names or have the same name on the item on two pages?
Had some fun with this goal.
Consider this UserForm in Editor with TabStrip, 2 frames and some other controls.
Frames are named from Frame0, Frame1, etc.
Assuming the Frame0 is the location reference and first to display when UserForm is displayed, code below will be what you want.
Code:
Option Explicit
Private Sub TabStrip1_Change()
Dim i As Long, lActiveTabIndex As Long
lActiveTabIndex = Me.TabStrip1.Value
For i = 0 To Me.TabStrip1.Tabs.Count - 1
Me.Controls("Frame" & i).Visible = (i = lActiveTabIndex)
Next i
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
With Me
.Height = 288 ' Adjust to your desired height
' Align all FrameX top/left to same as Frame0, delete Caption and SpecialEffect
For i = 0 To Me.TabStrip1.Tabs.Count - 1
With Me.Controls("Frame" & i)
.Top = Me.Frame0.Top
.Left = Me.Frame0.Left
.Caption = ""
.SpecialEffect = fmSpecialEffectFlat
End With
Next i
End With
' Ensure frame for first tab is displayed
TabStrip1_Change
End Sub
Userform first load (didn't save screenshot, neither the workbook, sorry).
Next tab clicked:

Create ComboBox's and AddItems to them all within the VBA code

I need to create ComboBox's and then AddItems to each ComboBox. This will all be done to a userform. I need to do this entirely within the VBA code, this is because each time the userform is opened new information will be shown.
this is what I have so far:
Private Sub UserForm_Initialize()
for i = 1 to size
Set CmbBX = Me.Controls.Add("Forms.ComboBox.1")
CmbBX.Top = ((90 * i) - 18) + 12 + 20
CmbBX.Left = 30
CmbBX.Text = "Please select an item from the drop down"
CmbBX.TextAlign = fmTextAlignCenter
CmbBX.Width = 324
CmbBX.Visible = False
CmbBX.Name = "ComBox2" & i
Next
end sub
the problem is, once each ComboBox is created its like its name isnt there. I cannot referance the combobox. this is what I have tried:
ComBox21.AddItems "Test1"
ComBox22.AddItems "Test2"
And it errors out. When I look at the UserForms function bar at the top of the screen (where I would usually select ComBox22_Change() for example), It shows that no ComboBoxes even exist!
Any Ideas on how to dynamically create and additems to comboboxes?
Thank you in advance
Here an sample of the code.
You need still to change it for you needs but this will be easy.
I have created a simple userform and one button to do test and it works fast.
To imput the comboboxes replace ".additem" with a loop to load each of them.
How to do that -- search in google
how to Populate a combobox with vba
You cannot refferance any controls on userform if they dont exist.
You need to search for them after creation and then modify them.
Example below with button code.
I think this should bring you to an idea how to manage this.
Option Explicit
Private Sub CommandButton1_Click()
Dim refControl As Control, frm As UserForm
Dim x
Set frm = Me
With Me
For Each x In Me.Controls
If TypeName(x) = "ComboBox" Then
Select Case x.Name
Case "cmbDemo3"
MsgBox "works!"
'here you can put your code
End Select
MsgBox x.Name
End If
Next x
End With
End Sub
Private Sub UserForm_Initialize()
Dim combobox_Control As Control
Dim i
For i = 0 To 5
Set combobox_Control = Controls.Add("forms.combobox.1")
With combobox_Control
.Name = "cmbDemo" & i
.Height = 20
.Width = 50
.Left = 10
.Top = 10 * i * 2
.AddItem "hihi" 'here you can add your input code
End With
Next i
End Sub

Can't change dimensions of dynamically added listbox

I have been looking for hours now and I hope someone can help me here.
I am creating a form in vba where I want to dynamically add Listboxes. The listboxes are added, so that goes as planned. However, I can't seem to change the width and heigth of the listbox. All other things are being changed. This is my code:
Dim lb As MSForms.ListBox
Set lb = Me.controls.add("Forms.Listbox.1")
With lb
.ColumnCount = 4
.Left = 180
.Top = 16
.MultiSelect = 1
.Height = 270
.Width = 665
End with
The other thing that I noticed is that Heigth and Width aren't in the property list of the ListBox. Could it be that I use the wrong ListBox type?
EDIT: It get's stranger. When I go through the code line by line, it functions normally and the ListBox size is as I want it.
Try this may be
Me.Controls("Forms.Listbox.1").IntegralHeight = False
or
lb.IntegralHeight = False

Immediate Box (Debug window) Display Separately

I am really sorry if this is a silly question. I would like to display a message box similar to the Immediate window that will sit "always on top" and scroll a countdown while not interrupting the VBA program.
I am essentially crunching numbers for 40,000 rows and each run takes about 15 minutes. I don't know if it's still running or when the current VBA code will complete.
Does anyone have suggestions?
Use the status bar:
Application.StatusBar = "Row " & rowNum & " of " & rowCount
At the end, to clear the status bar:
Application.StatusBar = False
You can do it by displaying modeless user form. Below is an example how to do this.
In order to make this example working properly you need to add new, empty UserForm to your project and change it name to frmProgress.
Sub test()
Dim form As frmProgress
Dim lblProgress As Object
Dim i As Long
'-------------------------------------------------
'Create an instance of user form and show it modeless on the screen.
Set form = New frmProgress
With form
.Width = 200
.Height = 60
.Caption = "Progress"
'Add label for displaying text...
Set lblProgress = .Controls.Add("Forms.Label.1", "lblProgress")
'... and format it to meet your requirements.
With lblProgress
.Width = 200
.Height = 60
.TextAlign = fmTextAlignCenter
.Font.Size = 12
.Top = 6
End With
Call .Show(vbModeless)
End With
For i = 1 To 100000
'(Some code ...)
DoEvents
'Here the new text is inserted on the message box.
lblProgress.Caption = i
Next i
Call form.Hide
End Sub

The name of a frame in a loop

I want to add a Control in every for in my application. Let's say I have 5 frames...
I want to do someting like this:
Set cControl = Me!iooly&i.Controls.Add("Forms.Label.1", "str12" & i, True)
With cControl
.Caption = "1/2"
.Width = 20
.Height = 8
.Top = 10
.Left = 435
End With
i is a counting variable
the problems is that Me!iooly&i ... Can I do this operation when my frames have names la iooly1, iooly2, iooly3 and so on?
Your Me is presumably a form? This won’t work. Also, the Me!iooly&i syntax doesn’t work, this only works if your string is a constant.
You can use the Forms collection though:
Set cControl = Forms("iooly" & i).Controls.Add(…)
This is assuming that the form already exists. If it doesn’t, you need to first load it.