PowerPoint VBA: Copy and paste image, align to center, and stretch to fit page - vba

I'm trying to create a command to automatically export a PDF in PowerPoint.
I have a command to paste a photo that is working. However, it just pastes to the top left of the screen.
I have been looking on the web for a script to align to the center of the slide and stretch to fit the slideshow page. I tried to record it but it seems as if PowerPoint does not have a record function.
Here is my Copy + Paste script that works below.
Sub PastePhoto()
Dim Sld As Slide
'Ensure focus is on slide
Application.ActiveWindow.Panes(2).Activate
Set Sld = Application.ActiveWindow.View.Slide
On Error GoTo NoCopy
Sld.Shapes.PasteSpecial (ppPasteEnhancedMetafile)
On Error GoTo 0
Exit Sub
NoCopy:
MsgBox "There was nothing copied to paste!"

This should be all that's needed to insert a picture into your slide and stretch it to fit the slide's width:
' Get the first slide...
Dim sl As Slide
Set sl = ActivePresentation.Slides(1)
' Insert a picture at (0, 0)...
Dim sh As Shape
Set sh = sl.Shapes.AddPicture("c:\path\to\my.jpg", msoFalse, msoTrue, 0, 0)
' Set the picture's width to that of a slide...
sh.Width = ActivePresentation.PageSetup.SlideWidth
And if you want to center it vertically:
sh.Top = (ActivePresentation.PageSetup.SlideHeight - sh.Height) / 2

After some tweaking I've figured it out :)
Sub PastePhoto()
Const ppLayoutBlank = 12
Dim objWorkSheet As Worksheet
Dim objRange As Range
Set objWorkSheet = ThisWorkbook.ActiveSheet
Range("A1:H18").Select
Range("H18").Activate
Selection.Copy
Dim objPPT As PowerPoint.Application
Dim objPresentation As Presentation
Set objPPT = CreateObject("PowerPoint.Application")
objPPT.Visible = True
Set objPresentation = objPPT.Presentations.Add
Set objSlide = objPresentation.Slides.Add(1, 1)
objPresentation.Slides(1).Layout = ppLayoutBlank
' paste as the meta file
objPPT.Windows(1).View.PasteSpecial ppPasteMetafilePicture, msoTrue, , , "testlabel"
End Sub

Related

Excel VBA: Paste Excel Range as a Table in Powerpoint

I'm trying to automate the creation of powerpoint decks that i have to produce every month. I'm working in Excel VBA and cant figure out how to copy a range from excel, and paste it into a slide as a table.
Below is the code i have so far:
Sub Open_PowerPoint_Presentation()
Dim objPPT As Object, _
PPTPrez As PowerPoint.Presentation, _
pSlide As PowerPoint.Slide
Set objPPT = CreateObject("PowerPoint.Application")
objPPT.Visible = True
Set PPTPrez = objPPT.Presentations.Open("file location")
Set pSlide = PPTPrez.Slides(4)
Dim RevenueDetail As Range
Dim RevenueDetailTable As Object
Sheets("Revenue By Type Slide").Activate
Set RevenueDetail = Range("B4:I18")
RevenueDetail.Copy
Set RevenueDetailTable = pSlide.Shapes.PasteSpecial(ppPasteEnhancedMetafile)
With RevenueDetailTable
.Left = 43.99961
.Top = 88.61086
.Width = 471.2827
.Height = 395.2163
End With
End Sub
This works OK but it pastes the excel range as a picture which is not ideal. i'd like to paste it as a table which is what the default paste option does, but then i lose the ability to re-size and re-position it on the slide by the means that i'm currently using. I've been messing with this for awhile and can't seem to get it right.
if i modify
Set RevenueDetailTable = pSlide.Shapes.PasteSpecial(ppPasteEnhancedMetafile)
and change it to
Set RevenueDetailTable = pSlide.Shapes.Paste
it pastes in the format i want but i cant figure out how to reposition and resize. any help would be greatly appreciated.
Fixed it... just needed to add a line "pSlide.Select" to select the slide i'm pasting into prior to pasting, and change .PasteSpecial(ppPasteEnhancedMetafile) to just .Paste...thanks for all help!!!!
Sub Open_PowerPoint_Presentation()
Dim objPPT As Object, _
PPTPrez As PowerPoint.Presentation, _
pSlide As PowerPoint.Slide
Dim RevenueDetail As Range
Dim RevenueDetailTable As Object
Set objPPT = CreateObject("PowerPoint.Application")
objPPT.Visible = True
Set PPTPrez = objPPT.Presentations.Open("file location")
Set pSlide = PPTPrez.Slides(4)
Set RevenueDetail = Sheets("Revenue By Type Slide").Range("B4:I18")
RevenueDetail.Copy
pSlide.Select 'needed to add this line
Set RevenueDetailTable = pSlide.Shapes.Paste
With RevenueDetailTable
.Left = 43.99961
.Top = 88.61086
.Width = 471.2827
.Height = 395.2163
End With
End Sub

