Move a Shape to the next Slide with VBA (PPT) - vba

First of all I'm new to VBA.
I would like to go to move a shape from one slide to the following slide. And I want to do it for each slide of the presentation. (in edit mode)
Dim Sld As Slide
Dim Shp As Shape
For Each Sld In ActivePresentation.Slides
For Each Shp In Sld.Shapes
With Shp
If .Type = msoAutoShape _
And .Left = 715 _
And .Top = 366 _
Then
/!\ In the next slide /!\
.Left = 50 'change the number for desired x position
.Top = 50 'change the number for desired y position
End If
End With
Next 'Shape
Next Sld ' Slide
this is the code I have so far. It is working to move shapes inside the same slide, but I don't really know what to add move the shape in the next slide.
Thank you in advancefor your help.

Here's a little snippet that should help:
' Copy the shape to the clipboard:
Shp.Copy
' Paste the shape to the next slide
' Shp.Parent gives you a reference to the slide the shape is on
' Shp.Parent.SlideIndex + 1 gives you a reference to the NEXT slide
ActivePresentation.Slides(Shp.Parent.SlideIndex + 1).Shapes.Paste
' And delete the original shape
Shp.Delete
You'll need to make sure that there really IS a next slide, of course. ActivePresentation.Slides.Count will tell you how many slides there are.

Related

VBA Code for Powerpoint, changes all MS Object (from Excel) of all slides

I have a lot of slides in Powerpoint. All have MS Object Connections to Excel tables. I am looking for a code, to changes the size and position of all this objects. I have some code already. But the problem is its also changes the size and position of texts. Do someone know how to changes it?
Sub ResizeAll()
For Each tSlide In ActiveWindow.Presentation.Slides
tSlide.Select
With tSlide.Shapes.Item(1)
'assume a blank slide with one image added only
.Select
.Height = 72 * 1000.39
.Width = 72 * 10.67
'algin middle (Horizontal Center)
.Left = 100
.Top = ActivePresentation.PageSetup.SlideHeight / 5
End With
Next
End Sub
I'd stay away from using the Selection object. This code checks that the shape is an OLE object, then resizes only that shape. If this doesn't answer your question, please clarify "also changes the size and position of texts".
Sub EnlargeExcelTables()
Dim oSlide As Slide
Dim oShape As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShape In oSlide.Shapes
If oShape.Type = msoLinkedOLEObject Then
With oShape
'Insert Size process here.
End With
End If
Next oShape
Next oSlide
End Sub

"Error -2147188160 (80048240) Shapes (unknown member): Invalid request." when trying to convert objects to images in PowerPoint

I'm a new stackoverflow user so I'm not sure if I'm doing this right, but I'm trying to post a question on a previously given solution by Steve Rindsberg. I don't have enough reputation to comment, and there doesn't appear to be a way to message another user directly, so I'm posting a new question here.
I can't seem to get the code below to work. I'm using PowerPoint O365 Version 1901 and I have two type of shapes I'm trying to convert, msoChart and msoLinkedOLEObject (some Excel worksheets). I originally changed ppPasteEnhancedMetafile to ppPastePNG because I want PNG's, but it fails with either.
Here is the code:
Sub ConvertAllShapesToPic()
Dim oSl As Slide
Dim oSh As Shape
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
' modify the following depending on what you want to
' convert
Select Case oSh.Type
Case msoChart, msoEmbeddedOLEObject, msoLinkedOLEObject
ConvertShapeToPic oSh
Case msoPlaceholder
If oSh.PlaceholderFormat.ContainedType = msoEmbeddedOLEObject _
Or oSh.PlaceholderFormat.ContainedType = msoLinkedOLEObject _
Or oSh.PlaceholderFormat.ContainedType = msoChart _
Then
ConvertShapeToPic oSh
End If
Case Else
End Select
Next
Next
End Sub
Sub ConvertShapeToPic(ByRef oSh As Shape)
Dim oNewSh As Shape
Dim oSl As Slide
Set oSl = oSh.Parent
oSh.Copy
Set oNewSh = oSl.Shapes.PasteSpecial(ppPastePNG)(1)
With oNewSh
.Left = oSh.Left
.Top = oSh.Top
Do
.ZOrder (msoSendBackward)
Loop Until .ZOrderPosition < oSh.ZOrderPosition
End With
oSh.Delete
End Sub
I noticed if I run ConvertAllShapesToPic from an link/action in Slide Show mode, it doesn't complete and fails silently. If I add a Command Button (ActiveX control) and run it from there I get the following:
Run-time error '-2147188160 (80048240)':
Shapes (unknown member): Invalid request. The specified data type is unavailable.
It's failing on Set oNewSh = sld.Shapes.PasteSpecial(ppPastePNG)(1). After the error, if I go back to the slide and Ctrl-V I get the image, so I know it's working up to that point.
I've tried various solutions I found online for this such as adding DoEvents or ActiveWindow.Panes(1).Activate after the copy, but it doesn't seem to make a difference. Any suggestions?
Thanks
I found some other code to convert the charts and then I break links on the worksheets which automatically turns them in to images.
One thing I figured out was you must be out of slide show mode to break msoLinkedOLEObject links. I'm not 100% sure why... but this is the code that works for me:
Sub DoStuff()
Call LinkedGraphsToPictures
ActivePresentation.SlideShowWindow.View.Exit
Call BreakAllLinks
End Sub
Sub LinkedGraphsToPictures()
Dim shp As Shape
Dim sld As Slide
Dim pic As Shape
Dim shp_left As Double
Dim shp_top As Double
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.Type = msoChart Then
'Retrieve current positioning
shp_left = shp.Left
shp_top = shp.Top
'Copy/Paste as Picture
shp.Copy
DoEvents
sld.Shapes.PasteSpecial DataType:=ppPastePNG
Set pic = sld.Shapes(sld.Shapes.Count)
'Delete Linked Shape
shp.Delete
'Reposition newly pasted picture
pic.Left = shp_left
pic.Top = shp_top
End If
Next shp
Next sld
End Sub
Sub BreakAllLinks()
Dim shp As Shape
Dim sld As Slide
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.Type = msoLinkedOLEObject Then
shp.LinkFormat.BreakLink
End If
Next shp
Next sld
End Sub

