Reading text in grouped objects - vba

I made a presentation (with Powerpoint 2016 in Windows 10) on which there are text attached to the images.
I know VBA (not thoroughly) for Word or Excel but I'm new to PP. But Powerpoint grammar confuses me (it will also be for my age). I want to extract all the title and text of all the slides and about this I create the following program which works fine but doesn't let me know the text on grouped objects. Where am I wrong?
Sub RiepilogaConWord()
Dim applWord As Word.Application
Dim docWord As Word.Document
Dim paraWord As Word.Paragraph
Dim oSh As Shape
Dim oSL As Slide
Set applWord = New Word.Application
applWord.Visible = True
applWord.WindowState = wdWindowStateMaximize
Set docWord = applWord.Documents.Add
docWord.ShowSpellingErrors = False
applWord.Selection.TypeText Text:="RIEPILOGO AL " & Format(Date, "dd/mm/YYYY") & " alle ore " & Format(Time, "hh:mm")
docWord.Paragraphs.Add
Set paraWord = docWord.Paragraphs(docWord.Paragraphs.Count)
paraWord.Range.InsertAfter "Totale diapositive " & Presentations(1).Slides.Count
docWord.Paragraphs.Add
For Each oSL In ActivePresentation.Slides
paraWord.Range.InsertAfter oSL.SlideIndex
docWord.Paragraphs.Add
Dim g As Integer
For Each oSh In oSL.Shapes
Select Case oSh.Type
Case Is = msoGroup
On Error Resume Next
oSh.Ungroup.Group , msoTextBox
For g = 1 To oSh.GroupItems.Count
If oSh.TextFrame.HasText Then
paraWord.Range.InsertAfter oSh.Name & ":= " & oSh.TextFrame.TextRange
End If
Next g
On Error GoTo errorhandler
Case Else
With oSh
If .HasTextFrame Then
If .TextFrame.HasText Then
paraWord.Range.InsertAfter oSh.Name & ":= " & .TextFrame.TextRange
End If
End If
End With
End Select
Next
Next
docWord.SaveAs FileName:="C:\EPITETI CINQUE\Presentazione\RiepilogoPresentazione"
applWord.Quit
Set docWord = Nothing
Set applWord = Nothing
Set paraWord = Nothing
Exit Sub
errorhandler:
End Sub
Thank you for any help.
Francesco

Couple of things at issue here
On Error Resume Next is hiding the issue from you. Remove it
oSh.Ungroup.Group , msoTextBox makes no sense, I don't know what you are trying to do there
When you find a grouped object, iterate its members
I've refactored your code to demonstrate.
I've removed the Word stuff to make the Q clearer, and just dump the text to the Immediate Window (Ctrl-G to display it in the VBA editor). You can add it back...
added comments on changed code, marked <---
Added indenting to make the code readable
Sub RiepilogaConWord()
Dim oSh As Shape
Dim oSL As Slide
Dim g As Integer '<--- move here, no point in putting it in the loop, that does nothing
'<--- Add here to use a general error.
' Comment it out while debugging to expose any errors
' On Error GoTo errorhandler handler
For Each oSL In ActivePresentation.Slides
For Each oSh In oSL.Shapes
Select Case oSh.Type
Case Is = msoGroup
'On Error Resume Next '<--- Delete this
'oSh.Ungroup.Group , msoTextBox '<--- Delete this
For g = 1 To oSh.GroupItems.Count
With oSh.GroupItems.Item(g) '<--- simplify
'<--- use g to iterate the grouped items
If .HasTextFrame Then '<--- more robust
If .TextFrame.HasText Then
Debug.Print .Name & ":= " & .TextFrame.TextRange
End If
End If
End With
Next g
'On Error GoTo errorhandler '<--- Delete this
Case Else
With oSh
If .HasTextFrame Then
If .TextFrame.HasText Then
Debug.Print oSh.Name & ":= " & .TextFrame.TextRange
End If
End If
End With
End Select
Next
Next
Exit Sub
errorhandler:
End Sub

Related

Align bottom all shapes according to a name with VBA (Powerpoint)