Loop Through Charts on Selected (or Range of) Powerpoint Slides

I am currently using this code to update all links in my powerpoint presentation:
Sub UpdateLinks()
Dim ExcelFile
Dim exl As Object
Set exl = CreateObject("Excel.Application")
ExcelFile = "C:\Users\J\Documents\Reporting\Governance Physical Charts.xlsm"
Dim i As Integer
Dim k As Integer
'Go through every slide
For i = 1 To ActivePresentation.Slides.Count
With ActivePresentation.Slides(i)
'Go through every shape on every slide
For k = 1 To .Shapes.Count
On Error Resume Next
'Set the source to be the same as teh file chosen in the opening dialog box
.Shapes(k).LinkFormat.SourceFullName = ExcelFile
If .Shapes(k).LinkFormat.SourceFullName = ExcelFile Then
'If the change was successful then also set it to update automatically
.Shapes(k).LinkFormat.AutoUpdate = ppUpdateOptionAutomatic 'other option is ppUpdateOptionManual
End If
Next k
End With
Next i
End Sub
Instead of updating the link of every chart in the presentation, is it possible to have this code loop through only selected slides? Or if it's easier - is it possible to set a range? For example, only update charts on slides 15-30?
Thank you!
EDIT:
Resolution provided in comments - here is my revised code
Sub UpdateLinks()
Dim ExcelFile
Dim exl As Object
Set exl = CreateObject("Excel.Application")
Dim sld As Slide
ExcelFile = "C:\Users\J\Documents\Reporting\Governance Physical Charts.xlsm"
Dim i As Integer
Dim shp As Shape
For Each sld In ActivePresentation.Slides.Range(Array(11, 12, 13, 14, 15, 16, 17, 18))
For Each shp In sld.Shapes
On Error Resume Next
shp.LinkFormat.SourceFullName = ExcelFile
If shp.LinkFormat.SourceFullName = ExcelFile Then
shp.LinkFormat.AutoUpdate = ppUpdateOptionAutomatic 'other option is ppUpdateOptionManual
End If
Next shp
Next
End Sub
Yes you can compose custom ranges on Slides as well as on Shapes, using an Array as the index parameter. Try this:
Dim sld As Slide
For Each sld In ActivePresentation.Slides.Range(Array(1, 3, 5))
Debug.Print sld.Name
Next
Output:
Slide2
Slide4
Slide6
p.s. I had deleted a slide in the test presentation.
Since you also mentioned processing just selected slides, you can do that like so:
Sub SelectedSlides()
Dim osl As Slide
For Each osl In ActiveWindow.Selection.SlideRange
Debug.Print osl.SlideIndex
Next
End Sub
Note that this will give you the selected slides in REVERSE order of selection. That is, if you control-click slides 2,4,6, this will give you 6,4,2.

pasting a picture from excel to powerpoint which fits the layout

