As far as I know, in Excel we can assign macros to several kinds of objects: shape, Form Control, ActiveX Control...
I would like to write a VBA code to do the following, given an Excel file:
Go through all the existing objects which are eligible to be assigned to a macro
For each object found, print its name and the name of its macro (or ideally the body as well) if a macro is assigned.
I would like this to be exhaustive, could anyone help?
Extending #mehow answer for shapes located in ActiveSheet the following code will result with names of shape and it's macro name if one associated.
Sub getShapeMacro()
'to secure for unexpected...
On Error Resume Next
Dim SHP As Shape
For Each SHP In ActiveSheet.Shapes
Debug.Print SHP.Name, SHP.OnAction
Next
End Sub
Related
I'm using a userform to collect data and add it to an empty line in a workbook.
Structure of code is as follows:
Main sub s_OpenWriteToTargetFile is called from userform mainForm.
It checks availability of the target workbook.
It opens the target workbook.
It calls sub "s_WriteLines". Everything is OK up to this point.
Sub s_WriteLines should load textbox values from mainForm into various variables and paste them into the target workbook.
For some reason, code execution jumps out of s_WriteLines as soon as it reaches With MainForm..., and it returns to the mother sub.
s_WriteLines sub
Sub s_WriteLines
Dim a,b as integer
With mainForm
a = .tb_a.Value
b = .tb_b.Value
End With
End Sub
I can't wrap my head around it. Does this have something to do with the modality of the userform?
As AcsErno suggested in the comments, there was a on error resume next that I didn't notice, and it kept me from learning that the form is failing to load a rowsource property of a combobox.
The rowsource was specified as follows:
mainForm.cb_Wiresize.RowSource = wiresizesWSheet.Name & "!" & wiresizesFinalRange.Address
The workbook that is opened to be written in also becomes active, and then the range that I specified as rowsource refers to a worksheet that doesn't exist - because I specified it only as "worksheet + range", instead of "workbook + worksheet + range".
To expand on my question, how can I refer to the specific workbook object using the syntax posted above? I tried different formulations but none worked.
I have an Excel sheet with four shapes and a couple of buttons to run macros. The shapes are named topCircle, leftCircle, rightCircle & midCircle.
Wanting one of the buttons to run a macro that copies the four shapes to clipboard, for pasting into other Office docs.
Have been though various MSDN articles (like https://msdn.microsoft.com/en-us/library/office/ff940375.aspx) but having trouble. Trying to imitate the example on the linked article, I wrote this:
Set myDocument = Worksheets("Overall")
myDocument.Shapes.Range(Array("leftCircle", "rightCircle", "topCircle", "midCircle")).Copy
But getting an error "Object doesn't support this property or method". Have also tried a few other things without luck. Any ideas as to how to get this to work? Cheers!
It seems that to copy multiple shapes from an Excel worksheet you have 3 options:
Option 1: Use Select first to select all Shapes, and then copy the Selection :
myDocument.Shapes.Range(Array("leftCircle", "rightCircle", "topCircle", "midCircle")).Select
Selection.Copy
Option 2: Use the Group to group all selected shapes, then copy them together, and afterwards use the Ungroup to split them back:
With myDocument.Shapes.Range(Array("leftCircle", "rightCircle", "topCircle", "midCircle"))
.Group.Copy
' paste to wherever you want
.Ungroup
End With
Option 3: use For Each MyShape In myDocument.Shapes to loop through all Shapes in myDocument worksheet, and if it mathces one of the Shape.Name you wanted it, copy it:
Dim MyShape As Shape
For Each MyShape In myDocument.Shapes
Select Case MyShape.Name
Case "leftCircle", "rightCircle", "topCircle", "midCircle"
MyShape.Copy
' paste to wherever you want
End Select
Next MyShape
I am attempting to call the below Sub in order to copy given chart to a specified PowerPoint presentation. However, when I run the macro which calls this Sub, the line indicated below returns the following error: "Object doesn't support this property or method." What's odd is that both Shapes and Slide do contain the methods which are called. As well, the bitmap is correctly copied to my clipboard and pastes into the slide before the error is called. You will find the Sub() below.
Sub copyChart(chrt As Chart, pres As PowerPoint.Presentation)
Dim curSlide As Slide, dummySlide As Slide
Set dummySlide= pres.Slides(2) 'Second slide is dummy slide.
Set curSlide = dummySlide.Duplicate(1) 'Duplicate dummy, set as current slide.
chrt.CopyPicture Appearance:=xlScreen, Format:=xlBitmap 'Copy the chart as a picture.
curSlide.Shapes.Paste '<-----------Error here.
End Sub
As well, I was hoping to provide a .txt file of my entire script, but was unsure how (it is a little lengthy to paste here). Thanks for your help.
(Note that this implementation is very similar to that at Paste Excel Chart into Powerpoint using VBA, further confusing me.)
I have had a lot of trouble in recent versions of Office. 2003 and earlier didn't have this problem, 2007 and 2010 had it a bit, and 2013 and 2016 have it in spades.
When you step through the code it works fine, but when you run it at full speed, it errors on the paste.
It's as if the copy doesn't have time to finish finish, so when you paste the clipboard doesn't have anything in it yet to paste.
Sometimes this helps:
chrt.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
DoEvents
curSlide.Shapes.Paste
DoEvents tells VBA to wait while background operations have a chance to finish up.
It looks like the error can be attributed to how VBA handles variables across different references. (In particular, how PPT VBA handles them.) I was able to get the macro to work by actively selecting/copying the charts. I will need to do a little more research to get why variables cause problems, but at least I know how tackle the problem.
Sub copyChart(curSlide As Slide)
Dim chr as ChartObject
Set chr = Sheets("CHARTSHEET").ChartObjects(1)
Sheets("CHARTSHEET").Select
ActiveChart.CopyPicture
curSlide.Shapes.PasteSpecial
End Sub
I like to use another method, I like to define an Object, then set it to the pasted Chart. Afterwards, it's much easier modifying the pasted Chart object's parameters inside PowerPoint (from Excel).
See code below:
Sub copyChart(curSlide As Slide)
Dim chr As ChartObject
Dim myChart As Object
Set chr = Sheets("CHARTSHEET").ChartObjects(1)
chr.Copy
' setting myChart object to the pasted chart (let's me later an easy way to modify it's parameters)
Set myChart = curSlide.Shapes.PasteSpecial(ppPasteBitmap, msoFalse) ' can change first parameter to other avaialabe formats : ppPasteGIF, ppPasteEnhancedMetafile, ppPasteOLEObject, etc.
' set different parameters for the pasted chart in PowerPoint slide
With myChart
.Left = 200
.Top = 200
End With
End Sub
In the code line:
Set myChart = curSlide.Shapes.PasteSpecial(ppPasteBitmap, msoFalse)
You can change the first parameter in brackets: ppPasteBitmap to many other avaialble formats (test them and see which one gives you the best result), such as: ppPasteGIF, ppPasteEnhancedMetafile, ppPasteOLEObject, etc.
I have a macro that creates a summary sheet at the front of a Workbook. Shapes are created and labeled after the sheets in the workbook and then hyperlinks are added to the shapes to redirect to those sheets, however, when I recorded the macro to do this, the code generated was:
ActiveSheet.Shapes.Range(Array("Rounded Rectangle 1")).Select
ActiveSheet.Hyperlinks.Add Anchor:=Selection.ShapeRange.Item(1), Address:=""
The hyperlinks that were manually created in excel while recording the macro work just fine and when hovering over them, display the file path and " - Sheet!A1" but they don't seem to actually be adding the link location into the address portion of the macro. Does anyone know the code that should go in that address section to link to the sheet?
The macro recorder doesn't record what is actually happening in this case. The property you are looking for is SubAddress. Address is correctly set in your code.
Create a hyperlink from a shape without selecting it
You want to avoid selecting things in your code if possible, and in this case it definitely is. Create a shape variable and set it to the shape you want to modify, then add the hyperlink to the sheet the shape is on. Note that you can also set the text for the screen tip.
In the example below, the shape I want to modify is on Sheet 6, and hyperlinks to a range on Sheet 4.
Sub SetHyperlinkOnShape()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet6")
Dim hyperLinkedShape As Shape
Set hyperLinkedShape = ws.Shapes("Rectangle 1")
ws.Hyperlinks.Add Anchor:=hyperLinkedShape, Address:="", _
SubAddress:="Sheet4!C4:C8", ScreenTip:="yadda yadda"
End Sub
I have an error during initialization and I do not get why this is not working:
Private Sub Workbook_Open()
Dim ws As Worksheet
Set ws = Worksheets(1)
ws.ComboC15.AddItem "Technology"
end sub
It is very weird, the code should be correct. I have checked the combo name and it is "ComboC15".
In fact, this is the sub:
Private Sub ComboC15_Change()
Ps: I also checked the sheet and it is the first sheet where I have the Combo
The Worksheet object in VBA doesn't have a property or method called ComboC15, as this is entirely your own invention. However, the individual worksheet object in your workbook, i.e. the sheet itself as a physical sheet and not as a VBA sheet, knows all about ComboC15 since it's been dropped on it by you. Therefore, you need to access the worksheet object (notice the little w) and not the Worksheet object (notice the big W). If it's confusing to read, imagine how confusing it is for me to try to explain this...
To get access to the worksheet Object, you can do any of the following:
' Assuming "Sheet1" is the code name of the object. You can find this code name
' in the VBA editor. In the "Project Explorer" window, look under Microsoft
' Excel Objects. Your sheets are listed there in the form (for a blank, new
' workbook) "Sheet1 (Sheet1)". The bit *outside* the brackets is the code name.
Sheet1.ComboC15.AddItem "Technology"
' You can even call it directly from the "Worksheet" object by using the sheet
' index.
Worksheets(1).ComboC15.AddItem "Technology"
However, if you want to create a variable with it so you don't have to copy/paste the same thing over and over, declare it as an Object and not as a Worksheet. So do this:
Private Sub Workbook_Open()
Dim ws As Object ' Declare ws as "Object"!
Set ws = Worksheets(1)
ws.ComboC15.AddItem "Technology"
End Sub
The following SO Q&A explains a bit more about the different kind of sheet names:
Excel tab sheet names vs. Visual Basic sheet names
and I hope this article might give you a better insight on how to reference different kinds of objects in VBA.