combobox addItem strangely not working - remains blank - vba

very simple Problem:
Dim myForm As Object
Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3)
Set MyComboBox = myForm.Designer.Controls.Add("Forms.ComboBox.1")
With MyComboBox
.Left = 100
.Top = 20 + x * 10
.Height = 16
.Width = 100
For Each col In fields
.AddItem col
Next
End With
I can clearly print out the values in fields (which is a variant), but somehow the Combobox remains blank... Any ideas? I'm wasting way to much time on this...
thanks for your help

Related

Adding OnChange event to dynamically created vba form controls

I have a form in excel, where I need to have dynamically created Comboboxes and Listboxes. So, the idea is, each listbox is linked to combobox. The first ones are set up by default, and user can press the "Add" button, if he needs to add another combo + list boxes. So the code for "Add" button is following:
Private Sub AddCountry_Click()
aaa = "a"
Set comb = Controls.Add("Forms.Combobox.1", "CountryList" & Val(CountryLabel.Caption) + 1)
With comb
.Top = CountryList1.Top
.Width = CountryList1.Width
.Height = CountryList1.Height
.Left = (CountryList1.Width + 3) * Val(CountryLabel.Caption) + CountryList1.Left
.AddItem ("--Choose country--")
For i = 3 To 20
.AddItem Worksheets("Countries").Range("B" & i).Value
Next i
.Text = "--Choose country--"
End With
Set listb = Controls.Add("Forms.Listbox.1", "Countries" & Val(CountryLabel.Caption) + 1)
With listb
.Top = Countries1.Top
.Width = Countries1.Width
.Height = Countries1.Height
.Left = (Countries1.Width + 3) * Val(CountryLabel.Caption) + Countries1.Left
.ColumnCount = 2
.MultiSelect = 1
End With
CountryLabel.Caption = Val(CountryLabel.Caption) + 1
End Sub
The idea is, that Comboboxes must will have names "CountryList" and a number, that is stored in invisible label (to which is added +1 every time the button is bressed), so it will be CountryList1, CountryList2, etc. Same for listboxes.
So the thing is, that comboboxes are made and values (country names) are added correctly. But I did not get, how to use them after it? The thing, that I need is to - when a combobox is changed (user selects different country), the list box below must be filled with certain values (different for each country).
I assume, the problem might be in defining the name for combo/list box. So is it possible to add dynamical names (CountryList1, CountryList2, etc) and then somehow add OnChange Events? Thanks in advance.
Here's an example for the ComboBox. You can base the listbox of of it, since the principle is the exact same.
First create a class named cComboBox and put this code in there:
Private WithEvents p_ComboBoxEvents As MSForms.ComboBox
Private Sub p_ComboBoxEvents_Change()
'Here you can handle the events.
End Sub
Public Property Let Box(value As MSForms.ComboBox)
Set p_ComboBoxEvents = value
End Property
Public Property Get Box() As MSForms.ComboBox
Set Box= p_ComboBoxEvents
End Property
Next, in your existing code, you can add this cComboBox and just put the Combobox you're adding already:
'Add the custom box!
Private customBox as cComboBox
Private Sub AddCountry_Click()
aaa = "a"
Set comb = Controls.Add("Forms.Combobox.1", "CountryList" & Val(CountryLabel.Caption) + 1)
With comb
.Top = CountryList1.Top
.Width = CountryList1.Width
.Height = CountryList1.Height
.Left = (CountryList1.Width + 3) * Val(CountryLabel.Caption) + CountryList1.Left
.AddItem ("--Choose country--")
For i = 3 To 20
.AddItem Worksheets("Countries").Range("B" & i).Value
Next i
.Text = "--Choose country--"
End With
Set customBox = New cComboBox
customBox.Box = comb
End Sub
Of course you might want to create an array of these so you can have as many as you want, regardless of how they're named. However: you'll see that if you change the added ComboBox value the p_ComboBoxEvents_Change will trigger.

Microsoft ActiveX Controls

