(PPT VBA) Select textrange.characters failure - vba

I want to select some characters in textrange. It works when I use "With activepresentation.slides(2).shapes(2)".
The codes:
dim Txtrng as textrange
dim Words_Instr as integer
dim aa as string
With ActivePresentation.Slides(2).Shapes(2)
Set Txtrng = .TextFrame.textRange
aa = "AAAA"
Words_Instr = InStr(Txtrng, aa)
If Words_Instr > 0 Then
Txtrng.Characters(Words_Instr, Len(aa)).Select
end if
end with
It doesn't work when I use "pres.". I want to do the same thing in every shape of every slide.
The Codes:
dim pres as presentation
dim sli as slide
dim shp as shape
dim Txtrng as textRange
dim Words_Instr as integer
dim aa as string
set pres=Presentations.Open(filename:=f1)
aa = "AAAA"
For Each sLi In pRes.Slides
for each sHp in sLi.shapes
If sHp.HasTextFrame = msoTrue Then
Set Txtrng = sHp.TextFrame.textRange
Words_Instr = InStr(Txtrng, aa)
If Words_Instr > 0 Then
Txtrng.Characters(Words_Instr, Len(aa)).Select
end if
end if
next
next
It always showed error in “txtrng.characters(...).select”
I will be grateful for any help.

If you only refer to current presentation instead of open another ppt, then the following code will do, I only change set pre part only, copy and paste this code into your existing ppt and run it, it will select the text on the shape:
Sub test()
Dim pres As Presentation
Dim sli As Slide
Dim shp As Shape
Dim Txtrng As TextRange
Dim Words_Instr As Integer
Dim aa As String
Set pres = ActivePresentation
aa = "AAAA"
For Each sli In pres.Slides
For Each shp In sli.Shapes
If shp.HasTextFrame = msoTrue Then
Set Txtrng = shp.TextFrame.TextRange
Words_Instr = InStr(Txtrng, aa)
If Words_Instr > 0 Then
Txtrng.Characters(Words_Instr, Len(aa)).Select
End If
End If
Next
Next
End Sub

Related

Copy/Paste CheckBoxes If True In PowerPoint

I am trying to copy all true or checked boxes on all slides and paste them onto one slide within my presentation. I can't seem to figure it out. Below is the code that I am using. Any help is appreciated.
`Sub ckbxCopy()
Dim shp As Shape
Dim sld As Slide
Dim i As Integer
On Error Resume Next
For Each sld In ActivePresentation.Slides
For i = 1 To 4
shp = ActivePresentation.Slides("CheckBox" & CStr(i))
If Err.Number = 0 Then ' shape exists
If shp.OLEFormat.Object.Value = True Then
shp.Copy
ActivePresentation.Slides(3).Shapes.Paste
End If
End If
Next i
Next sld
End Sub`
This works for me:
Sub ckbxCopy()
Dim shp As Shape, pres As Presentation
Dim sld As Slide, sldDest As Slide
Dim i As Integer, t As Long
Set pres = ActivePresentation
Set sldDest = pres.Slides(3) 'where shapes are to be pasted
sldDest.Shapes.Range.Delete 'remove existing shapes
t = 20
For Each sld In pres.Slides
If sld.SlideIndex <> sldDest.SlideIndex Then
For i = 1 To 4
Set shp = Nothing
Set shp = SlideShape(sld, "CheckBox" & CStr(i))
If Not shp Is Nothing Then
If shp.OLEFormat.Object.Value = True Then
shp.Copy
pres.Slides(3).Shapes.Paste.Top = t 'paste and position
t = t + 20
End If
End If
Next i
End If
Next sld
End Sub
'Return a named shape from a slide (or Nothing if the shape doesn't exist)
Function SlideShape(sld As Slide, shapeName As String) As Shape
On Error Resume Next
Set SlideShape = sld.Shapes(shapeName)
End Function

Deleting all datalabels except the last two in i time series