I have an Excel Picture as Shape and i want to paste it to mny PowerPoint app which has a Special layout which i have already specified.
Sub ExcelShapePowerpoint()
Dim PowerPointApp As Object
Dim myPresentation As Object
Dim mySlide As Object
Dim myShape As Object
Dim pastedPic1 As Shape
Set DestinationSheet1 = Workbooks("myExcelFile.xlsm").Sheets("myExcelSheet")
Set pastedPic1 = DestinationSheet1.Shapes(10)
On Error Resume Next
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
Application.ScreenUpdating = False
Set myPresentation = PowerPointApp.Presentations.Add
Set mySlide = myPresentation.Slides.Add(1, 11) '11 = ppLayoutTitleOnly
With myPresentation.PageSetup
.SlideWidth = 961
.SlideHeight = 540
End With
pastedPic1.Copy
mySlide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShape.Left = -15
myShape.Top = 11
PowerPointApp.Visible = True
PowerPointApp.Activate
Application.CutCopyMode = False
End Sub
As its obvious from the code the layout is already set. Now i want the pastedpic1 to fit completely to the layout of the PowerPoint.
What should i do ?
To scale the shape myShape to the size of the slide, use this:
With myShape
.Top = 0
.Left = 0
.Width = ActivePresentation.PageSetup.SlideWidth
.Height = ActivePresentation.PageSetup.SlideHeight
End With
Note that depending on the aspect ratio of your shape and slide, stretching may occur. This can be dealt with using the cropping methods.
I had a similar problem but took another approach:
I created a PowerPoint template where I added Picture placeholders to the destinations where the pictures have to be inserted. This approach has the advantage, that you can edit the layout in PowerPoint and do not have to fiddle with pixel sizes in the basic code.
The following example is in VBScript but can be transfered to VBA easily:
Open the PowerPoint template:
Dim powerPoint, presentation
Set powerPoint = CreateObject("PowerPoint.Application")
Set presentation = powerPoint.Presentations.open("C:\template.pptx")
Select the Placeholder, and paste the picture:
Dim slide, view, image, placeholder
Set view = m_presentation.Windows(1).View
Set slide = m_presentation.Slides(slideId)
view.GotoSlide(slide.SlideIndex)
Set placeholder = slide.Shapes(shapeName)
placeholder.Select()
view.Paste()
slide.Application.CommandBars.ExecuteMso("PictureFitCrop")
Scale the picture to fit the size of the placeholder:
slide.Application.CommandBars.ExecuteMso("PictureFitCrop")

Copy and paste rows from Excel to Powerpoint

