Using Word VBA, is it possible to access/get a reference to a chart object using the chart name?
In the Word interface, you can open the "selection pane", and specify a name for a chart. I would like to use that name property to access the chart in VBA.
If I can't use the name, I have to get a reference through a more cumbersome route by locating the chart as part of a range's InlineShape collection.
Set MyChart= wrdApp.Selection.InlineShapes(1).Chart
But that is very tedious, so it would be great to be able to navigate straight to the chart based on the name...
InlineShape-objects do not have a name property. If you convert them to shape objects they do, but you would still have to address them with InlineShapes(index) for the conversion:
Sub ShapeTest()
Dim oShp As Shape
If ThisDocument.InlineShapes.Count > 0 Then
Set oShp = ThisDocument.InlineShapes(1).ConvertToShape
MsgBox "Shape name = " & ThisDocument.Shapes(oShp.Name).Name
End If
Set oShp = Nothing
End Sub
(The sample is quite meaningless, but you get the idea)
EDIT:
Just checked the online documentation for InlineShape and it seems that the InlineShape object as a Name property in Word 2013 and later. Which version are you running? I only have access to Word 2010 where my ansewer above is true.
Related
I'm trying to record a macro that will set the size of a pasted image to 6.5 x 4 cms and the image layout 'in front of text'. I usually set this by right clicking on the image and setting the picture properties but this isn't available when recording the macro. Using Shift-F10 does bring up the menu, but the option to set the image layout properties is greyed out.
Please help!
Thanks
Yes, that's interesting about the macro recorder...
If you need to do something like this in the future it will help you to know that an object with any kind of "text wrap" formatting (that "floats") is a Shape. An object that behaves like a character is an InlineShape. And you can convert between the two using ConvertToInlineShape / ConvertToShape. For future things of this nature that should give you a starting point :-)
The following code sample uses ConvertToShape so that text wrap formatting can be applied. (The conversion is an extra step involved that you don't have to do in the UI - Word does it for you.)
Before this happens the code changes the size, but it could also be the other way around, changing the size on the Shape object.
What else is happening in the code: When a picture is pasted inline it's not selected. So this code figures out how many pictures (InlineShapes) are already in the document up to the selection. After the paste the code then picks up the existing number of pictures up to that point, plus one, to get the picture that was just pasted.
The code uses CentimetersToPoints to convert the number of centimeters wanted to the Points measurement, since that's what Word uses to size graphical objects (and lots of other things).
How did I know to use wdWrapFront: When shp.WrapFormat.Type = is typed the VBA Editor will automatically show a list of valid entries for text wrap formatting. Similarly, when shp. is typed a list of valid properties for a Shape will appear, and so on. (This is called IntelliSense and is a wonderful help!)
Sub PasteAndSelectPicture()
Dim ils As Word.InlineShape
Dim shp As Word.Shape
Dim lNrIls As Long
Dim rngDoc As Word.Range
Dim rngSel As Word.Range
Set rngDoc = ActiveDocument.content
Set rngSel = Selection.Range
rngDoc.End = rngSel.End + 1
lNrIls = rngDoc.InlineShapes.Count
rngSel.Paste
' Debug.Print rngDoc.InlineShapes.Count, lNrIls
Set ils = rngDoc.InlineShapes(lNrIls + 1)
ils.width = CentimetersToPoints(6.5)
ils.height = CentimetersToPoints(4)
Set shp = ils.ConvertToShape
shp.WrapFormat.Type = wdWrapFront
End SUb
What I have:
An Excel file where in a column (actually it is free formatted but aligned to be within a column) some elements are embedded bmp pictures that show the formula =EMBED("Paint.Picture","") when you click on them. When you look at the Excel sheet, only the icon representing the picture is displayed, not the picture itself.
What I want:
The embedded picture (not the icon) copied to a new Word document.
The Code I have thus far:
'Image Objects
Dim myObjs As Shapes
Dim myObj As Shape
Set myObjs = ActiveSheet.Shapes
'Traversing objects
Dim row As Integer
Dim myRange As Range
Dim myRange2 As Range
Dim isAddressMatch As Boolean
'Word Document Objects
Dim wordApp As New Word.Application
Dim myWord As Word.Document
'Prepare word for output
Set myWord = wordApp.Documents.Add
wordApp.Visible = True
'Initalize traversing objectts
Set myRange = Sheets("myWorksheet").Range("Q5")
Set myRange2 = Sheets("myWorksheet").Range("E5")
row = 0
'Loop through range values in the desired column
While (myRange2.Offset(row).Value <> "")
'Loop through all shape objects until address match is found.
For Each myObj In myObjs
On Error Resume Next
isAddressMatch = (myObj.TopLeftCell.Address = myRange.Offset(row).Address)
If Err.Number <> 0 Then
isAddressMatch = False
On Error GoTo 0
End If
'When match is found copy the bmp picture from Excel to Word
If (isAddressMatch) Then
myObj.Select
''''''''This copies the excel default picture,'''''''''''''''
''''''''not the picture that is embeded.'''''''''''''''''''''
myObj.CopyPicture 'What is the correct way to copy myObj
myWord.Range.Paste
'Rest of the code not yet implement
End If
Next
row = row + 1
Wend
What happens when I run my code:
My code goes through all "shapes" that are within the bounds of the column and copies that objects picture. However, when I paste it into word, it literally made a copy of the link image (icon), and not the underlying embedded image.
What I've found thus far:
This code which shows me how to create an embedded object, but not how to copy one.
Update: Simpler solution
As specified in the comments by jspek, the image can actually be copied by using the Copy method of the OLEObject, e.g.:
Dim obj As OLEObject
Set obj = ActiveSheet.OLEObjects(myObj.Name)
'Copy the OLE object representing a picture.
obj.Copy
'Paste the picture in Word.
myWord.Range.Paste
Old solution
I've found a suboptimal solution that involves both the clipboard and SendKeys - inspired by this link. I'm quite convinced that you can do this more elegantly by exploring ways to extract the OLEObject's properties. Extracting these is beyond the scope of my expertise at this time of writing :-)
It revolves around OLEObject. This code executes the OLE object's host application (which is Paint in this case) of your picture, sends keys to copy the picture and finally, pastes it into Word.
'Get the OLE object matching the shape name.
Dim obj As OLEObject
Set obj = ActiveSheet.OLEObjects(myObj.Name)
'Activate the OLE host application.
obj.Activate
'Send CTRL+A to select the picture in Paint and CTRL+C to copy it.
Application.SendKeys "^a"
Application.SendKeys "^c"
'Paste the picture in Word.
myWord.Range.Paste
I am not a coder, but I found that if you "Define Name" for a cell range, you can do all kinds of things with the defined names. For example:
Linking Excel Workbook rows to a Word document
1. Open your Excel work book go to Formulas -> Define NAME
2. Create a "NAME" for each of the cells or groups of cells that you would like to link.
For example, I hyper-linked a Question # in a Word document to my Excel document that is used for importing questions into our Learning Management System. Example NAME = Question_22 and refers to cell range =WBT16DS058!$A$90 (=worksheet!cellrange)
3. Save & close Excel workbook.
4. Open the Word document and create your text (Question 022) , highlight and insert a hyperlink.
5. Browse & Select your Excel document, append the end of the address to include #NAME. (i.e. - R312Test.xlsx#Question_22).
6. Select the new link, and your Excel document will open to the cell range.
Because you are defining a NAME for the range of cells, the link will stay active even when the cells are moved around.
I am wondering if you used "Define Name" for your cell range that includes the picture you are trying to embed, you will have luck.
My apologies if you have already defined the cell range's name and tried this.
I'm relatively new to VBA and have only very limited programming experience in general, but would really appreciate some help!
The ultimate goal is to pass (formatted) text from a text box in PPT as a variable between presentations. I believe it is important that the (formatted) text be passed as a variable, because the variable will be used to generate the body of an email (that part of the code is done, but I'm trying to create the guts of that variable here). Unfortunately, I have no idea how to pass a variable in VBA. I think I've figured out how to grab the text, but the simple formatting (bold, text size differences, etc) is lost. Help please? :-)
Dim headlines
headlines = ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange.Text
You could set an object variable of type TextFrame and then set that to your shape's TextFrame in order to pass it between various apps.
e.g.
Dim myFormattedText as TextFrame ' or TextFrame2 to access all of the newer properties
Set myFormattedText = ActivePresentation.Slides(1).Shapes(1).TextFrame ' or TextFrame2
That way you have all of the text properties within that object.
This should help get you going. It copies a shape object, which contains all of the formatting properties you want, from one open presentation to a second open presentation. In reality, you would make the presentation, slide and shape references dynamic based on what you're trying to achieve but this is a working example to demonstrate the principle:
Option Explicit
' Macro to copy the first shape from the first slide of open presentation 1 to the first slide of open presentation 2
' Requires that 2 presetnations are open and that the first has a shape on slide 1
' Wriiten by Jamie Garroch of youpresent.co.uk
Sub PassTextBoxBetweenPresentations()
Dim oSrcShp As Shape ' Source Shape in Presentation 1
Dim oTgtShp As Shape ' Source Shape in Presentation 2
' Set a reference to a shape in the first presentation, in this case, the first shape on the first slide
Set oSrcShp = Presentations(1).Slides(1).Shapes(1)
' Copy the shape (with all of its properties) to the clipboard
oSrcShp.Copy
' Paste the shape from the first presentation to the second presentation
Presentations(2).Slides(1).Shapes.Paste
' Set a reference to the pasted shape
Set oTgtShp = Presentations(2).Slides(1).Shapes(Presentations(2).Slides(1).Shapes.Count)
' Do stuff with your pasted shape object
With oTgtShp
Dim headlines
If .HasTextFrame Then
If .TextFrame.HasText Then
headlines = .TextFrame.TextRange.Text
Debug.Print headlines
End If
End If
End With
' Clean up
Set oSrcShp = Nothing: Set oTgtShp = Nothing
End Sub
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
I had assigned object names to objects in a 2007 Powerpoint file for automation purposes. I ran the automated code in another machine which has office 2003 and found that the object names are dynamically changing there hence the automated code throws an error.
I tried renaming the objects again in that machine using VBA and it works while debugging. But the error throws up when I rerun the automation code.
Is it a compatibility issue between the 2 versions or something else?
that was my problem with differentversions of Word. Generally, Code to the highest version of PowerPoint might not be supported under earlier versions. but sometimes the code works but the method which it refereed may be caused the problem.
I recommend use late binding (... As Object) to solve the problem
revision with an example:
The difference is that you bind the object library in code at run-time. You don't use Tools-References. something like that:
Sub ppt()
Dim olApp As Object
Set olApp = CreateObject("PowerPoint.Application")
End Sub
By "object names", do you mean shape names? Ie the shape's .Name property? This does seem to be buggy.
Consider using tags on the shapes you need to work with. For example, assuming a reference to your shape in oSh, instead of using oSh.Name = "Remember me", do something like:
oSh.Tags.Add "ShapeName","RememberMe"
Then when you need to get a reference to a shape, use a function like:
Function ShapeNamed(oSl as Object, sName as string) as Shape
Dim oSh as Shape
For Each oSh in oSl.Shapes
If oSh.Tags("ShapeName") = sName Then
Set ShapeNamed = oSh
Exit Function
End If
Next
End Function
oSl is declared as Object rather than Slide so you can pass the function Slides, Masters, Layouts, etc.