Why are there 2 types of controls available in Excel? (2 buttons, 2 combo boxes, 2 check box, etc...)
What's the difference between Forms Controls and ActiveX Controls? Which one should I use?
Some code samples I find online work with my controls, but others do not. How come?
How do I work with each type, and how can I tell the difference?
There is [eternal] confusion surrounding the two types of controls available to Excel — exacerbated by the contrasting terminology used by different online sources.
This is only a general overview of the differences between Form Controls and ActiveX Controls (based on my old notes that helped me finally figure out the differences!) Visit the included links for more detailed information about each control including code and sample projects. ☺
(Adapted from my original post here — now closed)
Overview:
There are two types of controls: Form controls and ActiveX controls:
Both types of controls can be used on worksheets but only ActiveX controls can be used on userforms.
Form controls are part of the Shapes collection (just like Drawing Objects), and thus are referred to like:
ActiveX controls are basically part of the worksheet and are therefore referred to like:
Both types of controls can be created, modified and deleted from either the worksheet, or programmatically with VBA, however, the 2 types of controls have slightly varying syntax when using VBA to refer to them.
Some sites discuss also discuss a Data Form. This is nothing more than a userform made specifically for data entry/manipulation of data, so it would've made more sense to call them (the more familiar sounding) "Data Entry Userform".
Office documentation also occasionally refers to a worksheet as a form. While this is technically correct, don't let this confuse you. Think of the word "form" as being used in a general sense:
Two Types of Controls
Form Controls
ActiveX Controls
The two look, behave, and are controlled similarly, but not identically. (List here.)
For example, let's compare the two types of Combo Boxes. In some programming languages, comparable controls are referred to as a "drop-down menu" or "drop-down list". In Excel, we have a "Form Control Combo Box", and an "ActiveX Control Combo Box":
(Click image to enlarge.)
☆ "Default name" applies to controls created manually. Controls created programmatically do not have (or require) a default name and therefore should have one assigned immediately upon creation.
(Source: my answer)
Control Availability
This image below shows which common controls are generally available for use in Worksheets and User Forms.
Other factors may affect control availability.
Office.com : Why are form-related commands or controls on the ribbon disabled?
Office.com : Overview of forms, Form controls, and ActiveX controls on a worksheet
MSDN : Add Controls to a User Form
About ActiveX controls and related Security Concerns
An ActiveX control is an extension to the VBA Toolbox. You use ActiveX controls just as you would any of the standard built-in controls, such as the CheckBox control. When you add an ActiveX control to an application, it becomes part of the development and run-time environment and provides new functionality for your application.
An ActiveX control is implemented as an in-process server (typically a small object) that can be used in any OLE container. Note that the full functionality of an ActiveX control is available only when used within an OLE container designed to be aware of ActiveX controls.
This container type, called a control container or control object, can operate an ActiveX control by using the control’s properties and methods, and receives notifications from the ActiveX control in the form of events. The following figure demonstrates this interaction:
(Source: this and this)
See also:
Wikipedia: ActiveX
Symantec.com : Discussion of ActiveX Vulnerabilities
How-To Geek : What ActiveX Controls Are and Why They’re Dangerous
Option Buttons (Radio Buttons)
In Excel, the two types of radio buttons are actually called Option Buttons. To further confuse matters:
the default name for the form control is OptionButton1.
the default name for the ActiveX control is Option Button 1.
A good way to distinguish them is by opening the control's Properties list (on the ribbon under the Development tab, or by right-clicking the control and choosing Properties, or hitting F4), because the ActiveX control has many more options that the simpler form control.
Option buttons and checkboxes can be bound together (so only one option at a time can be selected from the group) by placing them in a shared Group Box.
Select the group box control and then hold Ctrl while selecting each of the other controls that you want to group. Right-click the group box control and choose Grouping → Group.
The first two links below are separate sets of instructions for handling each type of option button.
HANDLING CONTROL EVENTS:
Form control events (Click event only)
Form control events are only able to respond to one event: the Click event. (More info here.) Note that this section doesn't apply to userforms since they use only ActiveX controls.
To add a procedure for the Click event:
Right-click the control and choose Assign Macro...
In the 'Assign Macro` Dialog:
Select an existing procedure, and click OK, or,
Create a new procedure in the VBE by clicking New..., or,
Record a new macro by clicking Record..., or,
to Remove the assigned event, delete its name from Macro Name field and click OK.
(Click image to enlarge.)
To rename, edit or delete existing macros, hit Alt+F8 to open the Macro interface:
ActiveX control events
ActiveX controls have a more extensive list of events to which they can be set up to respond.
To assign events to ActiveX controls, right-click the control and choose View Code. In the VBE, you can paste in code, or choose specific events from the drop-down list at the top-right of the VBE window.
(Click image to enlarge.)
Control event handling on a userform:
Events can also be used in controls on userforms. Since only ActiveX controls can be placed a userform, you'll have the "more coding + more functionality" trade-off.
ActiveX controls are added to userforms the same way as they are added to a worksheet. Keep in mind that any events assigned to the userform itself (ie., background) will be "blocked" in any areas covered up by a control, so you may need to assign the same events to the controls as well as the userform.
For example, in order to make this userform respond to MouseMove anywhere on the form, the same event code was applied to the userform, textboxes, option buttons and the frame:
VBA EXAMPLES
Add/Modify/Delete a form control option button using VBA:
Sub formControl_add()
'create form control
Dim ws As Worksheet: Set ws = ActiveSheet
With ws.Shapes.AddFormControl(xlOptionButton, 25, 25, 100, 100)
.Name = "cOptionButton1" 'name control immediately (so we can find it later)
End With
End Sub
Sub formControl_modify()
'modify form control's properties
Dim ws As Worksheet: Set ws = ActiveSheet
ws.Shapes("cOptionButton1").Select
With Selection 'shapes must be Selected before changing
.Characters.Text = "wxyzabcd"
End With
End Sub
Sub formControl_delete()
'delete form control
Dim ws As Worksheet: Set ws = ActiveSheet
ws.Shapes("cOptionButton1").Delete
End Sub
Shapes.AddShape Method (Excel)
Shape Properties (Excel)
Characters Object (Excel)
Add/Modify/Delete an ActiveX command button using VBA:
Sub activexControl_add()
'create ActiveX control
Dim ws As Worksheet: Set ws = ActiveSheet
With ws.OLEObjects.Add("Forms.CommandButton.1")
.Left = 25
.Top = 25
.Width = 75
.Height = 75
.Name = "xCommandButton1" 'name control immediately (so we can find it later)
End With
End Sub
Sub activexControl_modify()
' modify activeX control's properties
Dim ws As Worksheet: Set ws = ActiveSheet
With ws.OLEObjects("xCommandButton1").Object
.Caption = "abcxyz"
.BackColor = vbGreen
End With
End Sub
Sub activexControl_delete()
' delete activeX control
Dim ws As Worksheet: Set ws = ActiveSheet
ws.OLEObjects("xCommandButton1").Delete
End Sub
OLEObjects.Add Method (Excel)
BackColor, ForeColor Properties (ActiveX Controls)
Add/Remove items from a form control combo box:
Sub ComboBox_addRemoveItems_FormControl()
Dim ws As Worksheet: Set ws = ActiveSheet
'add item to form control combo box
ActiveWorkbook.Sheets("Sheet1").Shapes("Drop Down 1").ControlFormat.AddItem "abcd"
'remove all items from from form control combo bo
ActiveWorkbook.Sheets("Sheet1").Shapes("Drop Down 1").ControlFormat.RemoveAllItems
End Sub
Add/Remove items from an ActiveX combo box:
Sub ComboBox_addRemoveItems_ActiveXControl()
Dim ws As Worksheet: Set ws = ActiveSheet
'add items to ActiveX combo box
ActiveWorkbook.Sheets("Sheet1").ComboBox1.AddItem "abcd"
'remove all items from ActiveX combo box
ActiveWorkbook.Sheets("Sheet1").ComboBox1.Clear
End Sub
More Information:
Office.com : Add a checkbox or option button (Form controls)
Office.com : Add a checkbox, option button, or toggle button (ActiveX controls)
Office.com : Overview of forms, Form controls, and ActiveX controls on a worksheet
Office.com : Enable selection through choice controls (check and list boxes)
Office.com : Add, edit, find, and delete rows by using a data form
MSDN : VBA Shape Members
MSDN : Using ActiveX Controls on Sheets (Office)
Exceldemy : How to Use Form Controls in Excel
MSDN : Using Windows Forms Controls on Excel Worksheets (Visual Studio)
Microsoft TechNet : Behaviour of ActiveX controls embedded in Office documents
Stack Overflow : What is the difference between “Form Controls” and “ActiveX Control” in Excel 2010?
Related
I have an Excel Workbook with a couple of custom ribbon tabs. I would like to activate a specified Sheet when clicking of particular custom ribbon tab.
Details:
The Workbook composed of a 5 Sheets has following additional ribbon tabs: "Parameters" and "Data Analysis". Each Tab has a few groups of controls. I need to add a trigger (macro?), which would automatically change a Sheet to Sheet3 (to run ActiveWorkbook.Sheets("Sheet3").Activate) only when a user picks the "Data Analysis" Tab.
I would appreciate any help.
It is possible to use a getVisible callback from a ribbon to achieve what you are looking for.
Here is an example xml for a tab (it should be nested inCustomUI and ribbon tags)
<tabs>
<tab id="ExampleTab" label="Example Tab">
<group id="ExampleGroup"
label="Example Group"
getVisible="GetVisibility"
tag="1"
>
</group>
</tab>
</tabs>
When someone clicks on the tab this xml will call GetVisibility sub in the workbook it belongs to. You can use tag property to pass a variable to the `Sub'. For example every tab can have its own tag, or it can be used for something else.
Now here is an example code for GetVisibility:
Public Sub GetVisibility(Control As IRibbonControl, ByRef Visible)
'your code to activate the worksheet can go here
Visible = True 'if you want to make a control visible
Select Case Control.Tag 'you can use Control.Tag to get a variable from ribbon
Case "1"
Case Else
End Select
End Sub
The only issue is that this code will normally only be called the first time you click on a tab. To get the code to rerun I think you need to invalidate your ribbon control. For that you would have to store your ribbon in a global scope variable at initialization. The last time I checked you may need a workaround for that, such as storing ribbon address in a worksheet. There is a number of question on Stack about that, for example: this one.
I have an Excel sheet with quite a few groups of option buttons (inserted from form controls and grouped using group boces). What is the easiest way to set the linked cell of each group using VBA code? I tried
ActiveSheet.Shapes.Range("test").Select
.LinkedCell = Range("A1")
but it had no effect. "test" is the name I set for one of the option buttons in the corresponding group.
(The reason for trying to set the LinkedCell via VBA is that these links are sometimes lost for reasons I don't yet understand. If anyone can point out a possible scenario how this could possibly happen in the first place, I would be very grateful.)
Using a named range will only point to one or more cells on a worksheet. It does not refer to a form control. You're likely using a Form Control Option Button somewhere on your worksheet. The code to set the LinkedCell property is
Dim optButton As Shape
Set optButton = Sheet2.Shapes("Option Button 2")
optButton.ControlFormat.LinkedCell = "H4"
Hi I am using excel 2010 with activex controls. I know activex controls can cause corruption and random resizing of the controls. This problem starts when I change screens.
I need to be able to add elements to a form control through a button being clicked and I also need to access elements in the form through VBA.
My question is how do you add an element into a form control listbox and how do you access it and how do you delete it.
My code uses all active x components but I want to switch them up. I am not sure how to set a name on a form control listbox to even access it in VBA.
Any help would be awesome!
PS. I am using windows 7, excel 2010
This method creates a listbox runtime. You just need to leave space on UserForm1 for it.
Dim lb As msforms.ListBox
Set lb = UserForm1.Controls.Add("forms.listbox.1", "MyListBox1")
This is also a good demostration on how to refer to an (ActiveX) object. A workaround to avoid accidental/unexpected resizing you can intentionally run the following snippet regularly from within the code:
If lb.width <> 100 Then ' or you can check other properties, too
lb.Top = 120
lb.Left = 40
lb.Width = 100
End If
This can be applied to other ActiveX objects, too, e.g.:
If UserForm1.Width <> 200 Then
UserForm1.Width = 200
...
You just need to find a good place in your code where this snippet is run often, and also definitely in UserForm_Initialize. You can also set other properties like caption or tabstop, etc. this way.
For adding and removing items you need to use indices like this:
lb.AddItem "First item", 1
lb.AddItem "Second item", 2
lb.AddItem "Third item", 3
lb.RemoveItem 2
I have problem with one CustomTaskPane in mutiple Excel 2016 documents. I create and display task pane with my WinForm user control
Dim cll As cMyControl = New cMyControl
Private Sub ThisAddIn_Startup() Handles Me.Startup
CustomTaskPanes.Add(cll, "Panel")
End Sub
This panel I can see in all workbook.
Private Sub Application_WorkbookActivate(Wb As Microsoft.Office.Interop.Excel.Workbook) Handles Application.WorkbookActivate
CustomTaskPanes.RemoveAt(0)
CustomTaskPanes.Add(cll, "Panel")
End Sub
The problem is that the panel is created but empty. Is any way how to transfer user control between CustomTaskPanels? Or how to attach created panel to another Excel window? Because the I don't want to create new cll object for each workbook activation.
Excel 2016 is a SDI and then you need to store a reference of each taskpane. You need to use Globals.ThisAddIn.Application.Hwnd to identify the Excel window.
See here for a solution : https://stackoverflow.com/a/24732000/3205529
I am maintaining a large spread sheet at work and there are ActiveX command buttons throughout the code. One sheet I am currently working on has almost 100 of these. I have made sure the button itself is visible as some of the buttons are hidden/unhidden depending on the flow of the code.
Is there a way I can find whereabouts on the sheet itself the button is located that the VBA code is pointing to? Here is a snippet:
enter code here
Private Sub CommandButton4_Click()
Application.Goto Range("Add_Trainees"), True
CommandButton3.Visible = True ' unhides menu button
CommandButton81.Visible = True ' hides SC1
CommandButton97.Visible = True ' hides SC2
End Sub
I am trying to find where on the sheet where command buttons 3, 81 and 97 are located.
TIA for any help/suggestions.
I think pnuts provides the correct way to find out where the buttons are.
I would also suggest to open the panel from "Developer" -> "Properties". In that panel, you can check out all the ActiveX Controls, including the command buttons, in the list.