I'm using the following script to produce buttons in excel, the range is just where I'd like it to be placed.
Sub CreateAddButton(rng As Range)
Dim btn As Button
With Worksheets("User")
Set btn = .Buttons.Add(rng.Left, rng.Top, rng.width, rng.Height)
With btn
.name = "Add"
.Caption = "Add Column"
.OnAction = "CreateVariable"
End With
End With
End Sub
Only problem is, I'd like a method which can delete all the buttons produced by this method? I want to steer away from global variables if possible. Any help would be gratefully received.
James
I'd suggest Tim's method using a specific name - which does't need a global variable. For example you could add a
"_||ForDeletion" suffix to each button name and then look for it on a delete routine
.Name = "Add_||ForDeletion"
A Forms button does provide another alternative though (no pun intended), you can store a text sting in the AlternativeText under "Properties" then "Web" and use this as an identifier for a delete routine.
The delete routine at bottom works backwards to avoid errors when looping through a range
Sub TesMe()
Call CreateAddButton([a2])
End Sub
Sub CreateAddButton(rng As Range)
Dim btn As Button
With Worksheets("User")
Set btn = .Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)
With btn
.Name = "Add"
.Caption = "Add Column"
.OnAction = "CreateVariable"
.ShapeRange.AlternativeText = "MyCollection"
End With
End With
End Sub
Sub GetMyButtons()
Dim btns As Object
Dim lngRow As Long
Set btns = Sheets("User").Buttons
For lngRow = btns.Count To 1 Step -1
If btns(lngRow).ShapeRange.AlternativeText = "MyCollection" Then
MsgBox "Found one", vbCritical
btns(lngRow).Delete
End If
Next
End Sub
Buttons in VBA are in the Shapes collection. You can use:
Sub deleteButtons()
Dim btn As Shape
For Each btn In ActiveSheet.Shapes
If btn.AutoShapeType = msoShapeStyleMixed Then btn.Delete
Next
End Sub
msoShapeStyleMixed seems to be the type for all Form and ActiveX controls.
Related
My first post here, but have been successfully sourcing solutions and ideas from this website for a while now. So thanks for the collection of solutions and ideas.
Basically, I have a spread sheet application requiring the first column, Column A, to be filled with "Active X" buttons in every cell, looping through for a given quantity. I have posted one such working solution below which makes use of "form type buttons" and a Modules. This exemplifies what I consider my most favored example with working buttons. Once operational the column of buttons will correspond to relative data on the same row, and when clicked will open corresponding folders, and userforms in later developments.
The second post uses the Range function, but obviously doesn't incorporate any buttons to interactive with. However, a mouse click over this Range will obviously activate any code from within the Worksheet_Selection Change procedure...Sorry just stating the obvious!
What I have been trying to achieve is a version of code employing "activeX" Command Buttons, but after having studied some great tutorials and poured over a range of programing concepts, I still fail miserably to employ OLEObjects.
How to add a button programmatically in VBA next to some sheet cell data?
Sheet 1 Procedure:
Sub ColumnA_Buttons()
Dim buttons As Button
Dim rng As Range
Dim LineQty As Variant
Application.ScreenUpdating = False
ActiveSheet.buttons.Delete
LineQty = 5
For i = 1 To LineQty
Set rng = ActiveSheet.Range(Cells(i, 1), Cells(i, 1))
Set buttons = ActiveSheet.buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)
With buttons
.OnAction = "Buttons"
.Caption = "Line " & i
.Name = "Line " & i
End With
Next i
Application.ScreenUpdating = True
End Sub
Public Click_Button As Variant ' Make Variable Public for Userform1
'
Form Button Module:
Sub Line_Buttons()
Click_Button = Application.Caller
MsgBox Click_Button & " was Clicked"
UserForm1.Show 'Launch custom userform
End Sub
And the next option to be considered is a range detection
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' e.g., range(A1:E1) is clicked
If Not Application.Intersect(Target, Range("B2:B12")) Is Nothing Then
MsgBox "You clicked " & Target.Address
End If
End Sub
Ok. I'm posting some code that I've been working on based on this post here: Multiple active X checkboxes... . It seems I've now come to the same stand still they did as descibed in their last post :
"Yes it is individual checkboxes. You can emulate control arrays in
VBA so that each checkbox uses the same click event code, but that is
probably overkill IMO. "
And if I read Jason's post above, this is what he's questioning regarding the event code.
Any assistance welcomed in completing this code, as I have Not yet seen a working example which interlocks it to a single event, as per the form button module above.
Sub Macro1()
Dim objCmdBtn As Object
Dim i As Integer
Dim Rnge As Range
Set ColumnRange = Range("A:A") ' Set width & height of column A
ColumnRange.ColumnWidth = 5: ColumnRange.RowHeight = 15.75
'Delete previous objCmdBtn
For Each objCmdBtn In ActiveSheet.OLEObjects
If TypeName(objCmdBtn.Object) = "CommandButton" Then objCmdBtn.Delete
Next objCmdBtn 'TypeName Function returns the data-type about a variable - TypeName(varname is objCmdBtn)
With ActiveSheet
For i = 1 To 25
Set Rnge = ActiveSheet.Range(Cells(i + 1, 1), Cells(i + 1, 1))
Set objCmdBtn = Sheets("Sheet1").OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
Link:=False, _
DisplayAsIcon:=False, _
Left:=Rnge.Left, _
Top:=Rnge.Top, _
Width:=Rnge.Width, _
Height:=Rnge.Height)
With objCmdBtn
'set a String value as object's name
'.Name = "CommandButton1"
With .Object
.Caption = i
With .Font
.Name = "Arial"
.Bold = True
.Size = 7
.Italic = False
.Underline = False
End With
End With
End With
Next
End With
End Sub
Here is an example of ActiveX buttons being created and coded to run. It may take some small tweaks, but will get the job done.
Sub CreateButton()
Dim Obj As Object
Dim Code As String
Dim cellLeft As Single
Dim cellTop As Single
Dim cellwidth As Single
Dim cellheight As Single
Dim LineQty as Integer
Sheets("Sheet1").Select
LineQty = 5
For i = 1 To LineQty
Set rng = ActiveSheet.Range(Cells(i, 1), Cells(i, 1))
cellLeft = rng.Left
cellTop = rng.Top
cellwidth = rng.Width
cellheight = rng.Height
'create button
Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False, DisplayAsIcon:=False, Left:=cellLeft, Top:=cellTop, Width:=cellWidth, Height:=cellHeight)
Obj.Name = "TestButton"
'button text
ActiveSheet.OLEObjects(1).Object.Caption = "Test Button"
'macro text to be added possibly by array?
Code = "Private Sub TestButton_Click()" & vbCrLf
Code = Code & "Call Tester" & vbCrLf
Code = Code & "End Sub"
'add macro at the end of the sheet module
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.Name).CodeModule
.insertlines
.CountOfLines + 1, Code
End With
Next i
End Sub
Sub Tester()
MsgBox "You have clicked on the test button"
End Sub
Note In order for this to not error on me, I had to go to the trust center and to trust center settings and macro settings and check the box "Trust Access to the VBA Project Object Model"
I have written VBA with 3 modules that work perfectly and the userform works as well when I run it from Developer - VBA window. I need to add the userform to my add-in to activate when I need it. I added the 4th module to install the macro
Sub Add_MainframeScrape_Menu()
Dim cbWSMenuBar As CommandBar
Dim muInbound As CommandBarControl
Dim iHelpIndex As Integer
Set cbWSMenuBar = Application.CommandBars("Worksheet Menu Bar")
iHelpIndex = cbWSMenuBar.Controls("Help").Index
Set muInbound = cbWSMenuBar.Controls.Add(Type:=msoControlPopup, Before:=iHelpIndex)
With muInbound
.Caption = "EDIMACROS"
With .Controls.Add '(Type:=msoControlPopup)
.Caption = "EDIMACROS"
.OnAction = "EDI_REPORTS"
End With
End With
End Sub
And I added the below code to the form itself to start when I click on add-ins
Public Sub EDI_MACROS_Initialize()
Me.Show
End Sub
But it's not working please help.
The OnAction should be the name of a Sub (in a regular module) which displays the form, not the name of the form
Sub Add_MainframeScrape_Menu()
Dim cbWSMenuBar As CommandBar
Dim muInbound As CommandBarControl
Dim iHelpIndex As Integer
Set cbWSMenuBar = Application.CommandBars("Worksheet Menu Bar")
iHelpIndex = cbWSMenuBar.Controls("Help").Index
Set muInbound = cbWSMenuBar.Controls.Add(Type:=msoControlPopup, _
Before:=iHelpIndex)
With muInbound
.Caption = "EDIMACROS"
With .Controls.Add '(Type:=msoControlPopup)
.Caption = "EDIMACROS"
.OnAction = "Show_EDI_MACROS"
End With
End With
End Sub
Public Sub Show_EDI_MACROS()
EDI_REPORTS.Show 'assumes your form is named "EDI_REPORTS"
End Sub
I've added two Dropdown (aka ComboBox) to a Sheet
Starting from this question (How do I refer to a controls object, on a worksheet, using a variable name?) I tried the following experiment without succeding.
How do I access to the controls on an Excel Sheet? And where do I see the name / properties of the controls I have just inserted?
You can do something like this:
Sub DropDown1_Change()
Dim s As Object
Set s = ActiveSheet.Shapes(Application.Caller)
Debug.Print s.ControlFormat.Value
End Sub
Application.Caller contains the name of the shape "containing" the form control
Similarly you can access other controls by name:
Dim myName as String, c As Object
myName = "List Box 2"
Set c = ActiveSheet.Shapes(myName).ControlFormat
Instead of adding it like that I suggest creating a Shape variable, and use that to add data/properties.
Something like this:
Sub t()
Dim newDD As Shape
Set newDD = ActiveSheet.Shapes.AddFormControl(xlDropDown, Left:=Cells(1, 1).Left, Top:=Cells(2, 1).Top, Width:=100, Height:=20)
With newDD
.ControlFormat.DropDownLines = 2
.ControlFormat.AddItem "Item 1", 1
.ControlFormat.AddItem "item 2", 2
.Name = "New Combo Box"
.OnAction = "myCombo_Change"
End With
End Sub
Try
Dim checkBox1 As Object
Set checkBox1 = Sheet1.OLEObjects("CheckBox1").Object
MsgBox checkBox1.Value
I tried `
Set chkBox = UserForm1.Controls.Add("Forms.Checkbox.i", "Checkbox" & i)
'.Object.Caption = Range("D3").Value
I even tried
With ActiveSheet.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
Left:=51.75, Top:=183, Width:=120, Height:=19.5)
.Name = "NewCheckBox"
.Object.Caption = Range("D3").Value
But this gives me a checkbox but not on my created userform but the activesheet I'm on.
Any suggestions
In the most primitive form I wrote, this added a checkbox (to the upper left corner of the UserForm1)
Private Sub CommandButton1_Click()
Dim chkBox As Control
Set chkBox = Me.Controls.Add("Forms.CheckBox.1", "checkbox")
End Sub
You'll want to play with the positioning and such.
I am trying to create pop-up menu, that will give option to copy-paste a shape object out from shape group named "Element" (Oval + Text Box).
But it seemed that Select & Paste methods did not work.
Public Element_Menu As CommandBar
Function CreateSubMenu() As CommandBar
Const pop_up_name = "pop-up menu"
Dim the_command_bar As CommandBar
Dim the_command_bar_control As CommandBarControl
For Each menu_item In CommandBars
If menu_item.Name = pop_up_name Then
CommandBars(pop_up_name).Delete
End If
Next
Set the_command_bar = CommandBars.Add(Name:=pop_up_name, Position:=msoBarPopup, MenuBar:=False, Temporary:=False)
Set the_command_bar_control = the_command_bar.Controls.Add
the_command_bar_control.Caption = "Add &Element"
the_command_bar_control.OnAction = "AddElement"
Set CreateSubMenu = the_command_bar
End Function
Sub ElementClick()
Set Element_Menu = CreateSubMenu
Element_Menu.ShowPopup
End Sub
Sub AddElement()
ActiveSheet.Shapes("Element").Select 'Selecting template object to replicate
ActiveSheet.Paste 'Inserting copy out from the clipboard
End Sub
Is the shape that is added correctly named "Element" (as per the line that does not work?) It seems that it is called "Test Element".