I am trying to link and insert a picture (*.png) into a shapes fill in powerpoint using vba in Excel. In the end I will loop through this on 100+ pages and the pictures will be updated frequently so automating this will be a huge time saver. Currently I have figured out how to loop through the pages and insert the pictures into the shapes, but I have been unable to figure out how to link the pictures too.
I'm using the below code to fill the shape with the picture but I can't find the syntax to both insert and link it:
Pres.Slides(1).Shapes(ShapeName).Fill.UserPicture PictureFilePath
Ultimately this should behave like clicking on a shape, going format > shape fill > picture > insert and link (On the drop down next to insert in the dialog box).
Not all user interface actions are in the VBA object model. One of those exceptions is creating a link to a shape fill. The closest you can get is to link pictures that are inserted as pictures rather than as fills. Here's the syntax to add a linked picture. It assumes the picture is in the same folder as the presentation:
Sub Macro1()
ActiveWindow.Selection.SlideRange.Shapes.AddPicture(FileName:="Picture1.png", LinkToFile:=msoTrue, SaveWithDocument:=msoFalse, Left:=300, Top:=251, Width:=121, Height:=38).Select
End Sub
Welcome to SO.
For answering your question, I'll give some credit to this similar SO question based on Excel and this similar SO question based on PP. Some additional information was gathered from the microsoft documentation on the subject.
What you seem to be looking for is the ActionSetting object in the shapes class, which seems to be availible to shapes in PowerPoint. Below is a code snippet created directly in PowerPoint VBA
Sub insertPictureIntoShapeWithLinkToPicture()
Dim PP_Slide As Slide, PP_Shape As Shape, imagePath As String
Set PP_Slide = ActivePresentation.Slides(1) 'Set slide (change as necessary)
Set PP_Shape = PP_Slide.Shapes(1) 'Set shape (change as necessary)
imagePath = "Path to image"
With PP_Shape
'add picutre
.Fill.UserPicture imagePath
'Set an action on click
With .ActionSettings(ppMouseClick)
'Set action to hyperlink
.Action = ppActionHyperlink
'Specify address
.Hyperlink.Address = imagePath
End With
End With
End Sub
The same approach should be available via Excel, either adding a reference to the PowerPoint object library, or using Late-Binding methods. Note that the 'click' method with hyperlink defaults to standard hyperlink clicking (ctrl + left mouse for windows with a Danish keyboard).
Please find attached code.
First create a shape in PPT and run the code.
Related
Please, can someone help me!
I have a userform which is called Configurator or "Config", which has some Image-Controls.
These images together look like a door, because the userform is a configurator for doors.
(where you can change width, height, material etc...)
Mostly the "door" consists of 4 different images which make the doorframe.
Now i want to use these images on my excel-worksheet, so the user sees a picture of the door on
the worksheet too.
Which method is the best way?
I tried to copy & paste the images from userform to a excel worksheet, but i dont know how.
I hope someone of you can show me the right way to do this!
Another way could be to somehow make a screenshot of a specific area of the userform
and paste the image to the worksheet. I dont know if there is a way to do this?
Thanks for any help!
Please, try the next way:
Let us say that pictDoor1 is the name of the picture you need to 'copy' and a new button to copy it (copyPicture). Copy next code in its Click event:
Private Sub copyPicture_Click()
Dim shPict As MSForms.Image, pic As MSForms.Image
Set pic = Me.pictDoor1 'use here the real name of the Image control
Set shPict = ActiveSheet.OLEObjects.Add(ClassType:="Forms.Image.1", link:=False, _
DisplayAsIcon:=False, left:=20, top:=20, width:=pic.width, height:=pic.height).Object
shPict.Picture = pic.Picture
End Sub
It will insert an Image control (as the picture to be copied dimensions, cut you can change them by multiplying, if need bigger ones) and place on it the necessary picture.
Then, use the newly created shape top and left according to the previously created width and height to appropriately position them...
I have added a few shapes to my worksheet. I have assigned macros to them. But I had to create separate macros for all.
Is there a way for excel to recognize which shape was clicked and based on its text value find the cell to copy. That way I need not have to create separate macros for each shape.
I have tried searching for it online, found a few things which I tried but did not work.
Any help would be greatly appreciated.
Yes, the Application.Caller property can be used here.
Option Explicit
Public Sub MyShapeMacro_Click()
Dim CalledByShape As Shape
Set CalledByShape = ActiveSheet.Shapes(Application.Caller)
'CalledByShape is your shape
Debug.Print CalledByShape.OLEFormat.Object.Text 'returns the text of the shape
End Sub
Link this macro MyShapeMacro_Click to all your shapes.
Note this macro cannot be started in the VBA editor (it will throw an exception) it can only be run by clicking the shape.
I'm sorry to be posting another PasteSpecial-question, but I haven't found something that relates precisely to what I'm trying to do.
I have some VBA code:
For Each Workbook In Workbooks
For Each Sheet In Workbook.Sheets
running_pp_app.ActivePresentation.Slides.Add running_pp_app.ActivePresentation.Slides.Count + 1, ppLayoutTitleOnly
Sheet.Range("a1:b2").Copy
running_pp_app.ActivePresentation.Slides(running_pp_app.ActivePresentation.Slides.Count).Shapes.PasteSpecial DataType:=ppPasteDefault, link:=msoCTrue
Next Sheet
Next Workbook
When I paste the Excel-range into a slide, I ultimately want to have the pasted range/shape occupying a placeholder in the slide-layout. I don't want it to be just some additional shape on the slide.
Ultimately, my goal is to be able to easily control all of the pasted ranges/shapes via master-layouts (via the UI, after my VBA runs). I don't know how to paste the linked OLE object into the slide so that it occupies a placeholder-position--so that it is the "content" in the "Title and Content" master-layout, for example.
How can I do this?
All help is appreciated. Thanks.
My first thought was that this doesn't appear to be possible. This works to paste into a placeholder:
Sub PasteIntoPlaceholder()
ActivePresentation.Slides(1).Shapes(2).Select
ActiveWindow.View.PasteSpecial DataType:=ppPasteDefault
End Sub
But as soon as you add the link parameter, it pastes as a separate shape, not in the placeholder.
This mostly corresponds to analogous actions in the user interface. A straight Paste onto a slide with a selected placeholder will insert the chart as expected, but a Paste Special will not.
Revision:
Following your suggestion, this mostly does the job. The placeholder shrinks to fit the pasted Excel object instead of the Excel object expanding to fit the placeholder, but hey, it works:
Sub PasteIntoPlaceholder()
With ActiveWindow
.View.PasteSpecial DataType:=ppPasteDefault, Link:=msoCTrue
.Selection.Cut
ActivePresentation.Slides(1).Shapes(2).Select
.View.Paste
End With
End Sub
I am looking at inserting/pasting a range of text data (40 columns) from Excel into bookmarks in Word. Most of the answers are done using Excel VBA, which is so not practical for my use case as I will have the Word document open, add a button that would run this 'import data' macro. I actually already have a button in the doc that inserts images into bookmarks, so that's one more reason I don't want to do it via Excel VBA.
I know this is not great code, but for the lack of definite leads, I'm throwing it here and hope that this gives you an idea of what I'm trying to achieve:
Sub ImportData()
Workbooks.Open ("\Book2.xlsm")
ActiveWindow.WindowState = xlMinimized
ThisWorkbook.Activate
Windows("Book2.xlsm").Activate
Range("A1:AF1").Select
Selection.Copy
Documents("test.docm").Activate
Selection.GoTo What:=wdGoToBookmark, Name:="Overlay_1"
Selection.Paste
End Sub
PS: It would be great if I could sort of 'transpose' the 40 columns into rows as it is pasted in Word.
Here's an update to my code based off #Variatus 's advice:
Sub ImportData()
Dim wb As Workbooks
Dim ws As Worksheets
Dim objSheet As Object
Dim objWord As Object
Set objWord = CreateObject("Word.Application")
wb.Open ("C:\Users\pc\Documents\Book2.xlsm")
Set objSheet = CreateObject("Excel.Application")
ActiveWindow.WindowState = xlMinimized
Set ws = Workbooks("Book2.xlsm").Sheets("Sheet1")
ws.Range("A1").Value.Copy
With objWord.ActiveDocument
.Bookmarks("Bookmark_1").Range.Text = ws.Range("A1").Value
End With
End Sub
I'm getting this error:
Runtime Error '91':
Object variable or With block variable not set.
Notice how I stuck with a single cell reference for now (A1). I'll just update my code as I learn along the way :)
When you click the button in your Word document you want the following sequence to be initiated.
Create an Excel application object. Make sure that a reference to Excel has been set (VBE > Tools > References) so that Excel's VBA objects are available.
Using the Excel application object, open the workbook. Create an object. Place the object in an invisible window.
Definitely forget about activating or selecting anything in either the workbook or your Word document. The latter is active and remains active from beginning to end. The bookmarks are points in your document you can reference and manipulate by name without selecting them. The Excel workbook is invisible. You can access any part of it using the Range object.
The data you want from your workbook are contained in Worksheets. Be sure to create an object for the worksheet you are about to draw data from.
Excel tables don't translate very well into Word tables. If you do want to go that way I suggest that you use VBA to create the table you want in Excel (transpose the data before you import them into Word). However, you may find it easier to first create the tables you want in Word and then just copy values from your Excel source into the word tables. That would involve taking one cell value at a time and placing it into one Word table cell. Transposing would be done by the algorithm you employ.
Close the workbook. Quit the Excel application. Set the Excel application = Nothing. At the end of your macro everything is as it was before except that your document has data in it which it didn't have before.
Each of the above six points will lead you to at least one question which you can ask here after you have googled the subject and written some code. In fact, I strongly urge you to create one Main procedure (the one which responds to your button click) and let that procedure call various subs which carry out the individual tasks and functions to support the subs. The smaller the parts you create the easier it is to write the code, to find questions to ask and get answers to them. If you plan your project well expect to have about 12 procedures in it by the time you are done. Good luck!
I'm using VBA to generate an Excel sheet which includes ActiveX form controls. However the documentation available for the object properties is rather sketchy. I notice that when I create, for example, an OptionButton control, the object includes a solid white border. I can manually go into Design Mode; right-click; "Format Object", then under the "Colors and Lines" tab in the dialogue box, change Fill (Automatic) to "No Fill". See the following example:
However I have yet to work out how to do this through code. Please see the following:
Dim sht as Sheet
Set sht = [WorkbookObject].Sheets(1)
With sht
.OLEObjects.Add(ClassType:="Forms.OptionButton.1", Left:=4.5, Top:=34.5, Width:=105, Height:=15).Name = "RadioB_1"
With .OLEObjects("RadioB_1").Object
.Caption = "First Option"
.GroupName = "ColumnFilter"
.BackColor = RGB (128, 128, 128)
.BackStyle = 1
End With
' The above all works fine, however I can't find the correct property
' for the border fill. I have tried various properties for
' .OLEObjects("RadioB_1") and for .OLEObjects("RadioB_1").Object
' however I can't find the correct property.
End With
Excel's Object Browser doesn't give me much of a clue.
I have also looked at
MSDN's Article on OLE Object Properties, however there doesn't appear to be anything to address what I need.
Aha..! A lot more searching and I found the answer to my own question:
sht.OLEObjects("RadioB_1").ShapeRange.Fill.Transparency = 1
ShapeRange was listed on that MS page, however the name of it is misleading, and there is still nowhere in official documentation which actually lists all the properties and what they do! Anyway - I decided to post the answer to my own question for the benefit of anyone looking for this in future.