I have an issue aligning shapes using VBA on PowerPoint (office 360).
I know I can use .Shapes.Range.Align msoAlignBottom, msoFalse
but I don't understand how to make it work with a specific shape name as I always have an error or nothing is happening.
This is the code in which I would like to implement this action:
Sub FixFitToShape()
Dim oSl As Slide
Dim sn As String
Dim oSh As Shape
sn = InputBox("Enter the name of the shape")
On Error Resume Next
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
If oSh.Name = sn Then
Select Case oSh.PlaceholderFormat.Type
Case 1, 3 'Title
oSh.TextFrame2.AutoSize = msoAutoSizeTextToFitShape ' OR msoAutoSizeNone
Case 2, 7 'Text / Content
oSh.TextFrame2.AutoSize = msoAutoSizeShapeToFitText
oSh.Shapes.Range.Align msoAlignBottom, msoTrue
End Select
End If
Next oSh
Next oSl
End Sub
Thank you very much for your help,
Try this code:
Sub FixFitToShape()
Dim oSl As Slide
Dim sn As String
Dim oSh As Shape
'sn = InputBox("Enter the name of the shape")
sn = "Name1" 'debug
'On Error Resume Next
For Each oSl In ActivePresentation.Slides
For i = 1 To oSl.Shapes.Count
Set oSh = oSl.Shapes(i)
If oSh.Name = sn Then
Select Case oSh.Type 'placeholder or not placeholder?
Case msoPlaceholder
' it's a placeholder! check the placeholder's type
If oSh.PlaceholderFormat.Type = ppPlaceholderTitle _
Or oSh.PlaceholderFormat.Type = ppPlaceholderCenterTitle Then
'do smth with placeholder
oSh.TextFrame2.AutoSize = msoAutoSizeTextToFitShape
End If
Case Else 'it's not a placeholder
oSh.TextFrame2.AutoSize = msoAutoSizeShapeToFitText
oSl.Shapes.Range(i).Align msoAlignBottoms, msoTrue 'align it to bottom of the slide
End Select
End If
Next
Next oSl
End Sub
I also recommend removing the On Error Resume Next statement because it hides errors and you don't get useful information about how the code works.
You have to create a ShapeRange that includes the shapes you want to align. Since you are keying off the name of the shape, the example below shows how a wildcard can be used.
Option Explicit
Sub Test()
LineUpShapes 1, "Rectangle", msoAlignTops
End Sub
Sub LineUpShapes(ByVal SlideNumber As Long, _
ByVal ShapeName As String, _
ByVal alignment As MsoAlignCmd)
Dim sl As Slide
Set sl = ActivePresentation.Slides(SlideNumber)
Dim namedShapes() As Variant
Dim shapeCount As Integer
Dim sh As Shape
For Each sh In sl.Shapes
If sh.Name Like (ShapeName & "*") Then
shapeCount = shapeCount + 1
ReDim Preserve namedShapes(shapeCount) As Variant
namedShapes(shapeCount) = sh.Name
Debug.Print "shape name " & sh.Name
End If
Next sh
Dim shapesToAlign As ShapeRange
Set shapesToAlign = sl.Shapes.Range(namedShapes)
shapesToAlign.Align alignment, msoFalse
End Sub
Thank you so much Алексей!
I have readapted your code and it works perfectly! It is always a placeholder in my case ;)
Sub FixFitToShape()
Dim oSl As Slide
Dim sn As String
Dim oSh As Shape
sn = InputBox("Enter the name of the shape")
For Each oSl In ActivePresentation.Slides
For i = 1 To oSl.Shapes.Count
Set oSh = oSl.Shapes(i)
If oSh.Name = sn Then
Select Case oSh.PlaceholderFormat.Type
Case 1, 3 'Title
oSh.TextFrame2.AutoSize = msoAutoSizeTextToFitShape ' OR msoAutoSizeNone
Case 2, 7 'Text / Content
oSh.TextFrame2.AutoSize = msoAutoSizeShapeToFitText
oSl.Shapes.Range(i).Align msoAlignBottoms, msoTrue 'align it to bottom of the slide
End Select
End If
Next
Next oSl
End Sub

How to Bulk Change Source Links?

