Programmatically copy shapes with source formatting (PowerPoint 2007) - vba

I need to be able to copy shapes (chart, table, etc.) programmatically from one slide to another in PowerPoint 2007 keeping their original colors. The source and destination slides are in different presentations which have different themes.
These shapes might be complex and include a lot of colors, e.g., charts, tables, etc. The destination slide must maintain its theme, so I cannot simply copy the entire original slide colorScheme.
When copying a shape manually in PowerPoint, I get an option to "Keep Source Formatting". This copies all the original colors of the shape, converting theme colors into absolute RGB values.
What is the simplest way to do this programmatically?

You need to go to the slide and use Application.CommandBars.ExecuteMso
If you don't need to return to the previously selected slide afterwards, you can skip DoEvents and the second call to Application.CommandBars.ExecuteMso
It seemed like the position of the new shape was sometimes a little bit skewed after pasting, so I obtain a reference to the last shape in the Shapes collection of the second slide and copy the position of the original shape.
At least on my machine, without DoEvents, the macro would do nothing when I executed it (but it would work if I stepped through it).
Sub CopySelectedShapeToNextSlide()
Dim oShape As Shape
Dim oSlide As Slide
Dim nextSlide As Slide
Dim newShape As Shape
Set oShape = Application.ActiveWindow.Selection.ShapeRange(1)
Set oSlide = Application.ActiveWindow.Selection.SlideRange(1)
Set nextSlide = oSlide.Parent.Slides(oSlide.SlideIndex + 1)
oShape.Copy
Application.ActiveWindow.View.GotoSlide nextSlide.SlideIndex
Application.CommandBars.ExecuteMso "PasteSourceFormatting"
Set newShape = nextSlide.Shapes(nextSlide.Shapes.Count)
newShape.Left = oShape.Left
newShape.Top = oShape.Top
DoEvents
Application.ActiveWindow.View.GotoSlide oSlide.SlideIndex
Debug.Print newShape.Name
End Sub

Related

What are some other methods I can use INSTEAD of "ActivePresentation" in PowerPoint VBA

I'm currently working on PowerPoint VBA and writing a code to be able to copy the first slide and paste it again in the same presentation. However, I keep getting the error "Clipboard is empty or contains data which may not be posted here" and according to Microsoft page the problem is the use of "ActivePresentation"
I'm looking for another way to refer to the slide that I have open without using ActivePresentation. Any help? Ideas?
The line of code I use ActivePresentation is below:
ActivePresentation.Slides(1).Copy
ActivePresentation.Slides.Paste(ActivePresentation.Slides.Count=1)
Don't copy, duplicate
Dim NewSlide as Slide
Set newSlide = ActivePresentation.Slides(1).Duplicate
NewSlide.MoveTo toPos:=4 'move it to become the fourth slide
Slight variant on Harassed Dad's solution. PPT barks at the Set line because Duplicate returns a SlideRange object rather than a Slide object. .Duplicate(1) returns the first slide in the range as a Slide object. This duplicates slide 2 and moves it to the first position in the presentation.
Sub CopySlide()
Dim oSl As Slide
With ActivePresentation
Set oSl = .Slides(2).Duplicate(1)
oSl.MoveTo (1)
End With
End Sub

Copy paste shape by using VBA in PowerPoint

I'm trying to copy paste shape by using VBA in PowerPoint.
This code can't exit from If...End If statement.
What's wrong with my code?
Sub pasteshape()
Dim oSl As Slide
Dim oSh As Shape
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
If oSh.Fill.Type = msoFillSolid Then
oSh.Duplicate
End If
Next
Next
End Sub
You're changing the collection you're iterating, as you're iterating it; that's always a bad idea!
So you have an infinite loop, because every time you duplicate a shape, you effectively add a solid-fill shape to the oSl.Shapes collection, which is then a solid-fill shape that should be duplicated - right?
You need a way to separate the process of knowing which shapes to copy and that of copying solid-fill shapes.
Make a new collection:
Dim solidShapes As Collection
Set solidShapes = New Collection
Now iterate the slides and their shapes, but instead of copying right away, add them to that collection:
For Each currentShape In currentSlide.Shapes
If currentShape.Fill.Type = msoFillSolid Then
solidShapes.Add currentShape
End If
Next
Notice I'm using readable identifiers without Systems Hungarian (aka useless) prefixes (read that link! Especially if you're a firm believer of Hungarian Notation).
Now you can iterate the solidShapes collection, and .Duplicate every item in it.

Copy a shape from a PowerPoint Master slide layout to the cu

