Note: this works only for radio buttons on a worksheet and can’t be used in user forms
A recent security update by Microsoft broke one of my clients Excel VBA applications which was using MSForms 2.0 radio buttons. The Excel workbook in question shows several tabular ranges on a single sheet. Each table has radio buttons and list boxes attached for custom sorting and filtering. Unfortunately, only ActiveX controls (MSForms 2.0) support more than one radio button group on a single sheet – so there was no way to recur to inbuilt Excel sheet controls.
The fix as advised by Microsoft didn’t work in our case – and since it is more hassle to discuss uninstalling a MS security update with the security chief, we decided that I should write a vba-only custom radio button group as a workaround.
To use it follow these steps:
- Make sure you include the class file in your project (“radioButtons.cls” ). See the download link at the end of this article.
- Place an empty chart somewhere on a worksheet. Name the chart object and style its background and border as you like.
- Add two images (or graphics) to the chart area – one for the deactivated and one for the activated radio button state. They should have the same size. In the picture properties set the title (under alternate text) to “deactivated” and “activated” respectively (important!)
- Add a textbox to the chart area and style it. Set the title to “caption”.
- In your workbook initialization routine (module or code-behind) add the following code:
code listing 1: worksheet code-behindVisual Basic123456789101112131415161718192021222324252627282930313233343536373839' Worksheet Code behind' ---------------------------------------------------------' Declare class objects for each radio button chart containerPrivate SortOrderButtons1 As New radioButtonsPrivate SortOrderButtons2 As New radioButtons' Trigger SortOrderButtons initialization when worksheet activatesPrivate Sub Worksheet_Activate()InitSortOrderButtonsEnd Sub' Initialize SortOrderButtonsPrivate Sub InitSortOrderButtons()If SortOrderButtons1.isAttached = False ThenWith SortOrderButtons1Set .Container = ActiveSheet.ChartObjects("sortOrderButtons1").Chart.addButton "radioButton_asc", "asc", "SortOrderButtons1_Click", "deactivated", "S10".addButton "radioButton_desc", "desc", "SortOrderButtons1_Click", "deactivated", "S10".initEnd WithEnd IfIf SortOrderButtons2.isAttached = False ThenWith SortOrderButtons2Set .Container = ActiveSheet.ChartObjects("sortOrderButtons2").Chart.addButton "radioButton_asc", "asc", "SortOrderButtons2_Click", "deactivated", "A50".addButton "radioButton_desc", "desc", "SortOrderButtons2_Click", "deactivated", "A50".initEnd WithEnd IfEnd Sub
the addButton class function takes the following parameters:
– button name: i.e. “radioButton_asc”, “radioButton_desc”
– caption text: i.e. “asc”, “desc”
– callback: to be called when clicked, i.e. “SortOrderButtons1_Click”
– button state: “deactivated” or “activated”
– cell selection target: cell to be selected after click event (default: “A1”)
The pictures and textbox act as templates for rendering the buttons as given in the initialization routine. You do not have to create all buttons and captions, this is provided for in the initialization. On each worksheet activation the class will check, if the buttons configured are there and if the class is attached to the chart container. If not, the buttons will be created and drawn and the class will attach to the container. This is done only one time. Subsequent worksheet activations will only attach the class to its container.
- When clicking on a radio button the clicked button gets activated and the function hook is called.
You may use as many buttonGroups on a worksheet as you like. Just repeat the steps above.
This simple solution has several advantages:
- easy to handle
- avoids dependency on MSForms
- more than one button group on a single worksheet (which is possible with the active-x controls in MsForms 2.0 but not with the inbuilt Excel controls)