Is there a way to change the index value of a ActiveX Button that inserted onto a spreadsheet. I currently have four buttons and two are hidden and two are visible. I would like to re-order the them to not have a large gap between objects. I have some VBA code that runs when the document is opened to ensure that they are the right size and location. Because it loops through the OLEObjects Collection; it will not matter what order they are in on the spreadsheet they will always appear with a gap because of the index value in the OLE Object collection. Below is the code:
Private Sub Workbook_Open()
Application.ErrorCheckingOptions.EvaluateToError = False
ActiveWorkbook.Worksheets("SITE").Activate
Dim button As OLEObject
Dim name As String, top As Integer
top = 15
For Each button In ActiveWorkbook.Worksheets("SITE").OLEObjects
Debug.Print button.name & " " & button.ZOrder
name = button.name
If button.OLEType = xlButtonOnly And InStr(name, "btn") = 1 Then
With button
.Height = 21.75
.Width = 174.75
.Left = 1114.5
.top = top
End With
top = top + 30
End If
Next button
End Sub
If you give them proper names with an integer code in it reflecting their intended position (e.g.: "btn...01", "btn...02",...) then you could try this code (sorry for not being able to format it as code by now):
Private Sub Workbook_Open()
Application.ErrorCheckingOptions.EvaluateToError = False
ActiveWorkbook.Worksheets("SITE").Activate
Dim button As OLEObject
Dim name As String
Dim btnRnk As Long
For Each button In ActiveWorkbook.Worksheets("SITE").OLEObjects
name = button.name
If button.OLEType = xlButtonOnly And InStr(name, "btn") = 1 Then
btnRnk = CLng(Right(name,2))
With button
.Height = 21.75
.Width = 174.75
.Left = 1114.5
.top = 15 + (btnRank - 1) * 30
End With
End If
Next button
End Sub

RE: Getting the name of the object onFocus & Adding Caption to a Button dynamically Created

I have written VBA code for Dynamically creating textboxes and buttons. The following is the code when I hit an "Add" button on the userform.
Dim oTxtBox As Control
Dim oBrwsBtn As Control
Dim oCaption As Control
Dim oTxtLen As Integer
oTxtLen1 = TextBox1.Width
oTxtBrth1 = TextBox1.Height
oTxtPos1 = TextBox1.Left
oButLen = CommandButton1.Width
oButBrth = CommandButton1.Height
oTxtLen2 = TextBox2.Width
oTxtBrth2 = TextBox2.Height
If i = Empty Then
i = 1
End If
Set oTxtBox = Me.Controls.Add("Forms.TextBox.1")
Set oBrwsBtn = Me.Controls.Add("Forms.CommandButton.1")
Set oCaption = Me.Controls.Add("Forms.TextBox.1")
With oTxtBox
.Left = oTxtPos1
.Top = oTxtBrth1 + 18 + (oTxtBrth + 18) * (i - 1)
.Width = oTxtLen1
.Height = oTxtBrth1
End With
With oBrwsBtn
.Left = oTxtPos1 + oTxtLen1 + 18
.Top = oTxtBrth1 + 18 + (oTxtBrth + 18) * (i - 1)
.Width = oButLen
.Height = oButBrth
End With
With oCaption
.Left = oTxtPos1 + oTxtLen1 + 18 + oButLen + 18
.Top = oTxtBrth1 + 18 + (oTxtBrth + 18) * (i - 1)
.Width = oTxtLen2
.Height = oTxtBrth2
End With
i = i + 1
Q1 Now How to Edit the caption of the browse Button which I create dynamically No method .Caption with oBrWsBtn
And Q2: How to get the value when the focus is changed
For example When I click on 'TextBox1' Object. A variable should assign itself with the name (i. e. var(str) = focus object name)
Thanks in advance
Q1: Why don't you try defining the control type more specifically and see if that permits you to use the .Caption method. Don't understand why it's not working now, but maybe the Control object type doesn't have the .Caption method because not all controls have captions.
Try:
'at the top of the sub:
Dim oBrwsBtn as CommandButton
'then later
Set oBrwsBtn = Me.Controls.Add("Forms.CommandButton.1")
Another option to consider would be to create these buttons and just have them be invisible until needed. But that assumes you don't actually have a good reason to create them dynamically, which you may have.
Q2: Use a control_AfterUpdate sub:
'Dim this wherever appropriate for scope. Could be in the afterupdate sub if that works.
dim TextBox1_Value as string
Private Sub TextBox1_AfterUpdate()
TextBox1_Value = TextBox1.value
End Sub

