How do I copy an Excel chart into a PowerPoint slide?
Here is the code I have so far.
'There is a bunch of other stuff defined.
' Just showing what I think are relevant definitions
Dim pptApp As PowerPoint.Application
Dim pptPres As PowerPoint.Presentation
Dim shp As PowerPoint.Shape
Dim sld As PowerPoint.Slide
Dim xlChrt As Excel.ChartObject
Set pptApp = CreateObject("PowerPoint.Application")
'This opens up my PowerPoint file
Set ppPres = pptApp.Presentations.Open(myPath & pptFile)
'This activates the worksheet where my chart is
Workbooks(wb2).Sheets("Sheet 1").Activate
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.ChartArea.Copy
'I think that my copying works because after I run the module,
' I have the chart in my clipboard.
'This takes me to slide 2 of my PowerPoint.
Set sld = pptPres.Slides(2)
sld.Shapes.Paste 'But nothing pastes to the slide
I am copying the chart because it is in my clipboard after the module runs.
I successfully reference the PowerPoint slide as later in the code, I edit text boxes on slide 2.
I believe your code should work if you correct the set pptPres statement. This example is a simplified example based on your code:
Option Explicit
Public Sub CopyChart()
Const myPath = "c:\temp\"
Const pptFile = "test.pptx"
Dim pptApp As New PowerPoint.Application
Dim pptPres As PowerPoint.Presentation
Dim sld As PowerPoint.Slide
' Open the PowerPoint and reference the slide
Set pptPres = pptApp.Presentations.Open(myPath & pptFile)
Set sld = pptPres.Slides(2)
' Copy the Chart
ActiveWorkbook.Sheets("Sheet 1").ChartObjects("Chart 1").Copy
' Paste it into the PowerPoint
sld.Shapes.Paste
End Sub
And the result ... you can see the chart pasted onto slide 2:
UPDATED ANSWER
Chartsheets aren't as functional as embedded charts: https://learn.microsoft.com/en-us/office/vba/api/excel.chart(object)
Here is one option which is small variation of the above which works for chartsheets:
Option Explicit
Public Sub CopyChartSheet()
Const myPath = "c:\temp\"
Const pptFile = "test.pptx"
Dim pptApp As New PowerPoint.Application
Dim pptPres As PowerPoint.Presentation
Dim myChart As Excel.Chart
Dim sld As PowerPoint.Slide
' Open the PowerPoint and reference the slide
Set pptPres = pptApp.Presentations.Open(myPath & pptFile)
Set sld = pptPres.Slides(2)
' Copy the Chart
Set myChart = ActiveWorkbook.Charts("Chart 1")
myChart.CopyPicture
' Paste it into the PowerPoint
sld.Shapes.Paste
End Sub
Related
I cant figure out how to incorporate my template into my actual code in VBA so that my sheets will build in the desired template and slides.
I have built the slides in a new blank powerpoint slides but cant figure out how to do it with template yet.
Sub LCTAKT_Macro()
'Declare variables
Dim PP As PowerPoint.Application
Dim PPPres As PowerPoint.Presentation
Dim PPSlide1 As PowerPoint.Slide
Dim PPSlide2 As PowerPoint.Slide
Dim PPSlide3 As PowerPoint.Slide
Dim PPSlide4 As PowerPoint.Slide
Dim PPSlide5 As PowerPoint.Slide
Dim PPSlide6 As PowerPoint.Slide
Dim PPSlide7 As PowerPoint.Slide
Dim SlideTitle As String
Dim objPPT As Object
'Open PowerPoint and create new presentation
Set objPPT = CreateObject("PowerPoint.Application")
objPPT.Visible = True
Set PP = New PowerPoint.Application
Set PPPres = PP.Presentations.Add
PP.Visible = True
objPPT.Presentations.Open ""
'-------------------------------------------------Station 42--------- ------------------------------------------------
'Add new slide as slide 2 and set focus to it
Set PPSlide1 = PPPres.Slides.Add(1, ppLayoutTitleOnly)
PPSlide1.Select
'Copy the range as a picture
Sheets("").Range("A1:W59").CopyPicture _
Appearance:=xlScreen, Format:=xlPicture
'Paste the picture and adjust its position
PPSlide1.Shapes.Paste.Select
PP.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
PP.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
'Add the title to the slide
SlideTitle = ""
PPSlide1.Shapes.Title.TextFrame.TextRange.Text = SlideTitle
'Position pasted chart
PP.ActiveWindow.Selection.ShapeRange.Left = 200
PP.ActiveWindow.Selection.ShapeRange.Top = 130
PP.ActiveWindow.Selection.ShapeRange.Height = 523
PP.ActiveWindow.Selection.ShapeRange.Width = 554
I expect the template to be incorporated in the slides while still building the necessary data snippets to it.
Assuming Office 2013 or better, try this:
TemplateName$ = "C:\Users\YourActualUserName\Documents\Custom Office Templates\YourActualTemplateName.potx"
Set PPPres = PP.Presentations.Open(TemplateName$, False, True, True)
I'm trying to write a code to run from excel, and then open an existing excel and powerpoint file from the c drive, and use the data in the worksheet named "Oct18" to update the FIRST table in Slide 2 of the powerpoint.
The following is the code I wrote, but somehow it doesn't work.
May I know if anyone knows how to go about this please ?
Sub WriteText_toPPT_Table()
'Add a reference to Microsoft Powerpoint 12.0 object library
Dim ppApp As PowerPoint.Application
Dim ppPres As PowerPoint.Presentation
Dim ppShp As PowerPoint.Shape
Dim ppSld As PowerPoint.slide
Dim xlworkbook As Workbook
Dim firstsheet As String
Dim fileDir As String
Dim excelFile As String
firstsheet = "Oct18"
'fileDir = "c:\masterpresentation.pptx"
'excelFile = "c:\masterexcel.pptx
'1) Open powerpoint application
Set ppApp = CreateObject("PowerPoint.Application")
ppApp.Visible = msoTrue
Set xlworkbook = Excel.Application.Workbooks.Open(Filename:=excelFile)
'2) opening an existing presentation
Set ppPres = ppApp.Presentations.Open(Filename:=fileDir)
Set exceldir = Excel.Application.Workbooks.Open(Filename:=excelFile)
ppPres.Slides(2).Shapes(1).Table.Cell(1, 1).Shape.TextFrame.TextRange.Text = xlworkbook.Sheets(firstsheet).Cells(4, 12)
End Sub
I've made a code to open Powerpoint from excel, and loop through all the slides, find the graph and change some columns. I have the code for doing the replacement but cant' seem to loop through the slides because it throws an ActiveX error 429 that is basically saying that powerpoint is not found :O.
Sub pptDataChange()
'Define variables of excel
Dim mySheet As Excel.Worksheet
'Define variables to open on PPT
Dim PowerPointApp As PowerPoint.Application
Dim myPresentation As PowerPoint.Presentation
Dim sld As Slide
Dim shp As Shape
Dim chrt As Chart
'Copy range from Excel
Set mySheet = ThisWorkbook.Worksheets("Sheet1")
'Create instance of Powerpoint
On Error Resume Next
'Open Powerpoint with Powerpoint is already opened
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear errors
Err.Clear
'If Powerpoint is closed, open Powerpoint
If PowerPointApp Is Nothing Then
Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
End If
'Handle error if Powerpoint isn't installed or not found
If Err.Number = 429 Then
MsgBox ("PowerPoint not found, aborting...")
Exit Sub
End If
On Error GoTo 0
'Make Powerpoint visible and active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Open Powerpoint Presentation from PATH and set it as the active
PowerPointApp.Presentations.Open ("File.pptx")
For Each sld In ActivePresentation.Slides
For Each shp in sld
'Iterate through charts and change data of chart using something like If sld Has.Chart Then ...
Next sld
Exit Sub
What I'm thinking is that maybe it's because of the ActivePresentation, but I've tried referencing to myPresentation but It was the same.
Can you please help?
I explicitly declared a Presentation variable to use instead of ActivePresentation and that seemed to do the trick. FYI: I also changed the declarations for the sld and shp variables to explicitly reference the PowerPoint object library.
Sub pptDataChange()
'Define variables of excel
Dim mySheet As Excel.Worksheet
'Define variables to open on PPT
Dim PowerPointApp As PowerPoint.Application
Dim myPresentation As PowerPoint.Presentation
Dim sld As PowerPoint.Slide
Dim shp As PowerPoint.Shape
Dim chrt As Chart
'Copy range from Excel
Set mySheet = ThisWorkbook.Worksheets("Sheet1")
'Create instance of Powerpoint
On Error Resume Next
'Open Powerpoint with Powerpoint is already opened
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear errors
Err.Clear
'If Powerpoint is closed, open Powerpoint
If PowerPointApp Is Nothing Then
Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
End If
'Handle error if Powerpoint isn't installed or not found
If Err.Number = 429 Then
MsgBox ("PowerPoint not found, aborting...")
Exit Sub
End If
On Error GoTo 0
'Make Powerpoint visible and active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Open Powerpoint Presentation from PATH and set it as the active
Dim pres As PowerPoint.Presentation
Set pres = PowerPointApp.Presentations.Open("File.pptx")
For Each sld In pres.Slides
For Each shp In sld.Shapes
'Iterate through charts and change data of chart using something like If sld Has.Chart Then ...
Next shp
Next sld
End Sub
This is my first time asking a question here, as you guys and gals are so good that I've never had to until now!
I have the following VBA code, which successfully pulls charts from a spreadsheet, and pastes them onto two newly created PPT slides. The only problem however, is that this code ONLY aligns the chart on the second slide, and doesn't affect the chart on the first slide.
I can't for the life of me figure out what's going on her, and would greatly appreciate any input!
Option Explicit
Sub MakeSlides()
Dim myData As Excel.Range
Dim sheet2 As Excel.Worksheet
Dim objPPT As Object
Set sheet2 = ActiveWorkbook.Sheets("Sheet2")
Set myData = sheet2.Range("A2:B43")
Set objPPT = CreateObject("Powerpoint.application")
myData.Copy
Dim pptApp As New PowerPoint.Application
pptApp.Visible = True
Dim pres As PowerPoint.Presentation
Set pres = pptApp.Presentations.Add
Dim firstslide As PowerPoint.Slide
Set firstslide = pres.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank)
Dim myChart As Excel.ChartObject
Set myChart = Sheet1.ChartObjects(1)
myChart.Copy
firstslide.Shapes.Paste.Select
' Align pasted chart
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
Set sheet2 = ActiveWorkbook.Sheets("Sheet2")
Set myData = sheet2.Range("A45:B69")
myData.Copy
pptApp.Visible = True
Dim secondslide As PowerPoint.Slide
Set secondslide = pres.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank)
Set myChart = Sheet1.ChartObjects(2)
myChart.Copy
secondslide.Shapes.Paste
' Align pasted chart
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
End Sub
Maybe like this; aligning the chart on the first slide right after you paste it in:
Option Explicit
Sub MakeSlides()
[...]
myChart.Copy
firstslide.Shapes.Paste.Select
' Align pasted chart
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
Set sheet2 = ActiveWorkbook.Sheets("Sheet2")
Set myData = sheet2.Range("A45:B69")
myData.Copy
pptApp.Visible = True
Dim secondslide As PowerPoint.Slide
Set secondslide = pres.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank)
Set myChart = Sheet1.ChartObjects(2)
myChart.Copy
secondslide.Shapes.Paste
' Align pasted chart
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
pptApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
End Sub
Try this instead.
A few points:
You don't need a new variable for each chart/slide etc. One, reused as needed, is plenty.
Never use SELECT unless there's no way around it (in Excel or PPT). It makes the code more fragile and forces you to make the app visible (not really necessary most of the time). It also slows your code down by an order of magnitude since PPT has to redraw everything.
Sub MakeSlides()
Dim myData As Excel.Range
Dim sheet2 As Excel.Worksheet
Dim objPPT As Object
Set sheet2 = ActiveWorkbook.Sheets("Sheet2")
Set myData = sheet2.Range("A2:B43")
Set objPPT = CreateObject("Powerpoint.application")
myData.Copy
Dim pptApp As New PowerPoint.Application
pptApp.Visible = True
Dim pres As PowerPoint.Presentation
Set pres = pptApp.Presentations.Add
Dim oSlide As PowerPoint.Slide
Dim oChtShape as PowerPoint.Shape
Set oSlide = pres.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank)
Dim myChart As Excel.ChartObject
Set myChart = Sheet1.ChartObjects(1)
myChart.Copy
Set oChtShape = oSlide.Shapes.Paste(1)
' Align pasted chart
oChtShape.Align msoAlignCenters, True
oChtShape.Align msoAlignMiddles, True
' Not sure what this is supposed to do:
Set sheet2 = ActiveWorkbook.Sheets("Sheet2")
Set myData = sheet2.Range("A45:B69")
myData.Copy
' it's already visible; don't need this
'pptApp.Visible = True
' don't need a new object variable for each slide;
' reuse the existing variable instead
Set oSlide = pres.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank)
Set myChart = Sheet1.ChartObjects(2)
myChart.Copy
'secondslide.Shapes.Paste
Set oChtShape = oSlide.Shapes.Paste(1)
' Align pasted chart
oChtShape.Align msoAlignCenters, True
oChtShape.Align msoAlignMiddles, True
End Sub
I've cobbled together a VBA script (I'm no expert, but thanks to the kind folks around here, I've been able to get something together and mostly working) to copy from multiple excel sheets into a powerpoint file (used a template, as you will see from the code.
Sub ATestPPTReport()
Dim PPApp As PowerPoint.Application
Dim PPSlide As PowerPoint.Slide
Dim PPPres As PowerPoint.Presentation
Set PPApp = CreateObject("Powerpoint.Application")
Dim SlideNum As Integer
Dim PPShape As PowerPoint.Shape
Set XLApp = GetObject(, "Excel.Application")
''define input Powerpoint template
Dim strPresPath As String, strExcelFilePath As String, strNewPresPath As String
''# Change "strPresPath" with full path of the Powerpoint template
strPresPath = "C:\template.ppt"
''# Change "strNewPresPath" to where you want to save the new Presentation to be created
strNewPresPath = "C:\macro_output-" & Format(Date, "dd-mmm-yyyy") & ".ppt"
Set PPPres = PPApp.Presentations.Open(strPresPath)
PPPres.Application.Activate
PPApp.Visible = True
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''define destination slide
SlideNum = 1
PPPres.Slides(SlideNum).Select
Set PPShape = PPPres.Slides(SlideNum).Shapes("slide1box")
Set PPSlide = PPPres.Slides(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex)
''define source sheet
Sheets("Info1").Activate
'copy/paste from
XLApp.Range("Info1Block").Copy
PPSlide.Shapes.PasteSpecial DataType:=ppPasteOLEObject, Link:=msoFalse
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''define destination slide
SlideNum = 2
PPPres.Slides(SlideNum).Select
' Set PPShape = PPPres.Slides(SlideNum).Shapes("slide2box")
Set PPSlide = PPPres.Slides(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex)
''define source sheet
Sheets("Info2").Activate
'copy/paste from
XLApp.Range("Info2Block").Copy
PPSlide.Shapes.PasteSpecial DataType:=ppPasteOLEObject, Link:=msoFalse
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Close presentation
PPPres.SaveAs strNewPresPath
'PPPres.Close
'Quit PowerPoint
'PPApp.Quit
' MsgBox "Presentation Created", vbOKOnly + vbInformation
' Clean up
Set PPSlide = Nothing
Set PPPres = Nothing
Set PPApp = Nothing
End Sub
My problem is: how do I resize/reposition the object once it's been pasted?
The function "PasteSpecial" returns a shape object, which you can use to resize or reposition.
For example:
Dim ppShape as PowerPoint.Shape
set ppShape = PPSlide.Shapes.PasteSpecial(DataType:=ppPasteOLEObject, Link:=msoFalse)
Then you can use this shape object to resize it. For example:
ppShape.Height = xyz
ppShape.Top = abc
etc etc.
Hope this helps.
Vikas B
This has been working for me:
Set shp = myPresentation.Slides(x).Shapes.PasteSpecial(DataType:=2)
shp.Left = topLeft + 1
shp.Top = midTop + 1
shp.Width = midLeft - topLeft - 1
Note the variables are set locally to place the image where I want it in relation to the slide. You can easily replace with integers.
It also works for DataType:=10 items as well