I am currently working on an Excel tool that I have equipped with one button and one shape-object.
The button is a select button to "select" the shape object. The idea is to Select a shape-object a Picture and change its color after selecting it.
I was able to locate the problem to the clicked Sub of the Select button.
To check if I'm correct I have written a the Macro Select_MyClicked and afterword used the call instruction to invoke the macro from within the Clicked-function of the select button.
Sub Select_MyClicked()
Dim ElementName As String
Dim Shp As Object
Set Shp = Sheets("Tabelle1").Shapes(ElementName)
Shp.Select
End Sub
==================================================================
Private Sub CommandButton3_Click()
Call Select_MyClicked
End Sub
==================================================================
What is interesting now is:
When I use the Button the Image is selected but in the Picture format register there i nothing selectable
If I cklick on the Image itselfe or use the Select_MyClicked Macro indepentently everything in the picture format register is selectable
I also tried to write the select instruction directly into the Button-Clicked private sub. Same result nothing selectable
What I want to do is select an image and change its color. My second question is does somebody know how to open the Colorpennel (with the many colored Rectangles) using vba ?
You need to reference the Shape by its Name. I assigned the name "myshape" to the Shape before running:
Sub Select_MyClicked()
Dim ElementName As String
Dim Shp As Shape
ElementName = "myshape"
Set Shp = Sheets("Tabelle1").Shapes(ElementName)
Shp.Select
End Sub
The code runs even if Tabelle1 is not the active sheet.
I have finally find the solution. It seems like it makes a difference which button you use. In my case it had to be the control elements not the activeX elements
Related
This is the first time I use VBA.
I want to create simple checkboxes using Activex label (not using form label because then I wouldn't be able to edit the font, etc).
I use this code along with Wingding font:
Private Sub Label1_Click()
If Label1.Caption = Chr(254) Then
Label1.Caption = Chr(168)
Else
Label1.Caption = Chr(254)
End If
End Sub
I have multiple labels to act like checkboxes.
So I applied the code above to one label and copy paste that label.
However, the code did not adjust to the new labels' name.
How do I copy paste labels along with its vba?
Or is there a line of code that I can add to mine so that the vba refers to all labels in my worksheet, not just one particular label?
Well, for such a purpose it was easier to handle Form labels. In such a case you could assign to all of them the same Sub and identify the object using Application.Caller...
In order to handle the ActiveX control you need a class:
Insert a class module, name it and paste the next code:
Option Explicit
Public WithEvents lbl_Control As msForms.Label
Public Sub lbl_Control_Click()
MsgBox lbl_Control.Caption ' you can do here whatever you want with the object...
End Sub
All labels for the sheet in discussion should be (somehow) initialized to use the above class for their Click event. So, please copy the next code in the Activate event or the respective worksheet:
Option Explicit
Private arrEvents As Collection, lblEvent As ClsLabels
Private Sub Worksheet_Activate()
Dim shP As Shape
Set arrEvents = New Collection
For Each shP In Me.Shapes
If shP.Type = msoOLEControlObject Then
If TypeOf shP.OLEFormat.Object.Object Is msForms.Label Then
Set lblEvent = New ClsLabels
Set lblEvent.lbl_Control = shP.OLEFormat.Object.Object
arrEvents.Add lblEvent
End If
End If
Next
End Sub
Activate another sheet and go back to the one where labels in discussion exist, in order to trigger the Worsheet_Activate event.
Now, click on the respective labels and enjoy the message...
Change their caption, dezactivate - activate the sheet and click on them.
In case of using Form labels, you should simple create a Sub:
Sub ChangeLBlCaption()
MsgBox "Label name: " & Application.Caller
Dim lbl As Label
Set lbl = ActiveSheet.Labels(Application.Caller)
MsgBox "label Caption: " & lbl.Caption
End Sub
Then, only assign this sub to all Form labels you need to return their name. It can be done automatically, too...
This second label type assures a more reliable handling for such a purpose. Since, in ActiveX case all labels must be reinitialized, from event class allocation point of view, after a VBA error and code stop, putting the label in Design mode to modify its caption (for instance) etc.
I am new to VBA. i have few shapes in a worksheet.
I want to get the name of shape to appear in combobox and character name in another Combobox, when any particular shape is selected. so i can rename that shape and link to particular excel column.
i have tried following.
With Selection
ActiveSheet.ComboBox1.Value = ActiveSheet.Shapes(Application.Caller).Name
End with
Not sure where to assign above code.
I tried assigning above code to a shape with .onaction as macro, it work but a marco assiged shape cannot be edited further(For design purpose).
Also It would be great if i can delete selected shape.
Thank you in advance.
You can use your code for any shape and you can change the code whenever you want, but assigning a macro, she shape will will not be selected when clicked... It becomes a kind of control.
Excepting the case when you force it to select:
Debug.Print ActiveSheet.Shapes(Application.Caller).Name
shW.ComboBox1.value.Shapes(Application.Caller).Select
You can change the code from right click context (on the chart bottom side) and choose 'Assign Macro... -> Edit'.
You can find the selected shape using the next code:
Sub testSelectedShape()
Dim shW As Worksheet, sh As Object, selSh As Object
Set shW = ActiveSheet
If TypeName(Selection) <> "Range" Then
Set selSh = Selection
Set sh = shW.Shapes(selSh.Name)
Debug.Print selSh.Name
shW.ComboBox1.value = selSh.Name
End If
End Sub
You can delete it simple using sh.Delete...
I am struggling try to solve an easy problem.
I have check boxes in Sheet 1 and check boxes in sheet 2 that have to assume the same value (TRUE or FALSE) of the ones in Sheet 1.
The problem is that when I open Sheet 2 they are not marked but I have to click on them with the mouse.
I'm using this code:
Sheet2.chk_2A.Value = Sheet1.chk_1a.Value
Am I forgetting an auto update command or something similar?
As far as I can tell there is no need for VBA code here if you link the two check boxes to the same cell. Just assign both check boxes the same cell in Format Control..., Control, Cell link:. If that's not an option then you'll have to place your code into a sub and assign this sub to these check boxes upon click.
In this case your code depends if you used form controls or ActiveX controls. For Form controls you'd have to use
Sheet2.Shapes("chk_2A").controlformat.value = Sheet1.Shapes("chk_1a").controlformat.value
and for ActiveX controls your code suggestion should work if the check boxes are named correctly.
Sheet2.chk_2A.value = Sheet1.chk_1a.value
In both cases I assume that you used either form controls or ActiveX controls. If you used one form control and one ActiveX control then you'll have to adjust the above code suggestions accordingly. The following code can help you determine what you used.
Public Sub AllShapes()
For Each ws In ActiveWorkbook.Worksheets
For Each shp In ws.Shapes
Debug.Print shp.Name
Select Case shp.Type
Case 8
Debug.Print "Form Control"
Case 12
Debug.Print "ActiveX Control"
Case Else
Debug.Print shp.Type
End Select
Next shp
Next ws
End Sub
I am looking to write a macro which copies formatting from one graph and applies it to multiple other graphs.
What I am struggling to do is determine a way to allow the user to set the template chart and then select the multiple other charts. While this could be done with a combo box if the user knew the chart name, I am trying to do it without them knowing the chart name.
As such I was thinking of having a user dialog box where the user can select the base chart, and then select the charts to apply the formatting to. Just like refedit for a range. However I cannot figure out how to reference to a graph from within a user form.
Can this be done, and if so, how?
Here is what will get you started.
Place Two ComboBoxes and two Image Controls on the userform.
Let's say your worksheet looks like this
In the UserForm_Initialize() event populate the Chart names in both the comboboxes. For example
Dim ws As Worksheet
'~~> Prepare your form
Private Sub UserForm_Initialize()
Set ws = ThisWorkbook.Sheets("Sheet1")
Dim ChartObj As ChartObject
For Each ChartObj In ActiveSheet.ChartObjects
ComboBox1.AddItem ChartObj.Name
ComboBox2.AddItem ChartObj.Name
Next ChartObj
End Sub
So when you run the form, it will look like this
In the click event of the comboboxes, use the Stephen Bullen's PastePicture code from HERE to show the chart in the userform. For example
Private Sub ComboBox1_Click()
ws.Shapes(ComboBox1.Value).CopyPicture
Set Me.Image1.Picture = PastePicture(xlPicture)
End Sub
Private Sub ComboBox2_Click()
ws.Shapes(ComboBox2.Value).CopyPicture
Set Me.Image2.Picture = PastePicture(xlPicture)
End Sub
This is how the form will look.
From there on, Now you have the names of the charts. Simply use them to work as you please.
Hope this helps.
The following code should allow you to do stuff with the selected chart area(s), where you can either select one or many charts:
Public Sub ProcessSelectedCharts()
Dim i As Integer
Dim chart_obj As ChartObject
Dim chart_area As chartArea
If TypeOf Selection Is DrawingObjects Then
For i = 1 To Selection.Count
If TypeOf Selection(i) Is ChartObject Then
Set chart_obj = Selection(i)
Set chart_area = chart_obj.Chart.chartArea
Call ProcessChart(chart_area)
End If
Next i
ElseIf TypeOf Selection Is chartArea Then
Set chart_area = Selection
Call ProcessChart(chart_area)
End If
End Sub
Public Sub ProcessChart(obj As chartArea)
' Do something...
End Sub
You may want to refine this a little, i.e. this should work if the user selects the actual charts, but may fail if he only selects a particular element within the chart.
Ok, the next question is, when do you invoke this from your user form. So first of all, your user form should be modal of course, to allow the user the select anything. So how do you notice when the users actually selects anything?
I can think of three methods, and I'll list them from best to worst (the last 2 only described very briefly as I wouldn't recommend using them):
Use the "Worksheet_SelectionChange" event on your worksheet, and have it call a method within your userform to inform it that the selection has changed. Now you'll just need to check if, and which charts have been selected (see code above), and run your algorithm.
Run a timer in your userform and regularly check the active selection.
Hook mouse events by DLL calls and register any mouse clicks, then check for selection changes.
That should allow you to create a ref-edit like feature for selecting charts on your worksheet from a userform.
Scenario: I have tons of images in a single worksheet,and many of them are overlapping with each other.
How can I write a VBA code so when user click on any image in that worksheet and Excel will automatically bring that image to the front?
If you have an object myObject that you want to bring to the front you use
myObject.ShapeRange.Zorder msoBringToFront
http://msdn.microsoft.com/en-us/library/office/aa213680(v=office.11).aspx
Your object might for example be the selection:
set myObject = Selection
As for responding to a click - that's trickier. There doesn't appear to be an event for "selecting a picture" . But there is a solution...
You can make a single macro called Picture_click(), and assign that macro to each picture. There doesn't appear to be an event-driven way to achieve this, but the following works:
Add the following to a module:
Sub picture_click()
ActiveSheet.Shapes(Application.Caller).Select
Selection.ShapeRange.ZOrder (msoBringToFront)
End Sub
Sub connect_all()
Dim sh As Shape
For Each sh In ActiveSheet.Shapes
sh.OnAction = "picture_click"
Next sh
End Sub
You have to run the connect_all sub just once, to assign the picture_click macro to each shape. Now, when you click a picture (or other shape) it comes to the front.
Note - the Application.Caller tells you what object was clicked - in other words, what caused the call to picture_click. This is necessary because the "click" doesn't cause the picture to be selected yet - that happens after the macro has run. So you can't just use the selection. Tricky, that.
I referenced this earlier post to come up with this solution - specifically, RichJ's solution.
afterthought
If you don't want the picture to be selected after you clicked it, you can modify the picture_click() sub to the following:
Sub picture_click()
ActiveSheet.Shapes(Application.Caller).ZOrder msoBringToFront
End Sub
This will move the picture to the front but doesn't select it. There is something to be said for that approach.
With every shape, assign the BringToFront macro, then put the following in a module
Sub BrintToFront
Selection.ShapeRange.ZOrder msoBringToFront
end sub
Assign this macro to all Shapes:
Sub lux()
ActiveSheet.Shapes(Application.Caller).ZOrder msoBringToFront
End Sub