I have this code and it dynamically creates text boxes and labels based on the user input for text box number. But I am getting
424 error
I tried to debug using F8.
I will have a column(dynamically updated) using which the labels have to be created and the count of the column items are the number of textboxes (will replace the input box with count of the column.)
Dim number As Long
Private Sub UserForm_Initialize()
Dim i As Long
number = InputBox("enter the number")
Dim txtB1 As Control
For i = 1 To number
Set txtB1 = Controls.Add(“Forms.TextBox1”)
With txtB1
.Name = “txtBox” & i
.Height = 20
.Width = 50
.Left = 70
.Top = 20 * i * 1
End With
Next i
Dim lblL1 As Control
For i = 1 To number
Set lblL1 = Controls.Add(“Forms.Label1”)
With lblL1
.Caption = “Label” & i
.Name = “lbl” & i
.Height = 20
.Width = 50
.Left = 20
.Top = 20 * i * 1
End With
Next i
Dim q As Long
For q = 1 To number
Controls(“lbl” & q) = Cells(1, q)
Next q
End Sub
Private Sub CommandButton1_Click()
Dim p As Long
Dim erow As Long
erow = "Sheet3!A2:A" & Range("A" & Rows.Count).End(xlUp).Row
For p = 1 To number
Cells(erow, p) = Controls(“txtBox” & p).Text
Next p
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
424 error is showing problem with this line
Set txtB1 = Controls.Add(“Forms.TextBox1”)
Thanks in advance
As mentioned already, the correct string to create a textbox on the fly is this:
Forms.TextBox.1
Notice the additional period .. See here for reference.
Set txtB1 = Controls.Add("Forms.TextBox.1")
To wrap up the other points made in the comments too:
You can add an explicit Me to make it even more clear where the controls live, i.e. Me.Controls(...). But excluding it will always implicitly link to the correct userform.
Just be careful that you use " rather than “
Related
I have tried #DaveShaw code, for events on runtime for checkboxes, is click not an valid method for checkbox? It never get into the method checkBoxEvent_click
Dim CheckBoxArray() As New ClassEvents
for i=0 to 10
Set cTemp = MOM.Frame_MOM_MOM.Controls.Add("Forms.CheckBox.1")
With cTemp
.Top = HeaderOffset + RowOffset + i * 25 'your top pos
.Visible = True
.Left = 30 'your left pos
.Width = widthOfLabel 'your width
.Name = Replace(keyArrays(i, 1), " ", "_")
.Caption = keyArrays(i, 1) 'your caption ,
End With
ReDim Preserve CheckBoxArray(0 To i)
Set CheckBoxArray(i).checkBoxEvent = cTemp
next i
and my ClassEvents class looks like this:
Public WithEvents checkBoxEvent As MSForms.checkBox
Private Sub checkBoxEvent_click()
MsgBox "halla" 'checkBox.Caption
End Sub
you have to keep Dim CheckBoxArray() As New ClassEvents at the very top of your userfom code pane, thus outside any of its subs/functions
furthermore use Option Explicit statement too
it becomes
Option Explicit
Dim CheckBoxArray() As New ClassEvents '<--| keep this line at the very top of your userform code pane
Private Sub UserForm_Initialize()
Dim i As Long
Dim cTemp As MSForms.CheckBox '<-- with "Option Explicit" you have to declare all your variables
For i = 0 To 10
Set cTemp = MOM.Frame_MOM_MOM.Controls.Add("Forms.CheckBox.1")
With cTemp
.Top = HeaderOffset + RowOffset + i * 25 'your top pos
.Visible = True
.Left = 30 'your left pos
.Width = widthOfLabel 'your width
.Name = Replace(keyArrays(i, 1), " ", "_")
.Caption = keyArrays(i, 1) 'your caption ,
End With
ReDim Preserve CheckBoxArray(0 To i)
Set CheckBoxArray(i).checkBoxEvent = cTemp
Next i
End Sub
furthermore, since you already know the dimension of your array, Dim it at the beginning and don't ReDim it at every iteration:
Option Explicit
Dim CheckBoxArray(0 To 10) As New ClassEvents '<--| keep this line at the very top of your userform code pane
Private Sub UserForm_Initialize()
Dim i As Long
Dim cTemp As MSForms.CheckBox '<-- with "Option Explicit" you have to declare all your variables
For i = 0 To 10
Set cTemp = MOM.Frame_MOM_MOM.Controls.Add("Forms.CheckBox.1")
With cTemp
.Top = HeaderOffset + RowOffset + i * 25 'your top pos
.Visible = True
.Left = 30 'your left pos
.Width = widthOfLabel 'your width
.Name = Replace(keyArrays(i, 1), " ", "_")
.Caption = keyArrays(i, 1) 'your caption ,
End With
Set CheckBoxArray(i).checkBoxEvent = cTemp
Next i
End Sub
First of all: I am a beginner on VBA and I don't have a clue about how UserForms works.
That said I am trying to assing code to 3 dynamically created CommandButtons.
After some research come across this page and I just wrote a code to write the codes of the buttons. Problem is, I need to distribute this Workbook so this approach is not good anymore.
I reaserched a lot (1, 2, 3, 4) and came across this post. I tried to do the example that #SiddharthRout did but I was not sucessfull. I tried to understand how the ClassModule works but I couldn't (1, 2). I think a code just exactly the one #SiddharthRout would solve my problem but I can't manage to make it work on a normal module.
Long story short: I need a code to assing the codes to the CommandButtons without using extensibility (code that writes code).
EDIT
I want to create these buttons on a normal Sheet, not on a UserForm.
Read this:
http://scriptorium.serve-it.nl/view.php?sid=13
Sub MakeForm()
Dim TempForm As Object ' VBComponent
Dim FormName As String
Dim NewButton As MSForms.CommandButton
Dim TextLocation As Integer
' ** Additional variable
Dim X As Integer
'Locks Excel spreadsheet and speeds up form processing
Application.VBE.MainWindow.Visible = False
Application.ScreenUpdating = False
' Create the UserForm
Set TempForm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
'Set Properties for TempForm
With TempForm
.Properties("Caption") = "Temporary Form"
.Properties("Width") = 200
.Properties("Height") = 100
End With
FormName = TempForm.Name
' Add a CommandButton
Set NewButton = TempForm.Designer.Controls _
.Add("forms.CommandButton.1")
With NewButton
.Caption = "Click Me"
.Left = 60
.Top = 40
End With
' Add an event-hander sub for the CommandButton
With TempForm.CodeModule
' ** Add/change next 5 lines
' This code adds the commands/event handlers to the form
X = .CountOfLines
.InsertLines X + 1, "Sub CommandButton1_Click()"
.InsertLines X + 2, "MsgBox ""Hello!"""
.InsertLines X + 3, "Unload Me"
.InsertLines X + 4, "End Sub"
End With
' Show the form
VBA.UserForms.Add(FormName).Show
'
' Delete the form
ThisWorkbook.VBProject.VBComponents.Remove VBComponent:=TempForm
End Sub
This code from here:
Sub CreateButtons()
Dim arrNames As Variant
Dim arrCaptions As Variant
Dim Wkb As Workbook
Dim Wks As Worksheet
Dim NewBtn As OLEObject
Dim Code As String
Dim NextLine As Long
Dim LeftPos As Long
Dim Gap As Long
Dim i As Long
'The Workbook, where...
Set Wkb = ActiveWorkbook
'... the worksheet is, where the button will be created
' and code will be written.
Set Wks = Wkb.Worksheets(1)
'Commandbuttons' CODENAMES in array
arrNames = Array("cmbName1", "cmbName2", "cmbName3")
'Commandbuttons' captions in array
arrCaptions = Array("First Task", "Second Task", "Third Task")
'Button pos.
LeftPos = 100
Gap = 15
For i = LBound(arrNames) To UBound(arrNames)
'Add a CommandButton to worksheet
Set NewBtn = Wks.OLEObjects.Add(ClassType:="Forms.CommandButton.1")
'Set button's properties
With NewBtn
.Left = LeftPos
.Top = 5
.Width = 65
.Height = 30
.Name = arrNames(i)
.Object.Caption = arrCaptions(i)
.Object.Font.Size = 10
.Object.Font.Bold = True
.Object.Font.Name = "Times New Roman"
End With
'Add the event handler code
Code = "Sub " & NewBtn.Name & "_Click()" & vbCrLf
Code = Code & " MsgBox ""Hello...""" & vbCrLf
Code = Code & "End Sub"
'"Code" is a string
With Wkb.VBProject.VBComponents(Wks.CodeName).CodeModule
'Find last line in Codemodule
NextLine = .CountOfLines + 1
.InsertLines NextLine, Code
End With
'NEXT button's pos.
LeftPos = LeftPos + NewBtn.Width + Gap
Next i
End Sub
I have a number of controls that are added during runtime but I want to populate a combobox that is created during runtime based on answers received from the the other dynamic controls (its hard to word)!
I will try and explain via my code! During runtime the following controls are added to my userform:
Set cLabel = Me.Controls.Add("Forms.Label.1")
With cLabel
.Caption = "Do you study maths?"
.Font.Size = 8
.Font.Bold = False
.Font.Name = "Tahoma"
.Left = 38
.Top = mathslbl
.Width = 220
End With
Set cManagedOptionButtonYes= Me.Controls.Add("Forms.OptionButton.1")
With cManagedOptionButtonYes
.Caption = "Yes"
.Name = "fibreRingYes" & i
.GroupName = "fibreRing" & i
.Left = 160
.Top = mathsYes
.Width = 100
.Height = 15.75
End With
ReDim Preserve TextListBox(1 To i)
Set TextListBox(i).mathsGroupYes = cManagedOptionButtonYes
Set cStudentDropdown = Me.Controls.Add("Forms.Combobox.1")
With cStudentDropdown
.Name = "StudenDropdown1" & (i)
.Left = 50
.Top = studentCombobox
.Width = 130
.Height = 18
End With
ReDim Preserve TextListBox(1 To i)
Set TextListBox(i).studentdropdown1Group = cStudentDropdown
So during runtime the following controls are created, these controls ask whether the student studies maths or not and dependant on the answer the user gives the combobox will be populated. Below is the code that is trying to populate the combobox based on the users answer to the question:
Private Sub cManagedOptionButtonYes_Click()
Dim rng As Range
Dim cell As Range
Dim c As Range
With cStudentDropdown
Sheets("Students").Activate
For Each c In Sheets("Students").Range("C14:C86")
.AddItem c.Value
Next
End With
End Sub
When the code tries to execute i get the following error Object variable or with block variable not set and I can't figure out why this won't work for me!
assuming this is in the userform's code page:
Private Sub cManagedOptionButtonYes_Click()
'Dim rng As Range
'Dim cell As Range
Dim c As Range
With Me.cStudentDropdown 'Me. is not necessary, but i like to use it in order to have a dropdown menu with all functions and controls created on the form
'Sheets("Students").Activate
.clear
For Each c In Sheets("Students").Range("C14:C86")
'.AddItem c.Value 'should work (whatever its format i think)..., so try this :
'make sure no cell in the looping range returns a error result such as #N/A something like that
.additem
.list(.listcount-1) = c.value 'or try c.value2
Next
End With
End Sub
`
In my userform I ask the user how many listboxs they require and based on the number that the user enters the controls are dynamically created during run time. I want to be able to set the size of my userform based on the bottom position of the last dynamic control that was added to the userform. Below shows the code that I have written to do this, all I want to do at the minute is alert the bottom position of each dynamic control as they are added to the user form.
Dim dynamicControl As Control
For i = 1 To TextBox1.Value
Set cList = Me.Controls.Add("Forms.ListBox.1")
With cList
.Name = "listbox" & (i)
.Left = 150
.Top = listStartPosition
.Width = 300
.Height = 140
End With
Next i
dynamicControl = "listbox" & (i)
Msgbox dynamicControl.Bottom
When I run my code it errors out when I am trying to set the dynamicControl = "listbox" & 0 and the error I am recieving is object variable or with block variable not setobject variable or with block variable not set
to get your dynamic height you can use a code like this , by sending the number of clist this code is going to create them :
Private Sub createcontrol(num As Integer)
Dim StartPos As Integer
Dim WidthPos As Integer
StartPos = TextBox1.Top + TextBox1.Height + 10
For i = 1 To num
Set cList = Me.Controls.Add("Forms.ListBox.1")
With cList
.Name = "listbox" & (i)
.Left = 150
.Top = StartPos
.Width = 300
.Height = 140
StartPos = StartPos + .Height + 10
Me.Width = .Width + .Left
End With
Next i
Me.Height = StartPos - 8
End Sub
I have a module that creates command buttons during run-time. It will create the command buttons in a specified user-form. Program works fine, when I execute the module.
However when I use the user-form to call the module instead, I have a error stating
Run-time error '91':
Object variable or With block variable not set
Code
Sub AddButtonAndShow()
Dim Butn As CommandButton
Dim Line As Long
Dim objForm As Object
Dim i As Integer
Dim x As Integer
Set objForm = ThisWorkbook.VBProject.VBComponents("Current_Stock")
For i = 1 To 3
Set Butn = objForm.Designer.Controls.Add("Forms.CommandButton.1")
With Butn
.Name = "CommandButton" & i
.Caption = i
.Width = 100
.Left = 300
.Top = 10 * i * 2
End With
Next
For x = 1 To 3
With objForm.CodeModule
Line = .CountOfLines
.InsertLines Line + 1, "Sub CommandButton" & x & "_Click()"
.InsertLines Line + 2, "MsgBox ""Hello!"""
.InsertLines Line + 3, "End Sub"
End With
'
Next x
End Sub
Kindly advise.
Editted post: based on VBProject Form Components
Earlier post is for Excel Sheet buttons. I noticed for Form buttons you may set the caption by directly referring to the button itself. I tried out your code. Doesn't seem to find any errors. The only addtional things I did was adding the reference Library (MS VB Extensibility 5.3), Private scope to code and combining code into one with statement.
As per this Mr.Excel article, you need add do Events to run the code when VB Editor is closed. Your error seems to be very much alike to what's mentioned in the article.
Revised Code:
Sub AddButtonAndShow()
Dim Butn As CommandButton
Dim Line As Long
Dim objForm As Object
Dim i As Integer
Dim x As Integer
Dim code As String
Application.DisplayAlerts = False
DoEvents
On Error Resume Next
Set objForm = ActiveWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
objForm.Name = "thisform1"
For i = 1 To 3
Set Butn = objForm.Designer.Controls.Add("Forms.CommandButton.1")
With Butn
.Name = "CommandButton" & i
.Caption = i
.Width = 100
.Left = 100
.Top = (i * 24) + 10
Line = objForm.CodeModule.CountOfLines + 1
code = "Private Sub " & Butn.Name & "_Click()" & vbCr
code = code & "MsgBox ""Hello!""" & vbCr
code = code & "End Sub"
objForm.CodeModule.InsertLines Line, code
End With
Next
Application.DisplayAlerts = False
VBA.UserForms.Add(objForm.Name).Show
End Sub
Excel Command Button code:
Private Sub CommandButton3_Click()
Call AddButtonAndShow
End Sub
Output: Use an Excel Sheet button to open the newly created Form with buttons.
Initial post:
Please take a look at this post for reference: Excel VBA create a button beside cell.
Possible error due to (object doesn't support property or method), is within the Caption property. As it has to be set with theBttn.Object.Caption
Try this please:
With Butn
.Name = "CommandButton" & i
.Object.Caption = i
.Width = 100
.Left = 300
.Top = 10 * i * 2
End With