Powerpoint VBA - How to add text box to multiple slides - vba

So I'm using the following code to add a text box to the header of several slides:
Set myDocument = ActivePresentation.Slides.Range(Array(4, 5, 6))
Set newTextBox = myDocument.Shapes.AddTextbox(msoTextOrientationHorizontal, _
260, Top:=30, Width:=541.44, Height:=43.218)
With newTextBox.TextFrame.TextRange
.Text = "Test Text"
.Font.Size = 17
.Font.Name = "Arial"
End With
When I run this code I get an automation error and it doesn't work. If I do it on a single slide it does work. Does anyone know why? What I'm attempting to do is add headers to specific slides. So I will be using the same method to add different headers to other slides as well.

You can go through all the slides with numbers from the array you set:
Sub slideTextBoxes()
For Each myDocument In ActivePresentation.Slides.Range(Array(4, 5, 6))
Set newTextBox = myDocument.Shapes.AddTextbox(msoTextOrientationHorizontal, _
260, Top:=30, Width:=541.44, Height:=43.218)
With newTextBox.TextFrame.TextRange
.Text = "Test Text"
.Font.Size = 17
.Font.Name = "Arial"
End With
Next
End Sub

Slides don't have headers. But here is code that will work:
Sub AddTextBoxes()
Dim oSlide As Slide
Dim oShape As Shape
For Each oSlide In ActivePresentation.Slides
If oSlide.SlideIndex = 4 Or oSlide.SlideIndex = 5 Or oSlide.SlideIndex = 6 Then
Set oShape = oSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, Left:=260, Top:=30, Width:=541.44, Height:=43.218)
With oShape.TextFrame.TextRange
.Text = "Test Text"
.Font.Size = 17
.Font.Name = "Arial"
End With
End If
Next oSlide
End Sub

Related

Coordinates of a textframe in PowerPoint via VBA