I need a macro for deleting all datalabels in a linechart except the last two.
I've managed to delete one column of labels, any help on how i can delete the rest.
Here is the code im using currently:
Option Explicit
Sub Format_linechart()
Dim sld As Slide
Dim shp As Shape
Dim chart As chart
Dim sr As Series
Dim i As Long
Dim Cnt As Integer
Set sld = Application.ActiveWindow.View.Slide
For Each shp In sld.Shapes
If shp.HasChart Then
Set chart = shp.chart
For i = 1 To chart.SeriesCollection.Count
Set sr = chart.SeriesCollection(i)
sr.HasDataLabels = True
sr.Points(sr.DataLabels.Count - 2).DataLabel.Delete
Next i
End If
Next shp
End Sub
I've also tried adding lines for each set of datalabels but i then get an error if there are to few datapoints in the chart.
Option Explicit
Sub Format_linechart()
Dim sld As Slide
Dim shp As Shape
Dim chart As chart
Dim sr As Series
Dim i As Long
Dim Cnt As Integer
Set sld = Application.ActiveWindow.View.Slide
For Each shp In sld.Shapes
If shp.HasChart Then
Set chart = shp.chart
For i = 1 To chart.SeriesCollection.Count
Set sr = chart.SeriesCollection(i)
sr.HasDataLabels = True
sr.Points(sr.DataLabels.Count - 2).DataLabel.Delete
sr.Points(sr.DataLabels.Count - 3).DataLabel.Delete
sr.Points(sr.DataLabels.Count - 4).DataLabel.Delete
sr.Points(sr.DataLabels.Count - 5).DataLabel.Delete
sr.Points(sr.DataLabels.Count - 6).DataLabel.Delete
Next i
End If
Next shp
End Sub
For each each series, you can loop through each point and delete the data label for the desired points . . .
Option Explicit
Sub Format_linechart()
Dim sld As Slide
Dim shp As Shape
Dim chart As chart
Dim sr As Series
Dim i As Long
Dim j As Long
Dim Cnt As Integer
Set sld = Application.ActiveWindow.View.Slide
For Each shp In sld.Shapes
If shp.HasChart Then
Set chart = shp.chart
For i = 1 To chart.SeriesCollection.Count
Set sr = chart.SeriesCollection(i)
sr.HasDataLabels = True
For j = 1 To sr.Points.Count - 2
sr.Points(j).DataLabel.Delete
Next j
Next i
End If
Next shp
End Sub

Powerpoint - find a specified word in a text box within a group and add a comment

I am looking to search for a specified word or phrase in a presentation and then add a comment to all slides where it appears. I have the below code which works well, however I want to be be able to search for text boxes that are in groups (the below code only searches in text boxes)
Any suggestions would be really appreciated.
Sub FindWordAndAddComment()
Dim sld As Slide
Dim shp As Shape
Dim txtRng As TextRange, rngFound As TextRange
Dim i As Long, n As Long
Dim TargetList
'enter or word phrase here
TargetList = Array("this is a test")
For Each sld In Application.ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.HasTextFrame Then
Set txtRng = shp.TextFrame.TextRange
For i = 0 To UBound(TargetList)
Set rngFound = txtRng.Find(TargetList(i))
Do While Not rngFound Is Nothing
n = rngFound.Start + 1
With sld.Comments.Add(12, 12, "found", "me", "'this is a test' has been found")
Set rngFound = txtRng.Find(TargetList(i), n)
End With
Loop
Next
End If
Next
Next
End Sub
This assumes that all groups have the default "Group" name:
Dim sld As Slide
Dim shp As Shape
Dim txtRng As TextRange, rngFound As TextRange
Dim i As Long, n As Long
Dim TargetList(2) As String
Sub FindWordAndAddComment()
'enter or word phrase here
TargetList(0) = "This is a test"
TargetList(1) = "This is a text"
TargetList(2) = "Here we go"
For Each sld In Application.ActivePresentation.Slides
For Each shp In sld.Shapes
If InStr(shp.Name, "Group") <> 0 Then
For X = 1 To shp.GroupItems.Count
If shp.GroupItems(X).HasTextFrame Then
Set txtRng = shp.GroupItems(X).TextFrame.TextRange
FindTextAddComment
End If
Next X
Else
If shp.HasTextFrame Then
Set txtRng = shp.TextFrame.TextRange
FindTextAddComment
End If
End If
Next
Next
End Sub
Sub FindTextAddComment()
For i = 0 To UBound(TargetList)
Set rngFound = txtRng.Find(TargetList(i))
Do While Not rngFound Is Nothing
n = rngFound.Start + 1
With sld.Comments.Add(12, 12, "found", "me", "'this is a test' has been found")
Set rngFound = txtRng.Find(TargetList(i), n)
End With
Loop
Next
End Sub

