Text isn't limited to text boxes. You can click most shapes in Microsoft PowerPoint and start typing text. This is because most (though not all) shapes have a text frame. To work with text in shapes programmatically, you start with the text frame. Here is a simple macro:
Sub AddSomeText() ' work with the currently selected shape With ActiveWindow.Selection.ShapeRange ' the shape's "text container" is the TextFrame With .TextFrame ' unless you specify otherwise, .TextRange refers to ' all of the text in the text frame With .TextRange ' add some text .Text = "You can add text to shapes" End With End With End With ' or somewhat more compactly With ActiveWindow.Selection.ShapeRange TextFrame.TextRange.Text = "This works too" End With End Sub
Most of the example macros here start with ActiveWindow.Selection.ShapeRange, which you can't replicate in AppleScript. This situation will likely surface often. In Microsoft Office 2004, you paste the
GetSelectedShape()
handler at the bottom of every script that needs it. The handler does not appear every time it is needed in this topic, but it is almost always called, so you always need it.
tell application "Microsoft PowerPoint" --get the selected shape via the handler set selectedShape to my GetSelectedShape() --paste it in below! tell selectedShape tell its text frame --needs 'its'! tell its text range --needs 'its' --unless noted, refers to all --the text in the text frame set content to "You can add text to shapes." end tell end tell end tell --or, more compactly set content of text range of text frame of selectedShape to ¬ "This works too!" end tell
The first time through, leave out the final line if you want to see the first text change — it is replaced by the second one so quickly that you won't spot it. Note that using nested
tell
blocks, which correspond to
With
blocks in Visual Basic for Applications (VBA), is useful if there are going to be more commands directed at any of the intermediate targets. Otherwise, for a single command like this one, it's simpler to use the more compact
of
version. You can use any combination of
tell
and
of
you like. It needn't be all or nothing.
This is a very useful example because it contains two properties — text frame and text range — that are the same term (keywords) both for the property of their containing object and for the class. As a result, you absolutely have to use
its
in
tell
blocks and in
whose
(where
its) clauses. You will notice that with two of them here, if you omit the first
its
for
text frame, the script won't even compile for
text range.
Ensure that a shape supports text frames
Some shapes cannot have text frames (namely lines, arrows, and connectors). In other cases, a shape that has a text frame might still cause the macro to throw errors when you try to access the text frame or its text. Conditional coding and error trapping solve this problem.
Sub TextCaveats()
With ActiveWindow.Selection.ShapeRange
On Error Resume Next
' does it have a text frame?
If .HasTextFrame Then
' does the text frame have any text?
' see if there's any there
' before trying to alter it
If .TextFrame.HasText Then
.TextFrame.TextRange.Text = "And here you are, safely"
End If
End If
End With
End Sub
becomes:
tell application "Microsoft PowerPoint" --get the selected shape via the handler set selectedShape to my GetSelectedShape() --paste it in below! try --to avoid error messages if shape --has no text frame or no text tell selectedShape if has text frame then --does it have one? --if so, does the text frame --have any text? if has text of its text frame then --needs 'its' set content of text range ¬ of its text frame to ¬ "And here you are safely." end if end if end tell end try end tell
For production work, after the GetSelectedShape handler, you put all the lines into an
IsSafeToTouch(selectedShape)
handler, sending it the
selectedShape
and returning a boolean true, or false under other conditions, or
on error, before setting the text in the main script. There are many different places and contexts where you can call this handler before setting text.
tell application "Microsoft PowerPoint" --get the selected shape via the handler set selectedShape to my GetSelectedShape() --paste it in below! set check to my IsSafeToTouch(selectedShape) if check then set content of text range of selectedShape's text frame to ¬ "Different text depending on context." end if end tell on IsSafeToTouch(selectedShape) tell application "Microsoft PowerPoint" try --to avoid error messages if shape has no --text frame or no text tell selectedShape if has text frame then --does it have one? --if so, does the text frame --have any text? if has text of its text frame then --needs 'its' return true else return false end if else return false end if end tell on error return false end try end tell end IsSafeToTouch


