Programmatically add a button with a macro to an Excel file - vba

I'm creating formated worksheets with an Excel VBA application and I would like to add programmatically add a button to each worksheet when created. This button must have a macro attached to it, which display the average of the values in a certain range in a special cell, and change the background color of this cell depending on the value of the average. Is it possible to this, and if yes, how can I do it ?

You can add the Button like this or example:
ActiveSheet.Buttons.Add(52.5, 7.5, 173.25, 41.25).Select 'Arguments are coordinates
Selection.OnAction = "Button_Click"
Now make sure the Button_Click sub has the logic you want.

Related

How to select an ActiveX Option/Radio Buttons in Form Controls

I have a Form Control with ActiveX Radio/Option Buttons in it.
The Form Control name is Side and contains Option/Radio Buttons with names xOption, oOption, and randomSide.
How would I be able to create a Macro that would allow me to set the radio buttons to a certain value upon opening the workBook. Recording a Macro of me clicking options results in a blank Macro. I've Already tried:
ActiveSheet.Shapes.Range(Array("Side")).Select
ActiveSheet.Shapes.Range("xOption").OLEFormat.Object.Value = 1
But this gives me error 1004 and other codes give me error 91. I'm really new to VBA so if I look stupid you know why.
Try something like this, using Worksheets instead of ActiveSheet:
Private Sub Workbook_Open()
Worksheets("your sheet name here").OLEObjects("xOption").Object.Value = 1
End Sub
As you want it to be selected after opening the sheet. Place this on ThisWorkbook.
You may try something like this...
ActiveSheet.OLEObjects("xOption").Object.Value = 1

Running a VBA script from a button after selecting a chart

I’m running Excel 2010 on Windows 7.
I have four charts on a worksheet. What I want to do is select one of the charts and then click a button to open the ‘Format Axis’ dialogue box. I found the following code online to open the dialogue box. If I select a chart and then run the code from the toolbar (Developer tab, Macros, select macro, press ‘Run’), it works well.
Sub formatXAxis1()
ActiveChart.Axes(xlCategory).Select
Application.CommandBars.ExecuteMso "ChartFormatSelection"
End Sub
The trouble I have is when the VBA script is assigned to a button. If I use a shape as the button, I get “Run-time error ‘91’: Object variable or With block variable not set”. I get the same error if I use an ActiveX Command Button. However, with a Form Control button it works as expected. The only problem with this solution is that it is not possible to change the background colour of the button so it looks out of place against the other macro calling buttons on the worksheet.
I'm guessing that in the first two cases (shape and ActiveX buttons), VBA drops or loses the chart selection when I press the button – even though the chart still appears selected on screen. Is there a fix for this, or am I doing something wrong?
For an ActiveX button, in the Properties set the property
TakeFocusOnClick
to False. That will cause Selection to keep on the chart rather than switch to the button and your code should work. The color can also be changed from the properties box, though you probably already know that.
You need to reference the chart by name. So either have 4 buttons (one for each chart), or ask the user to input the name of the chart, then:
Dim co as ChartObject
Dim c as Chart
Dim NameOfChart as String
NameOfChart = Inputbox("Enter name of chart")
Set co = ActiveSheet.ChartObjects(NameOfChart)
Set c = co.chart
c.Axes(xlCategory).Select
Application.CommandBars.ExecuteMso "ChartFormatSelection"

Excel ActiveX ListBox Shrinks with each update

I have a set of linked subs which work like this:
A user types into an ActiveX TextBox
A Change Event in that TextBox calls a sub in a Module
That Module sub drives updating a named range in a sheet
The range value drives updating a table of Excel cells that uses lookup functions based on the range value
The table values are copied and pasted to a another range (to eliminate links to formulas)
That pasted range is put into a ListBox using this (props to Rory for his patience):
ActiveSheet.ListBox1.List = Sheets("Search Criteria Control").Range("G1:G21").Value
The result is that for every character the user types in the TextBox the ListBox is updated.
The problem I have is that the ListBox shrinks a bit with every keystroke in the TextBox referred to in #1 above. Is this normal behavior and I'm misusing ListBoxes, am I doing something wrong or do I need to respecify the dimensions of the ListBox every time it is updated with something like this?
ActiveSheet.OLEObjects("ListBox1").Top = 35
ActiveSheet.OLEObjects("ListBox1").Left = 650
ActiveSheet.OLEObjects("ListBox1").Width = 550
ActiveSheet.OLEObjects("ListBox1").Height = 610
Thanks in advance for any thoughts on this.
I was having trouble with the same thing. My ActiveX listbox would move around on the sheet and change size for no reason that I could see.
While I did go ahead and develop some code to reset size and coordinates, that wasn't satisfactory since there had to be a mechanism to trigger that code - something I didn't want to burden end-users with.
I found a better answer in another user forum. There's a Listbox Property called IntegralHeight whose default property is True - something to do with screen resolution and optimal display of listbox contents. Simply set that to False. I did that with some ActiveX boxes that were giving me fits, and I was able to disable the "adjustment" code and, so far, so good!

