This question already has answers here:
VBA delete all slides in one go
(2 answers)
Closed 5 years ago.
I am trying to delete slides in Active Powerpoint Presentation but I have an error on sld_id = ActiveWindow.Selection.SlideRange.SlideIndex
Sub DEL()
Dim i As Long
Dim sld_id As Long
sld_id = ActiveWindow.Selection.SlideRange.SlideIndex
With ActivePresentation.Slides
For i = .Count To sld_id Step -1
.Item(i).Delete
Next i
End With
End Sub
Can anyone help me with that?
Many thanks!
Roxana
The code below uses Late Binding to PowerPoint (so you don't need to add reference to the PowerPoint library), and it checks if the PowerPoint instance is open.
After, it sets the ActivePresentation to ppPres.
At last, you loop backwards to delete all the slides from the end until the second slide (only the first slide will remain).
Note: You can modify the For i = ppPres.Slides.Count To 2 Step -1 loop quite easily to fit your needs.
Code
Option Explicit
Sub DEL()
Dim ppProgram As Object
Dim ppPres As Object
Dim ppSlide As Object
Dim i As Long
On Error Resume Next
Set ppProgram = GetObject(, "PowerPoint.Application")
On Error GoTo 0
' check if PowerPoint instance is open >> if not raise an error
If ppProgram Is Nothing Then
MsgBox "PowerPoint is closed!"
Exit Sub
Else
' set the ppPres object to active PowerPoint presentation
Set ppPres = ppProgram.ActivePresentation
' always loop backwards when deleting objects (in this case slides)
For i = ppPres.Slides.Count To 2 Step -1
Set ppSlide = ppPres.Slides(i)
ppSlide.Delete
Next i
End If
End Sub
Related
As part of a PowerPoint report automation, I'm copying a table from an Excel Macro-Enabled workbook to a PowerPoint presentation, running the VBA code from Excel. This is part of a bigger project, but the key parts of the code is as follows:
Sub test()
Dim mainWb As Workbook
Dim graphsWs As Worksheet
Dim pptApp As PowerPoint.Application
Dim pptTemp As PowerPoint.Presentation
Dim pptSlide As PowerPoint.slide
Dim shp As PowerPoint.Shape
Set mainWb = ThisWorkbook
Set graphsWs = mainWb.Sheets(1)
Set pptApp = New PowerPoint.Application
Set pptTemp = pptApp.Presentations.Add
Set pptSlide = pptTemp.Slides.AddSlide(1, pptTemp.SlideMaster.CustomLayouts(1))
With pptSlide
.Name = "Destination"
graphsWs.Range("A2:B4").Copy
.Application.CommandBars.ExecuteMso ("PasteSourceFormatting")
DoEvents
Debug.Print (.Shapes(.Shapes.Count).Name) ' Should print "Table X", but instead prints "Subtitle"
End With
End Sub
Problem:
The Debug.Print line gives be "Subtitle 2", where I expected it to give me "Table 3", as the table is the thing that was most recently copied into the sheet. In addition, when I, after the code has executed, try in PowerPoint VBA to write in the immediate window ?ActivePresentation.Slides(1).Shapes(ActivePresentation.Slides(1).Shapes.Count).Name I get the Table 3 as I would expect.
Hypothesis: It seems that the running of the script does not wait for the line that pastes the code (.Application.CommandBars.ExecuteMso ("PasteSourceFormatting") to complete before executing the next line. If this was true, it would give the result I see (as far as I can understand).
Potential fix: If my hypothesis is correct, then Using a Application.Wait-statement could potentially work, however, I don't like the idea of just throwing in a few milliseconds or seconds wait, as different users on different computers will be using this script.
Question: Is there a better way to tell the application to wait while it is busy? (In a PowerShell web-scrape script I've previously used something like: while($ie.Busy){Sleep 1}, but I can't seem to find anything similar in Excel VBA.
PS: Thanks to Tim for pointing out this related question. I've added my DoEvents, but it still doesn't seem to fix the problem...
Any help here is much appreciated!
You could try getting the value of .Shapes.Count before the paste, then go into a DoEvents loop until the value has increased by one. Probably a good idea to put a time limit on the loop too.
Dim i As Long, t
With pptSlide
.Name = "Destination"
i = .Shapes.Count
graphsWs.Range("A2:B4").Copy
.Application.CommandBars.ExecuteMso ("PasteSourceFormatting")
t = Timer
Do While .Shapes.Count = i
DoEvents
If Timer - t > 2 Then Exit Do '<< exit after a couple of seconds
Loop
Debug.Print (.Shapes(.Shapes.Count).Name)
End With
Following suggestion from #TimWilliams, the following code works:
Sub test()
Dim mainWb As Workbook
Dim graphsWs As Worksheet
Dim pptApp As PowerPoint.Application
Dim pptTemp As PowerPoint.Presentation
Dim pptSlide As PowerPoint.slide
Dim shp As PowerPoint.Shape
Dim i As Long, shapesCount As Long
i = 0 ' Counter for DoEvents Loop
shapesCount = 0
Set mainWb = ThisWorkbook
Set graphsWs = mainWb.Sheets(1)
Set pptApp = New PowerPoint.Application
Set pptTemp = pptApp.Presentations.Add
Set pptSlide = pptTemp.Slides.AddSlide(1, pptTemp.SlideMaster.CustomLayouts(1))
With pptSlide
.Name = "Destination"
graphsWs.Range("A2:B4").Copy
.Application.CommandBars.ExecuteMso ("PasteSourceFormatting")
shapesCount = .Shapes.Count
Do While shapesCount = .Shapes.Count
DoEvents
i = i + 1
If i > 10000 Then Exit Do
Loop
Debug.Print (.Shapes(.Shapes.Count).Name)
Debug.Print (i)
End With
End Sub
The suggestion was:
You could try getting the value of .Shapes.Count before the paste, then go into a DoEvents loop until the value has increased by one. Probably a good idea to put a time limit on the loop too
I am looking for VBA codes to create think cell chart from excel ranges.
All I found in the internet were VBA codes through which I can update a named thinkcell chart.
However I want the macro to create a new powerpoint and new thinkcell chart from my defined range.
Would that be possible?
Below is the code I found through which one can update Thinkcell chart, but not create a new thinkcell chart.
Sub UpdateThinkCellChart(Rng As Range, sChartName As String)
'Get the think-cell add-in object
Dim tcaddin As Object
Dim ppapp As Object
Dim pres As Object
Set tcaddin = Application.COMAddIns("thinkcell.addin").Object
'Set PowerPoint instance
'Set ppapp = New PowerPoint.Application
On Error Resume Next
Set ppapp = GetObject(, "Powerpoint.Application")
On Error GoTo 0
'Create PowerPoint presentation if none is open:
If ppapp Is Nothing Then
MsgBox "No PowerPoint presentation is open. Please open the relevant presentation and ensure that you have pre-assigned chart names to your ThinkCell charts"
Exit Sub
End If
'Dim pres As PowerPoint.Presentation
Set pres = ppapp.ActivePresentation
' The name sChartName must have been previously assigned to the chart using
' the control in the floating toolbar (left-click on the Think-Cell chart to see this)
' The final argument indicates whether the data range is transposed or not.
Call tcaddin.UpdateChart(pres, sChartName, Rng, False)
End Sub
Sub CopyToTC_ChartNo1()
Dim Rng As Range, sRange As String, sChartName As String
'Insert values:
sRange = "C21:F25"
sChartName = "ChartNo1"
Set Rng = ActiveSheet.Range(sRange)
Call UpdateThinkCellChart(Rng, sChartName)
End Sub
I have an Excel VBA tool, that resides inside a PowerPoint Presentaion as an EmbeddedOLEObject.
Process work-flow:
A user opens the PowerPoint.
Then opens the Excel embedded object in it.
Running the code in it updates data in the Excel file, and then exports it to the 1st slide of the PowerPoint it was opened from.
The problem starts when the user opens 2 of these PowerPoint presentations. If you open one Presnetation, let's call it "P1", then you open a second presentation "P2". Then you open the embedded Excel file in "P2", the excel gets stuck. When running in debug mode, it goes "crazy" opening numerous VBA windows (without giving an error message), at the following line:
Set objExcel = myShape.OLEFormat.Object.
When running this process the other order, If first you open "P2", and then "P1", open the Embedded Excel file in "P2" it works well.
Anyone got a clue ?
Code
Option Explicit
Public Sub UpdatePowerPoint()
Dim ppProgram As Object
Dim ppPres As Object
Dim CurOpenPresentation As Object
Dim ppSlide As Object
Dim myShape As Object
Dim SlideNum As Integer
Dim objExcel As Object
Dim i As Long
On Error Resume Next
Set ppProgram = GetObject(, "PowerPoint.Application")
On Error GoTo 0
If ppProgram Is Nothing Then
Set ppProgram = CreateObject("PowerPoint.Application")
Else
If ppProgram.Presentations.Count > 0 Then
' loop thorugh all open presentation, then loop through all slides
' check each object, check if you find an OLE Embedded object
For i = 1 To ppProgram.Presentations.Count
Set CurOpenPresentation = ppProgram.Presentations(i)
Set ppSlide = CurOpenPresentation.Slides(1) ' only check the first slide for Emb. Excel objects, otherwise not a One-Pager Presentation
For Each myShape In ppSlide.Shapes
Debug.Print myShape.Type & " | " & myShape.Name ' for DEBUG ONLY
If myShape.Type = 7 Then ' 7 = msoEmbeddedOLEObject
Dim objExcelwbName As String
' ***** ERROR in the Line below *******
Set objExcel = myShape.OLEFormat.Object
objExcelwbName = objExcel.CustomDocumentProperties.Parent.Name ' get's the workbook name of the Emb. Object
If objExcelwbName = ThisWorkbook.Name Then ' compare the name of the workbook the embedded object is in, with ThisWorkbook
Set ppPres = CurOpenPresentation
GoTo ExitPresFound
Else
Set objExcel = Nothing ' reset flag
End If
End If
Next myShape
NextPresentation:
Set CurOpenPresentation = Nothing ' clear presentation object
Next i
End If ' If ppProgram.Presentations.Count > 0 Then
End If
ExitPresFound:
If ppPres Is Nothing Then ' if One-Pager presentation was not found from all open presentations
MsgBox "Unable to Locate Presnetation, check if One-Pager Prsentation in Checked-Out (Read-Only Mode)"
End If
End Sub
Since the aim is to capture the presentation that hosts the embedded workbook, and as you confirmed that it looks to you as a good option, the suggested solution is the capture the ActivePresentation in the Workbook_Open event.
The risk that you raised is legitimate, it is possible (theoretically, I would say) that the impatient user switches presentations quickly before the workbook loads, but I could not test how likely is this scenario, due to some security alert in my test environment before the wb opens, giving a too large time for that action.
Awaiting your own confirmation :)
I am looking to copy and paste selected charts from Excel 2010 to Powerpoint 2010 as Microsoft Excel Chart Object formats into an active PPT slide. Ideally, I would like to be able to place these charts into specific positions on the active Powerpoint slide. I've scrounged the web but all if not most solutions are for all slides in a sheet to be pasted randomly on a PPT slide. I don't even have a code but if anyone can help, that would be awesome. Thanks!
Well, here's something: This is a pptGenerator-class that I wrote some time back.
In my scenario I wanted to right click specific charts in a workbook, have "Copy to presentation" as an option in a custom context menu, and add subsequent charts on subsequent slides in either the same presentation, or a new one.
These charts were captured in another class in order to create the context menu and have itself copied to the slide when passed to it.
Below is a slightly modified and stripped version, that should help you out to fix your specific situation by editing this class.
In a Class module:
'PowerPoint Generator class - Rik Sportel
'Maintains a PowerPoint application for Excel workbook.
Private WithEvents pptApp As PowerPoint.Application
Private ppt As PowerPoint.Presentation
Private pptPresentations As Collection 'Collection to add presentations to
Private p_currentPresentation As Boolean
'Make sure you don't add slides if there is no presentation.
Public Property Get CurrentPresentation() As Boolean
CurrentPresentation = p_currentPresentation
End Property
'Initialization
Private Sub Class_Initialize()
p_currentPresentation = False
Set pptApp = New PowerPoint.Application
Set pptPresentations = New Collection
End Sub
'Termination
Private Sub Class_Terminate()
Set pptPresentations = Nothing
Set pptApp = Nothing
End Sub
'Creates a new Presentation in the powerpoint app, and adds it to the pptPresentations collection. Add methods later to cycle through them.
Public Sub NewPresentation()
Set ppt = pptApp.Presentations.Add
pptPresentations.Add ppt
'Create presentation and use image stored within the current workbook as a background for it.
ThisWorkbook.Worksheets("BGItems").Shapes(1).Copy 'Copy the background
ppt.Windows(1).ViewType = ppViewSlideMaster
ppt.Windows(1).View.Paste 'Paste the background
ppt.Windows(1).ViewType = ppViewNormal
p_currentPresentation = True
End Sub
'Add a slide to the presentation, place passed chart on it.
Public Sub AddSlide(chartForSlide As Chart)
Dim nSlide As PowerPoint.Slide
Dim nChart As PowerPoint.Shape
'Create a new slide with the chart on it.
Set nSlide = pptApp.ActivePresentation.Slides.Add(1, ppLayoutBlank)
chartForSlide.ChartArea.Copy
nSlide.Shapes.Paste 'Paste the chart
Set nChart = nSlide.Shapes(1)
'Position the chart
With nChart
.Left = ppt.PageSetup.SlideWidth / 10
.top = ppt.PageSetup.SlideHeight / 10
.Width = ppt.PageSetup.SlideWidth / 100 * 80
.Height = ppt.PageSetup.SlideHeight / 2
End With
Set nChart = Nothing
Set nSlide = Nothing
End Sub
'Make sure to keep track of presentations properly if users interact with
'powerpoint in unexpected ways. Capture event and make sure the presentation object you write to will still exist.
Private Sub pptApp_PresentationClose(ByVal Pres As PowerPoint.Presentation)
For i = pptPresentations.Count To 1 Step -1
If pptPresentations.Item(i) Is Pres Then
pptPresentations.Remove i
End If
Next i
If Pres Is ppt Then
Set ppt = Nothing
p_currentPresentation = False
End If
End Sub
In my "factory" module. a regular code module:
Public Sub GetPowerpoint()
If pptApp Is Nothing Then Set pptApp = New pptGenerator
End Sub
How it's used:
'Pass a chart + optionally if it has to be a new presentation:
Public Sub CopyChartToPpt(tChart As Chart, Optional newPres As Boolean)
GetPowerpoint
If pptApp.CurrentPresentation = False Then pptApp.NewPresentation
If newPres = True Then pptApp.NewPresentation
pptApp.AddSlide tChart
End Sub
So where and how you obtain the selected chart is another thing, but as long as you manage to select the Chart from the ChartObject or Slide in your workbook, and pass it as a parameter to the above, you should be abled to fix it according to your own specs.
Other than my advise would be to check the VBA reference for your powerpoint version over at MSDN.
So here's a solution that worked for me. The macro copy + pastes selected range or chart into the active PowerPoint slide into a certain position. This reason I wanted to do this is that each quarter/month we generate reports for our clients and this helps to reduce the time required for copying + pasting and making the deck look nice. Hope this helps anyone else who make a ton of PPTs!
'Export and position into Active Powerpoint
'Prior to running macro, enable Microsoft Powerpoint Object Library in Tools - Reference
'Identifies selection as either range or chart
Sub ButtonToPresentation()
If TypeName(Selection) = "Range" Then
Call RangeToPresentation
Else
Call ChartToPresentation
End If
End Sub
Sub RangeToPresentation()
Dim PPApp As PowerPoint.Application
Dim PPPres As PowerPoint.Presentation
Dim PPSlide As PowerPoint.Slide
'Error message if range is not selected
If Not TypeName(Selection) = "Range" Then
MsgBox "Please select a worksheet range and try again."
Else
'Reference existing instance of PowerPoint
Set PPApp = GetObject(, "Powerpoint.Application")
'Reference active presentation
Set PPPres = PPApp.ActivePresentation
'Reference active slide
Set PPSlide = PPPres.Slides(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex)
'Copy the range as a picture
Selection.CopyPicture Appearance:=xlScreen, _
Format:=xlBitmap
'Paste the range
PPSlide.Shapes.Paste.Select
'Align the pasted range
PPApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
PPApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
' Clean up
Set PPSlide = Nothing
Set PPPres = Nothing
Set PPApp = Nothing
End If
End Sub
Sub ChartToPresentation()
'Uses Late Binding to the PowerPoint Object Model
'No reference required to PowerPoint Object Library
Dim PPApp As Object 'As PowerPoint.Application
Dim PPPres As Object 'As PowerPoint.Presentation
Dim PPSlide As Object 'As PowerPoint.Slide
'Error message if chart is not selected
If ActiveChart Is Nothing Then
MsgBox "Please select a chart and try again."
Else
'Reference existing instance of PowerPoint
Set PPApp = GetObject(, "Powerpoint.Application")
'Reference active presentation
Set PPPres = PPApp.ActivePresentation
'PPApp.ActiveWindow.ViewType = 1 ' 1 = ppViewSlide
'Reference active slide
Set PPSlide = PPPres.Slides _
(PPApp.ActiveWindow.Selection.SlideRange.SlideIndex)
'Copy chart as a picture
ActiveChart.CopyPicture Appearance:=xlScreen, Size:=xlScreen, _
Format:=xlPicture
'Paste chart
PPSlide.Shapes.Paste.Select
'Align pasted chart
PPApp.ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, True
PPApp.ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, True
' Clean up
Set PPSlide = Nothing
Set PPPres = Nothing
Set PPApp = Nothing
End If
End Sub
So I'm trying to get a table deleted from a powerpoint that is opened using VBa, and I can't seem to get it to work. I've tried a few things but they never have any effect or usually just give me an error.
So far I have gotten the following, which opens a specific powerpoint and copies in a specific table to the first slide. I really would like to be able to delete the table that is already there and replace it with the new one.
How would I go about doing this? Code below:
Sub ExcelRangeToPowerPoint()
'PURPOSE: Copy/Paste An Excel Range Into a New PowerPoint Presentation
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
'Copy Range from Excel
Set rng = ThisWorkbook.ActiveSheet.Range("Table1[#ALL]")
'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")
'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
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Open("Y:\Projects\VBa\vbatest2.pptx")
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Item(1)
'Delete current table in presentation
'ActivePresentation.Slides(1).Shapes(1).Delete
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
mySlide.Shapes.PasteSpecial DataType:=ppPasteSourceFormatting
Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShapeRange.Left = 20
myShapeRange.Top = 100
myShapeRange.Height = 400
myShapeRange.Width = 900
'Clear The Clipboard
Application.CutCopyMode = False
End Sub
myPresentation.Slides(1).Shapes(1).Delete
Place code above just after
Set mySlide = myPresentation.Slides.Item(1)
When I used this it deleted my table from my powerpoint however it was only a table in the slide, you may need to change the number in shapes to get this to work for you. I also don't know how it will fair will continued use, you may need to keep changing the number.
I used This link
to find out how to delete items from powerpoint
ActivePresentation.Slides(2).Shapes(5).Table.Rows(3).Delete
Is the origonal code from the site linked and was adapted using trial and error
This link
Explains shapes a bit more, hope it helps. In a basic overview it basicly says that in powerpoint most items you can enter in it are called shapes
If you want me to explain anything further just leave a comment and I shall try to do so
Try calling this function to delete all tables from the specified slide:
Option Explicit
' Deletes all tables from the specified slide (table shapes and tables within placeholders)
' Returns the number of tables deleted
' Written by Jamie Garroch of YOUpresent Ltd. (http://youpresent.co.uk)
Public Function DeleteTablesFromSlide(mySlide As PowerPoint.Slide) As Long
Dim lCntr As Long
Dim lTables As Long
' Count backwards when deleting items from a collection
For lCntr = mySlide.Shapes.Count To 1 Step -1
With mySlide.Shapes(lCntr)
Select Case .Type
Case msoTable: .Delete: lTables = lTables + 1 ' msoTable = 19
Case msoPlaceholder ' msoPlaceholder = 19
If .PlaceholderFormat.ContainedType = msoTable Then .Delete: lTables = lTables + 1
End Select
End With
Next
DeleteTablesFromSlide = lTables
End Function
Call with:
DeleteTablesFromSlide mySlide