Error with creating command button during runtime - vba

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

Related

Keeping on getting run time error 424

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 “

VBA Powerpoint Reference a textbox with variable

I am attempting to write a vba loop that will detect the value of all ActiveX textboxes on the slide. However I am have trouble writing the code for the "variable" in the textbox reference. For example TextBox(i) needs to be referenced in the loop. Where i is an integer I set the value to.
Dim i as Integer
For i = 1 to 4
If IsNull(Slide1.Shapes.("TextBox" & i).Value) = True
Then (Slide1.Shapes.("TextBox" & i).Value) = 0
Else: ...
Next i
However this script doesn't work and I have been unable to locate a source for how to properly code this variable portion of script. There has been some talk of using Me.Controls however I am not creating a form. Would anyone be willing to share what the error is here in my script?
This will put the value of i into TextBox i. Should get you started, I think.
Sub Example()
Dim oSh As Shape
Dim i As Integer
On Error Resume Next
For i = 1 To 4
Set oSh = ActivePresentation.Slides(1).Shapes("TextBox" & CStr(i))
If Err.Number = 0 Then ' shape exists
oSh.OLEFormat.Object.Text = CStr(i)
End If
Next i
End Sub
#Steve Rindsberg you had the correct code. Thank you. Here was the final script to obtain the value, and set the value if blank.
For i = 1 To 4
'set oSh to TextBox1, TextBox2, TextBox3... etc.
Set oSh = ActivePresentation.Slides(1).Shapes("TextBox" & CStr(i))
'set myVar to value of this TextBox1, TextBox2...
myVar = oSh.OLEFormat.Object.Value
If myVar = "" Then _
ActivePresentation.Slides(1).Shapes("Text" & CStr(i)).OLEFormat.Object.Value = 0 _
Else: 'do nothing
'clear value of myVar
myVar = ""
'start on next integer of i
Next i

How to assign code to a dynamically created button?

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

Implement For Loop with Counter

I have a Word Userform where I add text boxes dynamically. The code then puts information from the textboxes to bookmarks which are picture filenames. It is all dynamic in that you enter how many textboxes you need and it then adds them to the userform and the text in the document. I left this last part of code out because its very long and not needed at this point.
I am attempting to put this first part of my code into a "For Loop" but I have been having a lot of difficulty doing so. The second part of my code I am providing has a textbox counter I trying to tie into it.
Right now my code works if I enter 10 into a textbox called "Amount" which you see throughout the code. I need to be able to enter any number.
If you think the entire code will help let me know and I will add it instead. I have been able to get everything else to work but for some reason this has had me stumped for days.
Need "For loop" implemented
Sub CommandButton1_Click()
Dim Textbox As Object
Dim Textbox1 As Object
Dim Textbox2 As Object
Dim Textbox3 As Object
Dim Textbox4 As Object
Dim Textbox5 As Object
Dim Textbox6 As Object
Dim Textbox7 As Object
Dim Textbox8 As Object
Dim Textbox9 As Object
Dim Textbox10 As Object
Dim TBs(9) As Object
Set TBs(0) = UserForm1.Controls("TextBox_1"): Set TBs(1) = UserForm1.Controls("TextBox_2"): Set TBs(2) = UserForm1.Controls("TextBox_3")
Set TBs(3) = UserForm1.Controls("TextBox_4"): Set TBs(4) = UserForm1.Controls("TextBox_5"): Set TBs(5) = UserForm1.Controls("TextBox_6")
Set TBs(6) = UserForm1.Controls("TextBox_7"): Set TBs(7) = UserForm1.Controls("TextBox_8"): Set TBs(8) = UserForm1.Controls("TextBox_9")
Set TBs(9) = UserForm1.Controls("TextBox_10"):
Dim i
For i = 0 To Amount - 1
With ActiveDocument
If .Bookmarks("href" & i + 1).Range = ".jpg" Then
.Bookmarks("href" & i + 1).Range _
.InsertBefore TBs(i)
.Bookmarks("src" & i + 1).Range _
.InsertBefore TBs(i)
.Bookmarks("alt" & i + 1).Range _
.InsertBefore TBs(i)
End If
End With
Next
End Sub
TextBox Counter
Private Sub AddLine_Click()
Dim theTextbox As Object
Dim textboxCounter As Long
For textboxCounter = 1 To Amount
Set theTextbox = UserForm1.Controls.Add("Forms.TextBox.1", "Test" & textboxCounter, True)
With theTextbox
.Name = "TextBox_" & textboxCounter
.Width = 200
.Left = 70
.Top = 30 * textboxCounter
End With
Next
End Sub

Assign code to a button created dynamically

I'm trying to get a button I've created dynamically on an excel userform form to run a macro called transfer which I've written in Module 1 of the "Modules" section of my project.
Below I've pasted the code I've written so far in the userform which actually manages to create the Transfer to Sheet button in the frame (which I've also created dynamically) but for some reason, when I run VBA I get a 438 error message saying that Object doesn't support this property or method.
Can anybody tell me how I can resolve this?
Here's the code:
Dim framecontrol1 As Control
Set workitemframe = Controls.Add("Forms.Frame.1")
With workitemframe
.Width = 400
.Height = 400
.Top = 160
.Left = 2
.ZOrder (1)
.Visible = True
End With
workitemframe.Caption = "Test"
Set framecontrol1 = workitemframe.Controls.Add("Forms.commandbutton.1")
With framecontrol1
.Width = 100
.Top = 70
.Left = 10
.ZOrder (1)
.Visible = True
.Caption = "Transfer to Sheet"
End With
framecontrol1.OnAction = "transfer"
Here is an example. Please amend it to suit your needs :)
This example will create a command button and assign code to it so that when it is pressed, it will display "Hello World".
Paste this code in the click event of a command button which will create a new command button dynamically and assign code to it.
Option Explicit
Dim cmdArray() As New Class1
Private Sub CommandButton1_Click()
Dim ctl_Command As Control
Dim i As Long
i = 1
Set ctl_Command = Me.Controls.Add("Forms.CommandButton.1", "CmdXYZ" & i, False)
With ctl_Command
.Left = 100
.Top = 100
.Width = 255
.Caption = "Click Me " & CStr(i)
.Visible = True
End With
ReDim Preserve cmdArray(1 To i)
Set cmdArray(i).CmdEvents = ctl_Command
Set ctl_Command = Nothing
End Sub
and paste this code in a class module
Option Explicit
Public WithEvents CmdEvents As MSForms.CommandButton
Private Sub CmdEvents_Click()
MsgBox "Hello Word"
End Sub
SNAPSHOT
You need to add the code to the UserForm programatically. I used my code from this vbax article as the reference
The code below:
Runs from a normal module
Adds the button to a UserForm called UserForm1
Adds this code to the Userform for a Click Event
Private Sub CommandButton1_Click()
Call Transfer
End Sub
VBA from normal module
Sub AddToForm()
Dim UF As Object
Dim frameCOntrol1 As Object
Set UF = ActiveWorkbook.VBProject.VBComponents("UserForm1")
Set frameCOntrol1 = UF.designer.Controls.Add("Forms.CommandButton.1")
With frameCOntrol1
.Width = 100
.Top = 70
.Left = 10
.ZOrder (1)
.Visible = True
.Caption = "Transfer to Sheet"
End With
With UF.CodeModule
.InsertLines 2, _
"Private Sub " & frameCOntrol1.Name & "_Click()" & Chr(13) & _
"Call Transfer" & Chr(13) & _
"End Sub"
End With
End Sub