PowerPoint VBA select slide

My goal is to creat ppt via VBA. I have already the template in my desktop that i need to use. This part of the code is ok.
However I did not find how to select slides in the ppt. I try many ways and i get all the times error.
If someone could help me.
Option Explicit
Sub CreatePowerPoint()
Dim mySlide As PowerPoint.Slide
Dim myShapeRange As PowerPoint.Shape
Dim oPA As PowerPoint.Application
Dim oPP As PowerPoint.Presentation
Dim oPS As PowerPoint.SlideRange
Dim strTemplate As String
Dim rng As Range
strTemplate = "C:\Users\290866\Desktop\vba\PPT\Template.potx"
Set oPA = New PowerPoint.Application
oPA.Visible = msoTrue
oPA.Presentations.Open strTemplate, untitled:=msoTrue
If Not oPS Is Nothing Then Set oPS = Nothing
If Not oPP Is Nothing Then Set oPP = Nothing
If Not oPA Is Nothing Then Set oPA = Nothing
Err_PPT:
If Err <> 0 Then
MsgBox Err.Description
Err.Clear
Resume Next
End If
Set rng = ThisWorkbook.Sheets("Credit Recommendation").Range("B2:N59")
ActivePresentation.Slides (1)
rng.Copy
mySlide.Shapes.PasteSpecial (ppPasteBitmap)
Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
myShapeRange.LockAspectRatio = msoFalse
myShapeRange.Left = 20
myShapeRange.Top = 80
myShapeRange.Height = 400
myShapeRange.Width = 680
Application.CutCopyMode = False
End Sub
Thank you!!!
Here is your code modified to work. I explain the modifications below
Option Explicit
Sub CreatePowerPoint()
Dim mySlide As PowerPoint.Slide
Dim myShapeRange As PowerPoint.Shape
Dim oPA As PowerPoint.Application
Dim oPP As PowerPoint.Presentation
Dim oPS As PowerPoint.SlideRange
Dim strTemplate As String
Dim rng As Range
strTemplate = "C:\Users\290866\Desktop\vba\PPT\Template.potx"
Set oPA = New PowerPoint.Application
oPA.Visible = msoTrue
'changed this line to assign the new presentation to your variable
Set oPP = oPA.Presentations.Open(strTemplate, untitled:=msoTrue)
'If Not oPS Is Nothing Then Set oPS = Nothing
'If Not oPP Is Nothing Then Set oPP = Nothing
'If Not oPA Is Nothing Then Set oPA = Nothing
Err_PPT:
If Err <> 0 Then
MsgBox Err.Description
Err.Clear
Resume Next
End If
Set rng = ThisWorkbook.Sheets("sheet1").Range("B2:N59")
Set mySlide = oPP.Slides(1)
rng.Copy
mySlide.Shapes.PasteSpecial (ppPasteBitmap)
Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
myShapeRange.LockAspectRatio = msoFalse
myShapeRange.Left = 20
myShapeRange.Top = 80
myShapeRange.Height = 400
myShapeRange.Width = 680
Application.CutCopyMode = False
End Sub
You were declaring variables and never setting them equal to anything. I still did not see where oPS was ever used.
You received the ActiveX error because PowerPoint did not have an active presentation. It is always safer to work with your own objects rather than ActiveAnything within Office. So I set oPP equal to your new presentation and then used oPP rather than ActivePresentation
Also you never need to set things equal to nothing unless you're being picky about the order it happens. Everything declared in the Sub is set to nothing at the end of the sub.
Hope this helps!
Edit: Search and Replace
This is where I got the code, but I modified it to work as a callable Sub because I was calling it from different places many times:
'Find and Replace function
Sub FindAndReplace(sFind As String, sReplace As String, ByRef ppPres As PowerPoint.Presentation)
Dim osld As PowerPoint.Slide
Dim oshp As PowerPoint.Shape
Dim otemp As PowerPoint.TextRange
Dim otext As PowerPoint.TextRange
Dim Inewstart As Integer
For Each osld In ppPres.Slides
For Each oshp In osld.Shapes
If oshp.HasTextFrame Then
If oshp.TextFrame.HasText Then
Set otext = oshp.TextFrame.TextRange
Set otemp = otext.Replace(sFind, sReplace, , msoFalse, msoFalse)
Do While Not otemp Is Nothing
Inewstart = otemp.Start + otemp.Length
Set otemp = otext.Replace(sFind, sReplace, Inewstart, msoFalse, msoFalse)
Loop
End If
End If
Next oshp
Next osld
End Sub
You'll have to pass it the 2 strings and the Presentation object. It'll look like this in your Sub
FindAndReplace("FindMe","ReplaceWithThis", oPP)