Ok, here is what I am looking for (Im new, so be gentle):
Copy and paste (default format) from excel to powerpoint (from just the one sheet)
I can only fit so many rows in ppt - so after a slide fills, I want ppt to create a new slide
Same title for each slide is fine!
I only need columns B:K copied over
That's it, however I am stuck :( I know the below code is NOT the best way to write this and it contains errors in which I am sure will be easy to spot. I cannot find how to do this anywhere on the net.
This is what I have so far:
Sub ExcelRangeToPowerPoint()
Dim rng As Excel.Range
Dim PowerPointApp As PowerPoint.Application
Dim myPresentation As PowerPoint.Presentation
Dim mySlide As PowerPoint.Slide
Dim myShapeRange As PowerPoint.Shape
Dim i As Integer
'Create an Instance of PowerPoint
On Error Resume Next
'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, ppLayoutTitleOnly)
For i = 1 To 6
'need to set focus to slde 1
PowerPointApp.ActiveWindow.View.GotoSlide (1)
'Deletes Title
'mySlide.Shapes.Title.Delete
'builds new title
mySlide.Shapes.AddShape Type:=msoShapeRectangle, left:=9, Top:=6, Width:=702, Height:=30
mySlide.Shapes(mySlide.Shapes.Count).Line.Visible = msoTrue
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Font.Size = 20
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Font.Color.RGB = RGB(0, 0, 0)
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.ParagraphFormat.Alignment = ppAlignLeft
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Text = "Current Full Initiative Details – Branded Book as of " & Date
mySlide.Shapes(mySlide.Shapes.Count).Name = "I am TITLE"
mySlide.Shapes(mySlide.Shapes.Count).Line.ForeColor.RGB = RGB(0, 0, 0)
mySlide.Shapes(mySlide.Shapes.Count).Line.Weight = 1
mySlide.Shapes(mySlide.Shapes.Count).Fill.Visible = msoTrue
mySlide.Shapes(mySlide.Shapes.Count).Fill.ForeColor.RGB = RGB(255, 255, 255)
'Copy Range from Excel
Set rng = ActiveWorkbook.Worksheets("RAW").Range("B1:K23")
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
PowerPointApp.ActiveWindow.View.PasteSpecial DataType:=ppPasteDefault
Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShapeRange.left = 10
myShapeRange.Top = 42
myShapeRange.Height = 492
myShapeRange.Width = 702
ActiveWorkbook.Sheets("RAW").Rows("2:23").Delete
Call myPresentation.Slides.Add(1, PpSlideLayout.ppLayoutTitleOnly)
'Clear The Clipboard
Application.CutCopyMode = False
Next i
End Sub
As requested in comments, here is the code I use to copy a slide from a master PPT template to the report PPT.
There is some extraneous code in there to provide status updates on the form we use to drive the process, as well as a debugging flag that I can toggle on/off at run time - these can both be removed.
This will serve as a starting point to finding the proper solution for your situation, and is not a complete answer to the question as asked.
'I've chosen to declare these globally, though it's probably not the best way:
Dim PPTObj As PowerPoint.Application
Dim PPTMaster As PowerPoint.Presentation
Dim PPTClinic As PowerPoint.Presentation
Private Sub InsertPPT(ByVal SlideName As String, ByVal StatusText As String)
Dim Shp As PowerPoint.Shape
Dim Top As Single
Dim Left As Single
Dim Height As Single
Dim width As Single
PPTMaster.Slides(SlideName).Copy
PPTClinic.Slides.Paste
Form_Master.ProcessStatus.Value = StatusText & " InsertPPT"
With PPTClinic.Slides(PPTClinic.Slides.count)
If Debugging Then
.Select
End If
.Design = PPTMaster.Slides(SlideName).Design 'this ensures we get all the right formatting - only seems to be necessary 1 time, but we'll just do it on all
.ColorScheme = PPTMaster.Slides(SlideName).ColorScheme
.FollowMasterBackground = PPTMaster.Slides(SlideName).FollowMasterBackground
For Each Shp In .Shapes 'loop through all the shapes on the slide
If Debugging Then
' .Select
Shp.Select
End If
Form_Master.ProcessStatus.Value = StatusText & " InsertPPT-" & Shp.Name
If Shp.Type = msoLinkedOLEObject Then 'when we find a linked one
ReLinkShape Shp, TempVars!NewXLName
'need to store off top, left, width, height
Top = Shp.Top
Left = Shp.Left
Height = Shp.Height
width = Shp.width
Shp.LinkFormat.Update 'and force the link to refresh
MySleep 2, "S" 'hopefully, the 2 second pause will allow everything to update properly before moving on.
'then reset them here - they seem to change shape when I update them
Shp.LockAspectRatio = msoFalse
Shp.Top = Top
Shp.Left = Left
Shp.width = width
Shp.Height = Height
ElseIf Shp.Name = "SlideName" And Not Debugging Then 'if it's the "SlideName" tag
Shp.Delete 'delete it (unless we're debugging)
End If
Next
End With
Form_Master.ProcessStatus.Value = StatusText
End Sub
Private Sub ReLinkShape(ByRef Shp As PowerPoint.Shape, ByVal NewDestination As String)
Dim Link() As String
Dim link2() As String
If Shp.Type = msoLinkedOLEObject Then 'when we find a linked one
Link = Split(Shp.LinkFormat.SourceFullName, "!") 'update the link to point to the new clinic spreadsheet instead of the master
If InStr(1, Link(2), "]") > 0 Then
link2 = Split(Link(2), "]")
Link(2) = "[" & TempVars!ClinicName & ".xlsx]" & link2(1)
End If
Shp.LinkFormat.SourceFullName = NewDestination & "!" & Link(1) & "!" & Link(2)
End If
End Sub
Public Sub MySleep(ByRef Unit As Double, ByRef UOM As String)
Dim Pause As Date
Pause = DateAdd(UOM, Unit, Now())
While Now < Pause
DoEvents
Wend
End Sub

Size and move a picture in powerpoint

I have the following VBA code which let me paste an excel file into a powerpoint. I works, but after a paste it I would also like to size it (make it a little smaller) and move it to the right upper corner.
Any suggestions on how I should change code below to accomplish this?
Dear regards,
Marc
Sub OpenPPT()
Dim pptapp As PowerPoint.Application
Dim ppt As PowerPoint.Presentation
Dim slide As PowerPoint.slide
Dim shape As PowerPoint.shape
var2 = "C:\Documents and Settings\aa471714\Desktop\Presentation1.ppt"
Set pptapp = CreateObject("Powerpoint.Application")
Set ppt = pptapp.Presentations.Open(var2)
Set slide = ppt.Slides(1)
Set shape = slide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 100, 100, 100)
pptapp.Visible = True
With slide
.Shapes.Paste
End With
End Sub
Instead of this bit:
With slide
.Shapes.Paste
End With
Substitute this:
Set shape = slide.shapes.paste(1)
With shape
.Left = 100 ' or whatever
.Width = 500 ' or whatever
End With