I use PowerPoint in my lectures and print a subset of the slides for my students (to allow them to fill in blanks before I show my answers). Currently, I put a light blue circle at the bottom left of slides that I want to hide while printing (but not while lecturing). I then manually hide slides when it is time to print them, then unhide all of the slides before lecturing. Is there any way to automate this process? I use Office 365 on both PCs and Macs.
This will get you started, save this as pptm then save a copy as addin:
ChangeAnswersSlideState - changes activeslide to be an Answer Slide or not
PrintStudentHandout - Hide Answer slides and then print, then unhide
Option Explicit
Private Const ANS_ID As String = "ANS"
Sub PrintStudentHandout()
ChangeAnswersSlideVisible
With ActivePresentation
.PrintOptions.ActivePrinter = "Microsoft XPS Document Writer"
.PrintOut
End With
ChangeAnswersSlideVisible msoFalse
End Sub
Private Sub ChangeAnswersSlideVisible(Optional Hide As MsoTriState = msoTrue)
Dim oSlide As Slide, oShp As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShp In oSlide.Shapes
If IsAnswersShape(oShp) Then
oSlide.SlideShowTransition.Hidden = Hide
Exit For
End If
Next oShp
Next oSlide
End Sub
Sub ChangeAnswersSlideState()
Dim oShp As Shape, bChanged As Boolean
bChanged = False
For Each oShp In Application.ActiveWindow.View.Slide.Shapes
If IsAnswersShape(oShp) Then
oShp.Delete
bChanged = True
End If
Next oShp
If Not bChanged Then MakeAnswersSlide
End Sub
Private Sub MakeAnswersSlide(Optional ByRef AnswerSlide As Slide = Nothing)
If AnswerSlide Is Nothing Then Set AnswerSlide = Application.ActiveWindow.View.Slide
With AnswerSlide.Shapes.AddShape(msoShapeOval, -80, 460, 72, 72)
.TextFrame.TextRange.Text = ANS_ID
End With
End Sub
Private Function IsAnswersShape(ByRef CheckShape As Shape) As Boolean
Dim bIsAnAnswerShape As Boolean
bIsAnAnswerShape = False
With CheckShape
If .AutoShapeType = msoShapeOval Then
If .HasTextFrame Then
If .TextFrame.TextRange.Text = ANS_ID Then
bIsAnAnswerShape = True
End If
End If
End If
End With
IsAnswersShape = bIsAnAnswerShape
End Function
Related
I am making a PowerPoint Presentation with a lot of math equations.
I would like to ask if there are any way to change the color of those equations automatically.
I found a solution but it is for Word documents there:
https://www.codeproject.com/Tips/1378034/Macro-to-Change-the-Color-of-all-Equations-in-a-Wo
Sub Change_Equation_Color()
'Macro to Change the Font Color of all Equations in a Word Document
Dim Eq As OMath
For Each Eq In ActiveDocument.OMaths
Eq.Range.Select
Selection.Font.ColorIndex = wdDarkBlue 'Choose Color here, e.g. wdBlack
'Selection.Font.TextColor.RGB = RGB(255, 0, 255) 'To use RGB color, uncomment this line and comment the one above
Next
End Sub
This macro unfortunately does not work in PowerPoint. Could you please provide any solutions for this?
Thank you!
Here's the PowerPoint equivalent:
Sub ColorEquation()
Dim oSlide As Slide
Dim oShape As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShape In oSlide.Shapes
If oShape.HasTextFrame Then
If oShape.TextFrame2.HasText Then
If oShape.TextFrame2.TextRange.MathZones.Length > 0 Then
oShape.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(255, 0, 255)
End If
End If
End If
Next oShape
Next oSlide
End Sub
Use Count instead of Length at line 8.
Sub ColorEquation()
Dim oSlide As Slide
Dim oShape As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShape In oSlide.Shapes
If oShape.HasTextFrame Then
If oShape.TextFrame2.HasText Then
If oShape.TextFrame2.TextRange.MathZones.Count > 0 Then
oShape.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(255, 0, 255)
End If
End If
End If
Next oShape
Next oSlide
End Sub
In the master layout I defined the placeholders where the images are added, but I can't find a solution to scale to fit them. The reason for the image placeholders is that the pictures can be added for different layouts without adding the exact location properties (Left, Top, Width, Height)
My current code looks like this:
Sub InsertPictures
ActivePresentation.Slides(1).Shapes.AddPicture FileName:="U:\xyz\EAP.png", _LinkToFile:=msoTrue
ActivePresentation.Slides(1).Shapes.AddPicture FileName:="U:\xyz\DAP_01.png", LinkToFile:=msoTrue, _
End Sub
In the picture below you can see on the left side how the picture is added with a image placeholder and on the right side how it should be added, when its fitted.
I found a code which does the "crop to fit", but it only works when the slide is selected:
Sub cropFit()
Dim osld As Slide
Dim oshp As Shape
On Error Resume Next
Set osld = ActiveWindow.View.Slide
If Not osld Is Nothing Then
For Each oshp In osld.Shapes
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.Type = ppPlaceholderPicture Then
oshp.Select
CommandBars.ExecuteMso ("PictureFitCrop")
End If 'picture placeholder
End If 'placehoder
Next oshp
End If ' Slide selected
End Sub
How do I have to change the code that directly after adding the images with the code above (Sub Insert Pictures), the images are cropped to fit in the presentation mode?
Thanks for your help in advance!
What we need to do is get the Picture Placeholders, and assign pictures to those placeholders. You will put your file names in an array that can hold as many strings as placeholders ( I used 3 below because you say you have 3 picture placeholders). Then we will insert the pictures at those placeholders and crop them to fit. I borrowed concepts used here and here. So your code would be:
Sub InsertPictures()
Dim FileNames(1 To 3) As String, Shps As Shapes, i As Integer
Set Shps = ActivePresentation.Slides(1).Shapes
FileNames(1) = "U:\xyz\EAP.png"
FileNames(2) = "U:\xyz\DAP_01.png"
' Filenames(3) = "Blah Blah Blah"
i = 1
For Each Shp In Shps.Placeholders
' You only need to work on Picture place holders
If Shp.PlaceholderFormat.Type = ppPlaceholderPicture Then
With Shp
' Now add the Picture
Set s = Shps.AddPicture(FileNames(i), msoTrue, msoTrue, _
.Left, .Top, .Width, .Height)
' Insert DoEvents here specially for big files, or network files
' DoEvents halts macro momentarily until the
' system finishes what it's doing which is loading the picture file
DoEvents
s.Select
CommandBars.ExecuteMso ("PictureFitCrop")
i = i + 1
End With
End If
If (i > UBound(FileNames)) Then Exit For
If (FileNames(i) = "") Then Exit For
Next Shp
End Sub
Thank you guys for your help! I managed to solve this problem with the following code:
Sub CropToFit()
ActivePresentation.Slides(1).Shapes.AddPicture FileName:="U:\xyz\EAP.png", _LinkToFile:=msoTrue
ActivePresentation.Slides(1).Shapes.AddPicture FileName:="U:\xyz\DAP_01.png", LinkToFile:=msoTrue, _
ActivePresentation.SlideShowWindow.view.Exit
Do Events
Dim osld As Slide
Dim oshp As Shape
On Error Resume Next
Set osld = ActiveWindow.view.Slide
If Not osld Is Nothing Then
For Each oshp In osld.Shapes
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.Type = ppPlaceholderPicture Then
oshp.Select
CommandBars.ExecuteMso ("PictureFitCrop")
End If 'picture placeholder
End If 'placehoder
Next oshp
End If ' Slide selected
End Sub
I have the following macro that aligns 1 selected picture at a time in Power Point:
Sub Align()
With ActiveWindow.Selection.ShapeRange
.Left = 50
.Top = 100
End With
End Sub
This code works if I run the macro on a selected picture in a slide.
But how can I run this script for each picture of all slides?
This will do that for you Jose:
' PowerPoint VBA to reposition all pictures in all slides in a deck
' Written by Jamie Garroch of YOUpresent Ltd.
' http://youpresent.co.uk/
Option Explict
Sub RepositionAllPictures()
Dim oSld As Slide
Dim oShp as Shape
For Each oSld in ActivePresentation.Slides
For Each oShp in oSld.Shapes
If oShp.Type = msoPicture Then RepositionShape oShp
If oShp.Type = msoPlaceholder Then
If oShp.PlaceholderFormat.ContainedType = msoPicture Or _
oShp.PlaceholderFormat.ContainedType = msoLinkedPicture Then _
RepositionShape oShp
End If
Next
Next
End Sub
Sub RepositionShape(oShp As Shape)
oShp.Left = 50
oShp.Top = 100
End Sub
In presentation mode, I want only unhidden slides to appear with consecutive page numbers. How can I avoid that hidden slides are counted?
Thank you Steve. I found an answer to my question elsewhere. The function below allows you to avoid that hidden slides are interfering with the slide numbers of unhidden slides in presentation mode.
Sub Number_NonHidden()
'For v.2007 onwards only
Dim osld As Slide
Dim objSN As Shape
Dim lngNum As Long
'check all slides
For Each osld In ActivePresentation.Slides
'Is it hidden
If osld.SlideShowTransition.Hidden Then
osld.HeadersFooters.SlideNumber.Visible = False
Else
osld.HeadersFooters.SlideNumber.Visible = True
Set objSN = getNumber(osld)
lngNum = lngNum + 1
If Not objSN Is Nothing Then ' there is a number placeholder
objSN.TextFrame.TextRange = CStr(lngNum + 1)
End If
End If
Next osld
End Sub
Function getNumber(thisSlide As Slide) As Shape
For Each getNumber In thisSlide.Shapes
If getNumber.Type = msoPlaceholder Then
If getNumber.PlaceholderFormat.Type = ppPlaceholderSlideNumber Then
'it's the slide number
Exit Function
End If
End If
Next getNumber
End Function
In order to avoid that the title slide is numbered insert lngNum = -1 as follows and delete the slide number box in the master title slide.
'check all slides
lngNum = -1
For Each osld In ActivePresentation.Slides
In VBA you'd do something like this:
Sub CountSlides()
Dim oSl As Slide
Dim x As Long
For Each oSl In ActivePresentation.Slides
If Not oSl.SlideShowTransition.Hidden Then
x = x + 1
End If
Next
MsgBox x
End Sub
In other words, if the SlideShowTransition.Hidden property of the slide is True, don't count it.
I'm want to perform a variety of formatting options on images in slides.
The macro runs on images that I've SELECTED in a slide, but I'd like to run the macro without selecting the images.
Here's how I'm currently manipulating images (in this case aligning the image to the horizontal center of the slide) and the piece of code that I'm looking for help replacing:
With ActiveWindow.Selection.ShapeRange
.Align (msoAlignCenters), msoTrue
End With
Here's the entire code body so far:
Sub TestCenterImage()
Dim osld As Slide
Dim oshp As Shape
For Each osld In ActivePresentation.Slides
If osld.SlideIndex > 1 Then Exit Sub 'I don't know if I need this line
For Each oshp In osld.Shapes
If CheckIsPic(oshp) = True Then 'Making sure that we're only working with images
With ActiveWindow.Selection.ShapeRange 'The portion of code I need help with
.Align (msoAlignCenters), msoTrue
End With
End If
Next oshp
Next osld
End Sub
Function CheckIsPic(oshp As Shape) As Boolean
If oshp.Type = msoPicture Then CheckIsPic = True
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.ContainedType = msoPicture Then CheckIsPic = True
End If
End Function
Try it this way instead:
Sub TestCenterImage()
Dim osld As Slide
Dim oShp As Shape
For Each osld In ActivePresentation.Slides
'If osld.SlideIndex > 1 Then Exit Sub 'I don't know if I need this line
For Each oShp In osld.Shapes
If CheckIsPic(oShp) = True Then 'Making sure that we're only working with images
CenterOnSlide oShp
'End With
End If
Next oShp
Next osld
End Sub
Function CheckIsPic(oShp As Shape) As Boolean
If oShp.Type = msoPicture Then CheckIsPic = True
If oShp.Type = msoPlaceholder Then
If oShp.PlaceholderFormat.ContainedType = msoPicture Then CheckIsPic = True
End If
End Function
Sub CenterOnSlide(oShp As Shape)
Dim sngSlideWidth As Single
Dim sngSlideHeight As Single
sngSlideWidth = ActivePresentation.PageSetup.SlideWidth
sngSlideHeight = ActivePresentation.PageSetup.SlideHeight
oShp.Left = sngSlideWidth / 2 - oShp.Width / 2
oShp.Top = sngSlideHeight / 2 - oShp.Height / 2
End Sub
For Each osld In ActivePresentation.Slides
If osld.SlideIndex > 1 Then Exit Sub 'I don't know if I need this line
' If you leave that line in, your code will only touch the first slide in the presentation.
' If that's what you want, fine. Otherwise, delete it and the matching End If below.
For Each oshp In osld.Shapes
If CheckIsPic(oshp) = True Then 'Making sure that we're only working with images
' With ActiveWindow.Selection.ShapeRange 'The portion of code I need help with
' Instead:
With oshp
.Align (msoAlignCenters), msoTrue
End With
End If
Next oshp
Next osld
End Sub