In PowerPoint 2010:
I would like to create a macro that will copy a shape that I created on one of the layout slides of the master slide, and will paste it to the active slide - the slide that i'm on now when I'm running that macro.
(I need it so that i could utilize it on the slide- clone it, etc.)
How I do that?
Thanks,
You haven't mentioned how exactly you'd identify the shape to be copied, but if you know in advance that it'll be, for example, the sixth shape on the second custom layout of the first master in the presentation and you want to copy/paste it onto slide 3:
Sub Thing()
Dim oSh As Shape
' This copies the sixth shape on the second layout of the first master
' Change as needed
Set oSh = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(2).Shapes(6)
oSh.Copy
Set oSh = ActivePresentation.Slides(3).Shapes.Paste(1)
With oSh
' do any formatting/sizing/etc. you like here
End With
End Sub

PowerPoint vba - For each shape in each Layout in MasterView

I'm trying to programatically change the language of each shape in each customlayout in a PowerPoint template and I can't figure out how to do this. I've done it before, but I can't find the macro anymore so I don't really know how I did it. I've been able to select each custom layout though. But I need to loop through each textbox in each layout and select the language as well. My problem is targetting each shape. How do I do this?
This is what I've got so far:
ActiveWindow.ViewType = ppViewSlideMaster
For Each oLayout In ActivePresentation.SlideMaster.CustomLayouts
oLayout.Select
Next
This basically loops through each layout. But I can't figure out how to select each placeholder? How do I do this?
Edit: Resolution is now:
For Each oLayout In ActivePresentation.SlideMaster.CustomLayouts
oLayout.Select
Dim oShape As Shape
For Each oShape In oLayout.Shapes
oShape.Select
Next
Next
Loop through oLayout.Shapes, or perhaps oLayout.Shapes.Placeholders.
Thanks you two. I needed a solution to updating an embedded Excel object on the master slide.
This lead me to the perfect solution
'loops through all shapes in slidemaster
Dim oShape As Shape
For Each oShape In ActivePresentation.SlideMaster.Shapes
oShape.Select
'checks for excel object (type=7)
If oShape.Type = msoEmbeddedOLEObject Then
oShape.OLEFormat.Activate
ActiveWindow.Selection.Unselect 'deactivates shape
End If
Next

How to switch between "active paper" and "slides" in Power Point VBA

I have a simple question regarding PowerPoint VBA:
Which VBA code should I use to switch between the "active sheet of paper" (I am sorry I don't know how to name it properly), in which I am doing something with the object(s), and the file (or "field", again sorry for my poor terminology) where all the slides are ?
For example, if I want to move a selected object in the "active sheet of paper" I would use this macro:
ActiveWindow.Selection.ShapeRange.IncrementLeft
6#
and if I want to copy the selected slide in the slides file, I would use this code:
ActiveWindow.Selection.Copy
ActiveWindow.View.Paste
But how can I connect these two pieces of script? Let's say I want to move an object in the "active sheet of paper", then copy this whole "sheet", then create its twin in the slides field, and then jump into the twin sheet of paper to do something with objects there?
Shortly, how do I switch from "paper" to "slides" and back to "paper" in VBA?
(Again, I am sorry for terrible terminology here, I hope you understand what I mean here.)
Thank you all in advance.
If you record a macro in PowerPoint and examine the code, you'll see that it uses the Selection object for just about everything. That's sometimes useful (because it means it's more likely that the code will do what you want if you select another object), but for anything more than a very short macro, it's probably better to refer to the objects directly, as in the following code:
Sub Test()
' Get the active presentation
Dim oPresentation As Presentation
Set oPresentation = ActivePresentation
' Get the first slide in the presentation
Dim oSlide As Slide
Set oSlide = oPresentation.Slides(1)
' Get the first shape on the slide
Dim oShape As Shape
Set oShape = oSlide.Shapes(1)
' Nudge the shape to the right
oShape.Left = oShape.Left + 1
' Copy the whole slide
oSlide.Copy
' Paste the slide as a new slide at position 2
Dim oNewSlides As SlideRange
Set oNewSlides = oPresentation.Slides.Paste(2)
' Get a reference to the slide we pasted
Dim oNewSlide As Slide
Set oNewSlide = oNewSlides(1)
' Get the first shape on the NEW slide
Dim oNewShape As Shape
Set oNewShape = oNewSlide.Shapes(1)
' Nudge the shape to the right
oNewShape.Left = oNewShape.Left + 1
End Sub
Note that pretty much every object has a Select method, so if you do want to explicitly select something, you can. In some cases, you may need to change the active window's view type first - so for example, you can't select a shape on a slide while in slide-sorter view.