I want to take all the articles in Word document and transform them into PowerPoint Presentation.
1 article = 1 slide (if the text does not fit shrink it, else create a new slide).
I managed to recognize each part of the article by its Style in Word. I get text by its style and insert it into a slide and so forth. I retrieve text by paragraphs (Selection.StartOf and EndOf didn't work).
I didn't find a way to avoid overlaying one text over the other.
Maybe I can get what I need by the coordinates of the textframes?
What I have got so far:
For Each StyleInWord In ActiveDocument.Paragraphs
If StyleInWord.Style = "NAME_OF_THE_ARTICLE" Then
wordText0 = StyleInWord.Range
Set pptLayout = pptPres.SlideMaster.CustomLayouts.Add(ppLayoutBlank)
Set pptSlide = pptPres.Slides.AddSlide(1, pptLayout)
If pptPres.Slides(1).Shapes(1).HasTextFrame Then
pptPres.Slides(1).Shapes(1).Delete
End If
With pptPres.PageSetup
.SlideSize = ppSlideSizeCustom
.SlideHeight = CentimetersToPoints(21.008)
.SlideWidth = CentimetersToPoints(28.011)
End With
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(3.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With mySlide.TextFrame.TextRange
.Text = wordText0
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End If
If StyleInWord.Style = "DESCRIPTION_OF_THE_ARTICLE" Then
wordText1 = StyleInWord.Range
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(5.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With mySlide.TextFrame
With .TextRange
.Text = wordText1
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End With
End If
If StyleInWord.Style = "MAIN_TEXT_OF_THE_ARTICLE" Then
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(7.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
wordText2 = StyleInWord.Range
With mySlide.TextFrame
With .TextRange
.Text = wordText2
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End With
End If
Next StyleInWord
'Here i change the order, so the first slide i create will stay the first by the end of the forEachLoop
i = 1
For i = 1 To pptPres.Slides.Count
pptPres.Slides(i).MoveTo 1
Next i
Each time you add a textbox you set the top position to simply be 2cm lower than the previous one. This takes no account of the height of the previous text box.
There is a very simple solution to this. A text box has properties for both top and height, so just store those in variables. That way you can add each new text box directly below the previous one.
Your code also needs some improvement as some of the presentation setup you are doing should be outside the loop. You should also rename mySlide as pptTextBox so that the variable has a logical name that is consistent with the others.
Set pptLayout = pptPres.SlideMaster.CustomLayouts.Add(ppLayoutBlank) doesn't do what you think it does and is unnecessary. The presentation will already contain a blank layout, helpfully named "Blank", so all you need to do is set a pointer to it, again outside the loop.
'do presentation setup outside the loop
With pptPres.PageSetup
.SlideSize = ppSlideSizeCustom
.SlideHeight = CentimetersToPoints(21.008)
.SlideWidth = CentimetersToPoints(28.011)
End With
'a presentation will already include a blank layout so there is no need to create one
For Each pptLayout In pptPres.SlideMaster.CustomLayouts
If pptLayout.Name = "Blank" Then Exit For
'pptLayout now points to the Blank layout
Next
For Each StyleInWord In ActiveDocument.Paragraphs
If StyleInWord.Style = "NAME_OF_THE_ARTICLE" Then
wordText0 = StyleInWord.Range
Set pptSlide = pptPres.Slides.AddSlide(1, pptLayout)
If pptPres.Slides(1).Shapes(1).HasTextFrame Then
pptPres.Slides(1).Shapes(1).Delete
End If
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), CentimetersToPoints(3.73), _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With pptTextBox
With .TextFrame.TextRange
.Text = wordText0
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxTop = .Top
textBoxHeight = .Height
End With
End If
If StyleInWord.Style = "DESCRIPTION_OF_THE_ARTICLE" Then
wordText1 = StyleInWord.Range
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), textBoxTop + textBoxHeight, _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With pptTextBox
With .TextFrame.TextRange
.Text = wordText1
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxHeight = textBoxHeight + .Height
End With
End If
If StyleInWord.Style = "MAIN_TEXT_OF_THE_ARTICLE" Then
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), textBoxTop + textBoxHeight, _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
wordText2 = StyleInWord.Range
With pptTextBox
With .TextFrame.TextRange
.Text = wordText2
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxHeight = textBoxHeight + .Height
End With
End If
Next StyleInWord
'Here i change the order, so the first slide i create will stay the first by the end of the forEachLoop
i = 1
For i = 1 To pptPres.Slides.Count
pptPres.Slides(i).MoveTo 1
Next i

find the next shape with a special tag

For internal communication purposes in a group of people I have created a macro adding comment fields to a slide - not those of PPT itself.
Dim shp As Shape
Dim sld As Slide
'Comment field
On Error GoTo ErrMsg
If ActiveWindow.Selection.SlideRange.Count <> 1 Then
MsgBox "This function cannot be used for several slides at the same time"
Exit Sub
Else
Set sld = Application.ActiveWindow.View.Slide
Set shp = sld.Shapes.AddShape(Type:=msoShapeRectangle, Left:=0, Top:=104.88182, Width:=198.42507, Height:=28.913368)
shp.Fill.Visible = msoTrue
shp.Fill.Transparency = 0
shp.Fill.ForeColor.RGB = RGB(211, 61, 95)
shp.Line.Visible = msoTrue
shp.Line.ForeColor.RGB = RGB(255, 255, 255)
shp.Line.Weight = 0.75
shp.Tags.Add "COMMENT", "YES"
shp.Select
shp.TextFrame.TextRange.Font.Color.RGB = RGB(255, 255, 255)
shp.TextFrame.TextRange.Characters.Text = "Comment: "
shp.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignLeft
shp.TextFrame.VerticalAnchor = msoAnchorTop
shp.TextFrame.TextRange.Font.Size = 12
shp.TextFrame.TextRange.Font.Name = "Arial"
shp.TextFrame.TextRange.Font.Bold = msoTrue
shp.TextFrame.TextRange.Font.Italic = msoFalse
shp.TextFrame.TextRange.Font.Underline = msoFalse
shp.TextFrame.Orientation = msoTextOrientationHorizontal
shp.TextFrame.MarginBottom = 7.0866097
shp.TextFrame.MarginLeft = 7.0866097
shp.TextFrame.MarginRight = 7.0866097
shp.TextFrame.MarginTop = 7.0866097
shp.TextFrame.WordWrap = msoTrue
shp.TextFrame.AutoSize = ppAutoSizeShapeToFitText
shp.TextFrame.TextRange.Select
End If
Exit Sub
ErrMsg:
MsgBox "Please select a slide"
End Sub
Works well.
I have tagged them, because I want it to be easy to delete all of them at once, e.g., in case you find comments 5 minutes before you have to present. Here's my way to delete them:
Sub CommDel()
Dim sld As Slide
Dim L As Long
If MsgBox("Do you want to delete ALL comments from the entire presentation?", vbYesNo) <> vbYes Then Exit Sub
On Error Resume Next
For Each sld In ActivePresentation.Slides
For L = sld.Shapes.Count To 1 Step -1
If sld.Shapes(L).Tags("COMMENT") = "YES" Then sld.Shapes(L).Delete
Next L
Next sld
End Sub
Works fine, too.
Third step I would like to do, is creating a third macro, called "find next comment". On every click it jumps to the next shape tagged with the tag "COMMENT", no matter if that shape is on the same slide or the next or somewhere else in the presentation. Just the next one, where ever it is. And now I'm completely lost. I am able to do something to all tagged shapes on one slide or inthe entire presentation - as you can see in the function to delete. But what I'm looking for is not selecting all shapes at the same time. In another try I was able to find the first one - but after clicking the macro again nothing seemed to happen, because the macro started searching at the same point and selected the same shape again and again, never jumping to the next one, except I deleted the first one.
Would be great to read your ideas. Thank you in advance. But be careful, I'm far from being a good programmer. ;-)
This starts at the current slide and works toward the end, dropping out of the Sub as soon as the first comment is found:
Sub FindNextComment()
Dim oSlide As Slide
Dim oShape As Shape
Set oSlide = ActiveWindow.View.Slide
For Each oShape In oSlide.Shapes
If oShape.Tags.Count > 0 Then
For y = 1 To oShape.Tags.Count
If oShape.Tags.Name(y) = "COMMENT" Then
oShape.Select
Exit Sub
End If
Next y
End If
Next oShape
For x = oSlide.SlideIndex + 1 To ActivePresentation.Slides.Count
For Each oShape In ActivePresentation.Slides(x).Shapes
If oShape.Tags.Count > 0 Then
For y = 1 To oShape.Tags.Count
If oShape.Tags.Name(y) = "COMMENT" Then
ActivePresentation.Slides(x).Select
oShape.Select
Exit Sub
End If
Next y
End If
Next oShape
Next x
End Sub
Bonus VBA Tip: You can make your code run a little faster by using With statements:
With shp.TextFrame
.MarginBottom = 7.0866097
.MarginLeft = 7.0866097
.MarginRight = 7.0866097
.MarginTop = 7.0866097
.WordWrap = msoTrue
.AutoSize = ppAutoSizeShapeToFitText
.Orientation = msoTextOrientationHorizontal
.VerticalAnchor = msoAnchorTop
With .TextRange
.Characters.Text = "Comment: "
.Paragraphs.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Size = 12
.Name = "Arial"
.Bold = msoTrue
.Italic = msoFalse
.Underline = msoFalse
End With
End With
End With

How to add a custom Text placeholder in one of the master slides in MS Power Point presentation and access it using VBA Script for each slide?

I have created a custom placeholder namely "CustomHeader" of Text Box Type on one of the slides in my Power Point presentation. How can I iterate through all slides inserting the Presentation Title into this placeholder.
I have the following code, which enters the Page No in a custom format in the footer. It also inserts the Section to the footer of the slides. I would like to enter something in the CustomHeader placeholder to every matching slide.
Sub SecFootNew()
Dim oshp As Shape
Dim b_found As Boolean
If ActivePresentation.SectionProperties.Count > 0 Then
Dim osld As Variant
For iSlide = 1 To ActivePresentation.Slides.Count
' Need Help with These
With ActivePresentation.Slides(2).Shapes.Placeholders(CustomHeader).TextFrame.TextRange
.Text = "Happy Honika"
End With
' The Following portion of the code is working Perfectly
If iSlide <> 1 Then
Set osld = ActivePresentation.Slides(iSlide)
' Configure Display of Page Number
With osld.HeadersFooters.DateAndTime
.Visible = False ' True For making the Date Visible
' .UseFormat = True
' .Format = ppDateTimedMMMyy
End With
' Configure Footer
osld.HeadersFooters.Footer.Visible = True
osld.HeadersFooters.SlideNumber.Visible = True
For Each oshp In osld.Shapes
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.Type = ppPlaceholderFooter Then
With oshp.TextFrame.TextRange
.Font.Name = "Calibri"
.Font.Size = 12
.Font.Color = RGB(255, 255, 255)
.Text = ActivePresentation.SectionProperties.Name(osld.sectionIndex)
End With
End If
If oshp.PlaceholderFormat.Type = ppPlaceholderSlideNumber Then
With oshp.TextFrame.TextRange
.Font.Name = "Calibri"
.Font.Size = 12
.Font.Color = RGB(255, 255, 255)
.Text = "Slide " & CStr(osld.SlideIndex) & " of " & CStr(ActivePresentation.Slides.Count)
End With
End If
End If
Next oshp
End If
Next iSlide
End If
End Sub
As you can't add placeholders to slides I assume you mean that you have added a Text Placeholder to one of the Custom Layouts in the Slide Master and you have renamed that placeholder "CustomHeader".
When a slide based on that layout is added to the presentation your placeholder will no longer be called "CustomHeader". Instead it will be called something like "Text Placeholder 3". So your first task is to find the name PowerPoint gives your placeholder when it is inserted.
Then you can simply include an extra condition within your loop:
if oshp.Name = "Text Placeholder #" then _
oshp.TextFrame.TextRange.Text = "Happy Honika"

VBA Syntax errors

I want to override the Word 2010 standard quick styles with my own. But I get an error as shown below:
With tempDoc.Styles(wdStyleNormal) '// <-- here is the error
.Font.Name = "Arial"
.Font.Size = 10
.ParagraphFormat.Alignment = wdAlignParagraphJustify
.ParagraphFormat.LineSpacing = 12
End With
You can find the whole code here: http://qranberry.com/stackoverflow/code.bas
You need to set the document like below .. Code tested and working fine in my system
Sub test()
Dim tempDoc As Document
Set tempDoc = ActiveDocument
With tempDoc.Styles(wdStyleNormal) ' or u can use activedocument instead of tempdoc
.Font.Name = "Arial"
.Font.Size = 30
.ParagraphFormat.Alignment = wdAlignParagraphJustify
.ParagraphFormat.LineSpacing = 12
End With
End Sub

How to move shapes in Word to a bookmark position

I have a shape in a Word document that I need to move to a bookmark location.
I tried to use the "left" and "top" properties, however, this does not work because to my knowledge, bookmark does not have "left" and "right properties.
I have tried to use cut and paste, but this does not work for shapes.
The following is the code to create the shape:
Set shp = ActiveDocument.Content.InlineShapes.AddOLEControl("Forms.CommandButton.1")
With ActiveDocument.InlineShapes(1).OLEFormat.Object
.Caption = "Test"
.Height = 30
.Width = 44
End With
With ActiveDocument.InlineShapes(1).ConvertToShape
.Name = "Test1"
.ZOrder (msoBringInFrontOfText)
End With
Instead of using a bookmark could you use an Absolute Position on the document somewhere?
Dim Test1 As Shape
Set Test1 = ActiveDocument.Shapes("Test1")
With Test1
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Left = InchesToPoints(6.889)
.Top = InchesToPoints(0.374)
End With
End Sub
This is a very old thread, but the basic premise is still valid, and it is possible to insert a control at a bookmarked location (here a bookmark named 'bmShape') using VBA as shown below.
Dim oRng As Range
Dim oShp As InlineShape
Set oRng = ActiveDocument.Bookmarks("bmShape").Range
oRng.Text = ""
Set oShp = oRng.InlineShapes.AddOLEControl("Forms.CommandButton.1")
oRng.End = oRng.End + 1
oRng.Bookmarks.Add "bmShape"
With oShp.OLEFormat.Object
.Caption = "Test"
.Height = 30
.Width = 44
End With
With oShp.ConvertToShape
.Name = "Test1"
.WrapFormat.Type = wdWrapSquare
.WrapFormat.Side = wdWrapBoth
End With