How to reset Excel internal button count?

I have an an Excel sheet that uses VBA to generate some form control buttons on the fly.
the buttons are cleared and then new buttons are created.
I have noticed that even though old buttons are deleted Excel is keeping an internal register of each button. New buttons have button name of over 11K
I don't know if there is some sort of limit excel will allow for this and I don't want to run out of buttons.
I am not sure if this growing registry of buttons past is causing the file size to grow.
I would like to be able to reset the increment back to 0
Anyone have any idea how I can go back to button_0 ? (without starting a whole new Excel sheet)
Seems internal button count is sheet specific. Solution is to copy sheet, rename old sheet, then rename new sheet to old sheet name. Then delete old sheet. Viola! button count reset.
I found the answer somewhere in a forum, but I couldn't retrace it.
You could also pragmatically create the button by a function/sub-routine as a workaround.
Example: below function adds a button and limits the count to a fixed number (in my case, it is the total buttons available).
In my sheet, the first button is named "Button 687" (before I use the macro) and the second button is named "Button 2".
But, it is quite not dynamic when you want to add Drop Down or other form control etc. Macro recording helps you figure out the syntax, methods and properties of the form control you want to add though.
I am not sure why "buttons" is not listed in Properties/Methods after you typed "Activesheet." but Activesheet.Buttons(1).Name or Activesheet.buttons.add are valid codes.
Public Sub Add_Button(ButtonLabel$, ButtonSize#, BFontSize#, BFontName$)
Dim Button__ As Object
Dim One_Unit#: Per_Unit = Application.CentimetersToPoints(1)
'Creates a button at the sheet's first cell (row 1, col 1) with the height and width being 1cm.
Set Button__ = ActiveSheet.Buttons.Add(1, 1, One_Unit, One_Unit)
'button count will be restricted to the number set by user.
With Button__
.Name = "Button " & ActiveSheet.Buttons.Count
With .Characters
.Text = UCase(BLabel)
.Font.Name = BFontName
.Font.Size = BFontSize
End With
End With
End Sub
Sub AddAButton()
Add_Button BLabel:="SAVE"
Debug.Print ActiveSheet.Buttons(ActiveSheet.Buttons.Count).Name
End Sub

Custom Design of an Excel Textbox VBA

Well I was wondering whether we can somehow create custom looking text boxes that act as an input box and is linked to VBA.
As far as I am aware the standard procedure would entail adding an ActiveX Textbox Control and then using the TextBox1_Change event to add the code as to what needs to happen when the user enters something in to.
Sadly the look of the default textbox isn't matching the way I want by spreadsheet to look. So is there any way to change how it looks or have something replace it while serving the same purpose?
One thing I could think of and have tried is inserting a shape (blue):
Shape http://im52.gulfup.com/qD2F0B.png
I can get the text that is in the shape using VBA by:
InputText = Shapes("Rounded Rectangle 1").TextFrame.Characters.Text
But I don't suppose there is a way to detect a change of shape text event?
Suggestions / Workarounds are welcome!
Thanks
There are limitations on what you can change on an ActiveX TextBox, such as Font/Color/Border/SpecialEffects, but the basic rectangle shape cannot be changed.
However you can make the TextBox transparent by BackStyle property and group it to a shape (bring the TB forward) and still use the TextBox1_Change method for changes.
If you need to access the value in the TextBox somewhere else, a quick way is to use TextBox1.LinkedCell and below to set the value to a cell, or a Named Range.
Private Sub TextBox1_Change()
' Same Sheet as TextBox1
ActiveSheet.Range(TextBox1.LinkedCell).Value = TextBox1.Value
' Or Below for Named Range
ThisWorkbook.Names(TextBox1.LinkedCell).RefersToRange.Value = TextBox1.Value
End Sub