Reputation: 29155
I'm trying to see if there is a way to programmatically access multiple text selections in shapes/textboxes in PowerPoint.
The scenario is this - create a textbox that has the words "one two three" inside. Now, with the Ctrl button held down, select the words "one" and "three" (but not "two").
The ActiveWindow.Selection.TextRange
and ActiveWindow.Selection.TextRange2
objects only provide a single selection. I was hoping it would provide both selections, like in a series of Runs
, Paragraphs
or whatnot. The ActiveWindow.Selection.ShapeRange
object doesn't provide anything on this well - it's still a single shape.
In the PPT client, when you have multiple (disconnected) text selections, you can perform the same actions on them, like setting the font color to red. I'm looking for the same access, but programmatically - VBA, C#/VB.NET, VSTO, - any of those technologies are fine if you have a way to do this.
Upvotes: 4
Views: 695
Reputation: 371
It's a pity that ActiveWindow.Selection.TextRange only returns the last selected textrange. I found that ActiveWindow.Selection.Cut or .Copy manage to process all the selected textrange.
So, if any part of the text content is not duplicated, we can find all the selected textrange by searching for the copied text:
Sub test1()
Dim shp As Shape
Dim tr As TextRange2
Dim i As Integer
Dim lines() As String
If ActiveWindow.Selection.Type <> ppSelectionText Then Exit Sub
ActiveWindow.Selection.Copy
'get copied text from Clipboard
With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
.GetFromClipboard
lines() = Split(.GetText, vbNewLine)
End With
Set shp = ActiveWindow.Selection.ShapeRange(1)
For i = LBound(lines) To UBound(lines)
Set tr = shp.TextFrame2.TextRange.Find(lines(i))
If Not tr Is Nothing Then
'Here, do whatever you want to do with the textrange
tr.Font.Fill.ForeColor.RGB = rgbYellow
Debug.Print tr.Text, tr.Start, tr.Length
End If
Next
End Sub
But this 'searching' method fails to find the exact textrange when the text is like "Blah Blah Blah...."
Anothor method is to make a copy of the original shape and to compare the two textareas:
Sub test2()
Dim shp As Shape, dup As Shape
Dim tr As TextRange2, trDup As TextRange2
Dim p As Long, k As Long
Dim lines() As String
If ActiveWindow.Selection.Type <> ppSelectionText Then _
MsgBox "Select some multiple textrange first": Exit Sub
'duplicate the current shape
Set shp = ActiveWindow.Selection.ShapeRange(1)
Set dup = shp.Duplicate(1)
Set trDup = dup.TextFrame2.TextRange
'cut selection to Clipboard
ActiveWindow.Selection.Cut
Set tr = shp.TextFrame2.TextRange
'get cut text from Clipboard
With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
.GetFromClipboard
lines() = Split(.GetText, vbNewLine)
End With
'compare the original textrange with the copied text
For k = LBound(lines) To UBound(lines)
p = 1
Do While p <= trDup.Characters.Count
If trDup.Characters(p) <> tr.Characters(p) Then
DoEvents
trDup.Characters(p, Len(lines(k))).Copy
DoEvents
tr.Characters(p).InsertAfter " "
tr.Characters(p).Paste
DoEvents
With tr.Characters(p, Len(lines(k)))
'Here, do whatever you want to do with the textrange
.Font.Fill.ForeColor.RGB = rgbYellow
.Font.Bold = msoTrue
End With
Exit Do
End If
p = p + 1
Loop
Next k
'delete the tempoary shape
dup.Delete
End Sub
This 'Duplicating and Comparing' method succeeds to get all the multiple textareas even when some part of the text content is duplicated several times.
Notice:
I hope these work-arounds might help someone frustrated.
Upvotes: 0
Reputation: 586
You cannot do it because of lack of support in the object model. Take a look at this kb article - https://social.msdn.microsoft.com/Forums/office/en-US/98c90979-fff7-4d0f-9499-6e6e730d9ea4/disjoint-selection-of-text?forum=worddev. Though it pertains to Word, the limitations are similarly applicable to PowerPoint.
Upvotes: 3