You can change every shape on a slide, and change every slide in a presentation.
Here is a macro that sets the background color of every slide in a presentation to a pale aquamarine. (You can find this by clicking Slide Color Scheme on the Format menu. It is the background color of the first color scheme of the second row.) It then moves each shape on each slide half an inch to the right, looping through each slide in the presentation and each shape on each slide.
Dim oPres As Presentation Dim oSl As Slide Dim oSh As Shape Dim colSch As ColorScheme ' Get a reference to the current active presentation Set oPres = ActivePresentation ' Do something with each slide in the presentation For Each oSl In oPres.Slides ' Set the background color scheme of each slide to a pale aquamarine Set colSch = oSl.ColorScheme colSch.Colors(ppBackground).RGB = RGB(222, 246, 241) ' and do something with each shape on each slide For Each oSh In oSl.Shapes ' move it 36 points (.5 inch) to the right oSh.Left = oSh.Left + 36 Next Next
Here's the AppleScript version of the same thing:
tell application "Microsoft PowerPoint"
set oPres to active presentation
repeat with oSl in (get every slide of oPres)
set color for (color scheme of oSl) at background scheme ¬
to color {222, 246, 241}
repeat with oSh in (get every shape of oSl)
tell oSh
set left position to (get left position) + 36
end tell
end repeat
end repeat
end tellYou skip the
Dim
declarations and move on, using the same variables as the VBA version for clarity. However, there is no need in AppleScript to use initial characters of variables such as
o
,
s, and
l
to remind yourself to use the correct types for object, string, and long, for example, since it makes no difference in AppleScript. Writing scripts that will be read some months or years later using explanatory terms such as
theSlide
and
theShape
helps make the script self-commenting without needing a lot of extra comments, and it's much easier to follow.
This macro translates easily to AppleScript. The color scheme class is unusual in that it has no properties whatsoever (such as background scheme color, fill scheme color, and so on) for you to get and set in a standard way. Instead , you have to use the proprietary get color for and set color for commands whose at parameter accesses an identical enumeration of constants. (This is likely a result of inheriting the structure from VBA, where ColorScheme.Colors is a method rather than a property, with enumerated
pp
constants as arguments.) Here you use the background scheme constant.
The values for the color need some comment. In VBA, the RGBColor object is a Long made from an RGB property of an array of three, 0–255 based integers, being an 8-bit, Red-Green-Blue composite. In Microsoft Office
AppleScript (meaning Word, Excel, and PowerPoint
only here), any property or class whose type is denoted as color wants the same three, 0–255 based integers as a list, in list braces:
{222, 246, 241}. This is a sort of "Microsoft color class." It is very convenient when converting VBA macros to AppleScript, because you use the same three numbers for the RGB.
However, the true Apple-defined RGB color class in AppleScript is a 16-bit RGB list of three, 0–65535 integers. If you ever want to transfer a color from Word, Excel, or PowerPoint to another Macintosh application, including Microsoft Entourage (whose categories have a color property), you would get a completely different color if you used the same three numbers. The way to do it is to square each integer, as shown in the following subroutine:
ApplifyMSColor({222, 246, 241})
--> {49284, 60516, 58081}
to ApplifyMSColor({r, g, b})
set r to (r ^ 2) as integer
set g to (g ^ 2) as integer
set b to (b ^ 2) as integer
return {r, g, b}
end ApplifyMSColorIt needs
as integer
because AppleScript's exponentiation operator,
^, produces reals (floating point numbers) that look like 4.9284E+4 when 10000.0 or greater, but these values (all of them 65535 or less) will coerce to integer, which is what the color type requires. In the reverse direction, going from Entourage
to PowerPoint, you would get the square root of each 65535-based integer and round down to the nearest integer, which is easily done with the integer division operator
div, as follows:
set r to (49285 ^ 0.5) div 1 -->222
The coercion
as
integer
also works as of Mac OS X v10.4 (Tiger), but not before. If the 65535-based number is not a perfect square, its square root will be a real with a non-zero fractional part: 499285 ^ 0.5 results in 222.002252240828, for example. Before Mac OS X v10.4, trying to coerce that sort of real as integer
would cause an error, so
div 1
is the way to do it, and it works in all versions of Mac OS X.
Moving the shapes is straightforward, as the left position property of shape corresponds exactly to the Left Property in VBA. Note that when getting a property (left position) within a compound statement that will then do something with it in the same line, as opposed to setting a variable to it in a previous line, you must use the explicit get.
set left position to (get left position) + 36
You must also use the explicit get command when using the
repeat
loop form of
repeat with someVariable in someList
and you want to use (every element of someObject) as the list instead of setting a variable (someList) to that first.
The explicit get command is used here because many VBA programmers want to use parallel forms of the same expressions that you use in VBA. However, it is better practice to set variables first to ensure that you have evaluated the expressions before you try to operate on them. It is very easy to forget about that explicit get command and then wonder why the script keeps erroring:
can't get [whatever].
Note that if you want to set the left position of every shape on the slide to the same value (that is, not relative to its old position, which will be different for each shape), you can avoid the
repeat
loop entirely in AppleScript and do it all at one time.
set left position of every shape of oSl to 100
This is very helpful if you have perhaps 50 shapes on the slide — no looping. Using the
every element
syntax does not always work (as it has to be specifically implemented for an object), but it does here. It can't be done for setting the background of the color scheme because you were not setting a property but calling the proprietary command set color for.