Loop through selected slides and delete namned shape

I am trying to create a "sticker" macro for PowerPoint. In short terms I have a button that marks selected slides with a shape that says "Done". This macro is working. However, I also need a macro that deletes the done-sticker on selected slides. What I have right now manages to delete the shape if only one slide is selected. I am very new to VBA in PowerPoint.
Add sticker macro (that works):
Sub StickerDone()
Dim StickerText As String
Dim sld As Slide
StickerText = "Done"
Dim shp As Shape
For Each sld In ActiveWindow.Selection.SlideRange
'Create shape with Specified Dimensions and Slide Position
Set shp = sld.Shapes.AddShape(Type:=msoShapeRectangle, _
Left:=0 * 28.3464567, Top:=0 * 28.3464567, Width:=80, Height:=26.6)
'FORMAT SHAPE
'Shape Name
shp.Name = "StickerDone"
'No Shape Border
shp.Line.Visible = msoFalse
'Shape Fill Color
shp.Fill.ForeColor.RGB = RGB(56, 87, 35)
'Shape Text Color
shp.TextFrame.TextRange.Font.Color.RGB = RGB(255, 255, 255)
'Text inside Shape
shp.TextFrame.TextRange.Characters.Text = StickerText
'Center Align Text
shp.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignCenter
'Vertically Align Text to Middle
shp.TextFrame2.VerticalAnchor = msoAnchorMiddle
'Adjust Font Size
shp.TextFrame2.TextRange.Font.Size = 14
'Adjust Font Style
shp.TextFrame2.TextRange.Font.Name = "Corbel"
'Rotation
shp.Rotation = 0
Next sld
End Sub
Delete sticker macro (that does not work):
Sub StickerDelete()
Dim shp As Shape
Dim sld As Slide
For Each sld In ActiveWindow.Selection.SlideRange
For Each shp In sld.Shapes
If shp.Name Like "StickerDone" Then
shp.Select
shp.Delete
End If
Next shp
Next sld
End Sub
Deleting objects you are iterating over is generally a bad idea. Add them to an array and delete them after your (inner) loop is done.
Try this:
Sub StickerDelete()
Dim shp As Shape
Dim sld As Slide
ReDim ShapesToDelete(0)
Dim ShapeCount
For Each sld In ActiveWindow.Selection.SlideRange
For Each shp In sld.Shapes
If shp.Name Like "StickerDone" Then
'shp.Select
'shp.Delete
ShapeCount = ShapeCount + 1
ReDim Preserve ShapesToDelete(0 To ShapeCount)
Set ShapesToDelete(ShapeCount) = shp
End If
Next shp
Next sld
For i = 1 To ShapeCount
ShapesToDelete(i).Delete
Next
End Sub