How to pass control values between userform events?

I'm struggling with a userform (called Label_Select) that I created.
I'm initializing the userform with some text boxes and check boxes and assigning some values in them.
Then I have a OK button on the userform that was created at design mode (I can create this button at runtime if that helps).
I need to use the text boxes and check boxes values in the code of the OK_Click, refer below.
Currently I get a "Sub or Function not defined" for the OK_Click sub.
How can I pass the text boxes and check boxes values between the userform initialize code and other click events of the userform?
Thank you for your responses
Private Sub UserForm_Initialize()
Dim LotBox(500) As MSForms.TextBox
Dim SensorCheckBox(500) As MSForms.CheckBox
For i = 1 To 4
For j = 1 To 4
k = i + (4 * j)
Set LotBox(k - 4) = Label_Select.Controls.Add("Forms.TextBox.1")
Set SensorCheckBox(k - 4) = Label_Select.Controls.Add("Forms.CheckBox.1")
With LotBox(k - 4)
.Top = 250 + i * 25
.Left = (j * 80) - 50
.Width = 40
.Height = 30
.Font.Size = 14
.Font.Name = "Calibri"
.SpecialEffect = fmSpecialEffectSunken
.Value = k
.AutoSize = True
End With
With SensorCheckBox(k - 4)
.Top = 246 + i * 25
.Left = (j * 80) - 8
.Height = 30
End With
If LotBox(k - 4).Value = " " Then
Label_Select.Controls.Remove LotBox(k - 4).Name
Label_Select.Controls.Remove SensorCheckBox(k - 4).Name
End If
Next j
Next i
End Sub
Private Sub OK_Click()
Worksheets("Sheet1").Cells(1,1)=LotBox(1).Value
Worksheets("Sheet1").Cells(2,1)=SensorCheckBox(1).Value
End Sub
Try making LotBox and SensorCheckBox public variables
You've declared LotBox and SensorCheckBox within UserForm_Initialize, so as soon as that sub ends they will both go out of scope.
Move them up to the top of the module as Global variables.

How to create Excel Controls (Combo boxes etc) using Visual Basic

I'm working on a project to create and email a spreadsheet that is created by an ASP.NET/Visual Basic web application.
The top of this spreadsheet is one large cell, in which sits a Drop Down List, two Text Boxes, a few Labels and a Checkbox.
How do I create and organise these controls using Visual Basic? The spreadsheet is being physically created and I can manipulate cells at the moment, but I do not know how to create those controls specifically.
If you want to create these controls programmatically then this code should get you going, Essentially add a control, position it and set those properties that you require.
Sub addControls()
With Sheets("Sheet1")
.Columns(1).ColumnWidth = 60
.Rows(1).RowHeight = 150
'label
Set addedLbl = .OLEObjects.Add(ClassType:="Forms.Label.1")
With addedLbl
.Left = 180
.Top = 25
.Width = 90
.Object.BackColor = &HC0C0FF
.Object.Caption = "A Coloured Label"
End With
'combobox
Set addedCmbo = .OLEObjects.Add(ClassType:="Forms.Combobox.1")
With addedCmbo
.Left = 180
.Top = 75
.Width = 90
.Height = 20
End With
'checkbox
Set addedChkBox = .OLEObjects.Add(ClassType:="Forms.CheckBox.1")
With addedChkBox
.Left = 25
.Top = 25
.Width = 90
.Height = 20
.Object.Caption = "A Checkbox"
.Object.SpecialEffect = 2
.Object.Value = False
End With
'textbox
Set addedTextBox = .OLEObjects.Add(ClassType:="Forms.TextBox.1")
With addedTextBox
.Left = 25
.Top = 75
.Width = 90
.Height = 50
.Object.WordWrap = True
.Object.MultiLine = True
.Object.SpecialEffect = 1
.Object.Text = "Some wrapped text in this raised textbox."
End With
End With
End Sub
If you want to add them manually then select the Developer Tab and in the Controls group select Insert. You can then add controls to the worksheet. I have used ActiveX controls. Then right-click the control to list its Properties.