type mismatch looping through shapes

I'm getting a type mismatch 13 error in the line that loops through the shapes in a slide. I can see that the oSh is Nothing, but if I .Count the shapes, there are plenty of shapes in the slide. How does this make sense?
Brief code:
Dim oPP As PowerPoint.Presentation
Dim oS As Slide
Dim oSh As Shape
For Each oS In oPP.Slides
For Each oSh In oS.Shapes '<-- this line is the error line
On Error Resume Next
If oSh.Type = 14 _
Or oSh.Type = 1 Then
'do stuff
End If
On Error GoTo 0
Next oSh
Next oS
Full code:
Sub PPLateBinding()
Dim pathString As String
'no reference required
Dim PowerPointApplication As PowerPoint.Application
Dim oPP As PowerPoint.Presentation
Dim oS As Slide
Dim oSh As Object
Dim pText As String
Dim cellDest As Integer
Dim arrBase() As Variant
Dim arrComp() As Variant
ReDim Preserve arrBase(1)
ReDim Preserve arrComp(1)
Dim fd As FileDialog
Dim FileChosen As Integer
Dim FileName As String
Dim iPresentations As Integer
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'use the standard title and filters, but change the
fd.InitialView = msoFileDialogViewList
'allow multiple file selection
fd.AllowMultiSelect = True
FileChosen = fd.Show
If FileChosen = -1 Then
'open each of the files chosen
For iPresentations = 1 To fd.SelectedItems.Count
'On Error Resume Next
Set PowerPointApplication = CreateObject("PowerPoint.Application")
Set oPP = PowerPointApplication.Presentations.Open(fd.SelectedItems(iPresentations))
If Err.Number <> 0 Then
Set oPP = Nothing
End If
If Not (oPP Is Nothing) Then
cellDest = 0
'We assume PP is already open and has an active presentation
For Each oS In oPP.Slides
'Debug.Print oPP.Slides.Count
If oS.Shapes.Count > 0 Then
Debug.Print oS.Shapes.Count
For Each oSh In oS.Shapes
Debug.Print "hey"
On Error Resume Next
If oSh.Type = 14 Or oSh.Type = 1 Then
pText = oSh.TextFrame.TextRange.Text
ReDim Preserve arrBase(UBound(arrBase) + 1)
arrBase(UBound(arrBase)) = pText
'Debug.Print pText
ElseIf (oSh.HasTable) Then
Dim i As Integer
For i = 2 To oSh.Table.Rows.Count
ReDim Preserve arrComp(UBound(arrComp) + 1)
arrComp(UBound(arrComp)) = Replace(oSh.Table.Cell(i, 1).Shape.TextFrame.TextRange.Text, vbLf, "") & ":::" & oSh.Table.Cell(i, 3).Shape.TextFrame.TextRange.Text
Next i
End If
On Error GoTo 0
Next oSh
'x = InputData(arrBase, arrComp)
End If
Next oS
'Debug.Print tbl.Shape.TextFrame.TextRange.Text '.Cell(1, 1).Shape.TextRange.Text
oPP.Close
PowerPointApplication.Quit
Set oPP = Nothing
Set PowerPointApplication = Nothing
End If
Next iPresentations
End If
End Sub
Excel has its own Shape type (which is not the same as PowerPoint.Shape type), so you should change
Dim oSh As Shape
to (for earlier binding)
Dim oSh As PowerPoint.Shape
or (for late binding)
Dim oSh As Object
Also note, if you're going to use powerpoint with late binding (as suggests your function name Sub PPLateBinding()), you should change all types PowerPoint.Something to Object (unless you add reference to powerpoint object model, but in this case I don't see any reason for using late binding).