PowerPoint loop for specific slide numbers

I have number of slide sets with Excel charts that need to be formatted to be better displayed in PPT (increase font size).
I figured out the code below but can't a way to insert loop so this code is only applied to slides 36 to 45.
I've tried the following code below but doesn't work, I think it's because it references ActivePresentation whilst my formatting code references ActiveWindow but I don't have enought PPT VBA knowledge to fix that.
Dim oPresentation As Presentation
Set oPresentation = ActivePresentation
Dim oSlide As Slide
Dim oSlides As SlideRange
Dim oShape As Shape
Dim slideNumber As Integer
For slideNumber = 36 To 45
>>>REST OF MY CODE INSERTED HERE<<<
Next slideNumber
Sub FormatChartPPT()
'PURPOSE: Increase font size of chart data labels, legend, axes values and categories
Dim ocht As Chart
Dim i As Integer
Dim shp As Shape
'Auto select chart
For Each shp In ActiveWindow.Selection.SlideRange.Shapes
With shp
If .HasChart Then .Select
End With
Next shp
'Apply to selected chart
Set ocht = ActiveWindow.Selection.ShapeRange(1).Chart
'Format data labels
For i = 1 To ocht.SeriesCollection.Count
If ocht.SeriesCollection(i).HasDataLabels Then
With ocht.SeriesCollection(i).DataLabels.Font
.Size = 14
End With
End If
Next i
'Format legend
If ocht.HasLegend Then
With ocht.Legend.Font
.Size = 14
End With
End If
'Format axis values
With ocht.Axes(xlValue).TickLabels.Font
.Size = 14
End With
'Format axis category
With ocht.Axes(xlCategory).TickLabels.Font
.Size = 14
End With
End Sub
You should create a new method that takes a slide and formats the shapes on it as desired. Say we define it as Sub FormatShapes(sld As Slide) (see code later). This method should then be called in your main loop, e.g.:
For SlideNumber = 36 To 45
FormatShapes ActivePresentation.Slides(SlideNumber)
Next SlideNumber
FormatShapes could look like this:
Sub FormatShapes(sld As Slide)
Dim ocht As Chart
Dim shp As Shape
For Each shp In sld.Shapes
If shp.HasChart Then
Set ocht = shp.Chart
... Do shape chart formatting using ocht ...
End If
Next shp
End Sub

Powerpoint VBA: To execute from 2nd slide

Good day,
I have got this code to modify the size and position of every shape on all slides, but would like the procedure to start ONLY from slide 2.
Sub SlideLoop()
Dim osld As Slide
Dim oSh As Shape
For Each osld In ActivePresentation.Slides
' check each shape on the slide
' is it an image or whatever you're looking for?
For Each oSh In osld.Shapes
With oSh
If .Type = msoLinkedPicture _
Or .Type = msoPicture Then
' position it to taste
.Left = 30
.Top = 100
.Height = 750
.Width = 680
' centering/resizing gets trickier
' but is still possible.
' Exercise for the reader?
' Hint:
' ActivePresentation.PageSetup.SlideWidth and .SlideHeight
' tells you the width and height of the slide
'
' All values are in Points (72 to the inch)
End If
End With
Next ' Shape
Next osld ' Slide
End Sub}
What do I need to change?
Check the SlideIndex property of the slides - if it is 1, you skip to the next slide.
Just inside the For Each osld In ActivePresentation.Slides loop, add an if statement:
If osld.SlideIndex > 1 Then
'Your code...
For Each oSh In osld.Shapes
...
Next ' Shape
End If
Olle's correct. Or another approach, my changes in BOLD:
Sub SlideLoop()
Dim osld As Slide
Dim oSh As Shape
Dim x as Long
'For Each osld In ActivePresentation.Slides
For x = 2 to ActivePresentation.Slides.Count
Set oSld = ActivePresentation.Slides(x)
' check each shape on the slide
' is it an image or whatever you're looking for?
For Each oSh In osld.Shapes
With oSh
If .Type = msoLinkedPicture _
Or .Type = msoPicture Then
' position it to taste
.Left = 30
.Top = 100
.Height = 750
.Width = 680
' centering/resizing gets trickier
' but is still possible.
' Exercise for the reader?
' Hint:
' ActivePresentation.PageSetup.SlideWidth and .SlideHeight
' tells you the width and height of the slide
'
' All values are in Points (72 to the inch)
End If
End With
Next ' Shape
Next osld ' Slide
End Sub