Trying to change the Excel source file for charts and objects linked in a PowerPoint deck.
I found this:
Sub ChangeOLELinks()
Dim oSld As Slide
Dim oSh As Shape
Dim sOldPath As String
Dim sNewPath As String
' EDIT THIS TO REFLECT THE PATHS YOU WANT TO CHANGE
sOldPath = InputBox("Enter Old Project ie: \Development\", "Old Path")
sNewPath = InputBox("Enter New Project ie: \Test\", "New Path")
On Error GoTo ErrorHandler
For Each oSld In ActivePresentation.Slides
For Each oSh In oSld.Shapes
If oSh.Type = msoLinkedOLEObject Then
Dim stringPath As String
stringPath = Replace(oSh.LinkFormat.SourceFullName, sOldPath, sNewPath, 1, , vbTextCompare)
oSh.LinkFormat.SourceFullName = stringPath
' set update mode to auto and update then set it back to manual
oSh.LinkFormat.AutoUpdate = ppUpdateOptionAutomatic
oSh.LinkFormat.Update
oSh.LinkFormat.AutoUpdate = ppUpdateOptionManual
End If
Next oSh
Next oSld
ActivePresentation.Save
MsgBox ("Done!")
NormalExit:
Exit Sub
ErrorHandler:
MsgBox ("Error " & Err.Number & vbCrLf & Err.Description)
Resume NormalExit
End Sub
This works for OLE objects/links. It isn't updating any of the linked charts.
How can I include charts?
As your charts are paste-linked (4th option) from Excel, they're of msoChart type.
The LinkFormat.SourceFullName property works for this type too so you just have to replace your
If oSh.Type = msoLinkedOLEObject
with
if oSh.Type = msoChart

How do I remove extra spaces in PPT using VBA?

Can anyone help me with the below code? I am trying to use VBA to remove any extra spaces in a PowerPoint presentation.
Sub removeSpaces()
Dim sld As Slide
Dim shp As Shape
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
Do While InStr(shp, " ") > 0
shp.Value = Replace(shp, " ", " ")
shp.Value = Trim(shp.Value)
Next shp
Next sld
End Sub
When I currently run it, it shows an error of "Method or data member not found" and highlights the "shp.Value" part.
a Shape object doesn't have a .Value property. The Instr function may also not evaluate against a Shape object.
https://msdn.microsoft.com/en-us/library/office/ff747227(v=office.14).aspx
Generally, you need to refer to the shape's TextFrame, like:
Dim shpText as String
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.HasTextFrame Then
shpText = shp.TextFrame.TextRange.Text 'Get the shape's text
Do While InStr(shpText, " ") > 0
shpText = Trim(Replace(shpText, " ", " "))
Loop
shp.TextFrame.TextRange.Text = shpText 'Put the new text in the shape
Else
shpText = vbNullString
End If
Next shp
Next sld
End Sub

Deleting named objects in a Powerpoint presentation

I have some objects named"MYobject" in a PowerPoint presentation. I need a macro to delete those objects named "Myobject". How can I do that?
The code I use to tag objects:
Sub TagObject()
On Error GoTo ErrorHandler
Dim oSh As Shape
For Each oSh In ActiveWindow.Selection.ShapeRange
oSh.Tags.Add "Myobject", "YES"
Next
MsgBox "Done! Object has now been tagged.", vbInformation
Exit Sub
ErrorHandler:
MsgBox "Please select an object before tagging.", vbExclamation
End Sub
This will delete all shapes with a Myobject tag = "YES"
Sub DeleteMyObjects()
Dim oSl As Slide
Dim oSh As Shape
Dim x As Long
' note that this will not delete shapes
' within groups
For Each oSl In ActivePresentation.Slides
For x = oSl.Shapes.Count To 1 Step -1
If UCase(oSl.Shapes(x).Tags("Myobject")) = "YES" Then
oSl.Shapes(x).Delete
End If
Next ' Shape
Next ' Slide
End Sub

how to determine a character code (ascii or hex) using Dialogs(wdDialogInsertSymbol) in powerpoint

references that was selected:
- visual basic for applications
- Microsoft powerpoint 14.0 object library
- ole automation
- Microsoft office 14.0 object library
how to determine the character's code using Dialogs(wdDialogInsertSymbol) and what other reference(s) should be selected?
thanks.
Sub fdjlas()
Dim osh As Shape
Dim oSl As Slide
For Each oSl In ActivePresentation.Slides
For Each osh In oSl.Shapes
If osh.HasTextFrame Then
With osh.TextFrame.TextRange
For i = 1 To .Characters.Count
With .Characters(i).Font
MsgBox ("Char number: " & Dialogs(wdDialogInsertSymbol).CharNum)
End With
Next
End With
End If
Next
Next
MsgBox ("done")
End Sub
OUTPUT:
Compile error:
Method or data member not found
MsgBox ("Char number: " & Dialogs(wdDialogInsertSymbol).CharNum)
* the Dialogs gets highlighted
Something like this then?
Dim oSl As Slide
Dim oSh As Shape
Dim i As Long
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
If oSh.HasTextFrame Then
With oSh.TextFrame.TextRange
For i = 1 To .Characters.Count
'With .Characters(i).Font
' MsgBox ("Char number: " & Dialogs(wdDialogInsertSymbol).CharNum)
'End With
MsgBox .Characters(i) & ": " & Asc(.Characters(i))
Next
End With
End If
Next
Next