清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
Sub PowerPointBasics_1()
' PowerPoint 的对象模型 Ojbect Model (OM)模型导航
' 每个东东在 PowerPoint 中都是某个类型的对象
' 想操作好 PowerPoint,你就要和对象打交道 有些对象是另外一些对象的集合。
' 对象具有属性 – 用来描述对象的东东
' 对象具有方法 – 对象可以做或你可以对他做什么
' 对象模型就是所有 PowerPoint 对象自成一个体系的集合
' 就像一个倒置的树图
' 按 F2 浏览查看对象
' 数的最顶层是应用对象(Application)
' 就是 PowerPoint 本身
' 应用对象有他的属性
Debug.Print Application.Name
' 用 Debug.Print 代替 MsgBox 能节省一点时间
' 我们就不需要点击对话框的“确定”按钮
' Debug.Print 的结果输出在 VB 编辑器环境中的立即窗口中
' 如果它没有显示,通过点击菜单“视图”/“立即窗口”或者按 Ctrl+G 来显示
' .Presentations 属性返回当前打开演示文档的一个集合
' 我们通过“点”提示来调用它的功能
Debug.Print Application.Presentations.Count
' 我们可以指定一个特定的对象
Debug.Print Application.Presentations(1).Name
' 所以说 PowerPoint (即 application 对象) 包含 Presentations 对象
' Presentations 包含 Slides 对象
' Slides 包含 Shapes 对象,如 rectangles 和 circles。
' 所以我们可以自然的这样写:
Debug.Print Application.ActivePresentation.Slides(2).Shapes.Count
' 但是这么长的引用有些令人乏味
' 另一种形式对我们来说更容易一些同时也会让 PowerPoint 处理的更快一些
' 使用 With 关键字来引用你用的对象..
With ActivePresentation.Slides(2).Shapes(2)
' 这样你可以直接引用他的下级功能
Debug.Print .Name
Debug.Print .Height
Debug.Print .Width
' 最后用 End With 关键字来表明引用完毕
End With
' 我们也可以嵌套着使用
With ActivePresentation.Slides(2).Shapes(2)
Debug.Print .Name
With .TextFrame.TextRange
Debug.Print .Text
Debug.Print .Font.Name
End With
End With
End Sub
Sub PowerPointBasics_2()
' 控制当前选中的对象
' 显示对象的名字
With ActiveWindow.Selection.ShapeRange(1)
Debug.Print .Name
End With
' 更改名字并移动他:
With ActiveWindow.Selection.ShapeRange(1)
' 命名对象非常有用
.Name = "My favorite shape"
.Left = .Left + 72 ' 72 像素即 1 英寸
End With
End Sub
Sub PowerPointBasics_3()
' 控制一个已命名的对象
' 如果你知道一个对象的名字
' 你就可以直接控制他
' 不需要繁琐的调用了。
With ActivePresentation.Slides(2).Shapes("My favorite shape")
.Top = .Top - 72
End With
' 每页幻灯片也可以有名字
With ActivePresentation.Slides(2)
.Name = "My favorite slide"
End With
' 无论我们移动他到那个地方,名字不变
' 这样我们就可以方便的操作啦
With ActivePresentation.Slides("My favorite slide").Shapes("My favorite shape")
.Height = .Height * 2
End With
End Sub
Sub PowerPointBasics_4()
' 对象的引用
' 可以通过变量来保持对对象的引用
' 可能会有些难于理解,不过不用担心
' 参照实例很容易理解的。
' 先看下面的例子:
' 定义一个变量为某个类型
Dim oShape As Shape
' 让他指向某个特定的对象
Set oShape = ActivePresentation.Slides("My favorite slide").Shapes("My favorite shape")
' 注意我们使用已命名的对象。
' 从现在开始,我们就可以把 oShape 认作为我们命名的那个对象。
Debug.Print oShape.TextFrame.TextRange.Text
oShape.TextFrame.TextRange.Font.Color.RGB = RGB(255, 0, 0)
' 直到我们删除这个变量,都可以认为他就是我们命名的那个对象。
Set oShape = Nothing
End Sub
Sub PowerPointBasics_5()
' 遍历所有的幻灯片
' 便利所有的对象
' So far, we haven't done anything you couldn't do
' with your mouse, and do it more easily at that.
' One more little lesson, then the real fun starts.
Dim x As Long ' we'll use X as a counter
' OK, I said always to give variables meaningful names
' But for little "throwaway" jobs like this, programmers often
' use x, y, and the like
' Let's do something with every slide in the presentation
For x = 1 To ActivePresentation.Slides.Count
Debug.Print ActivePresentation.Slides(x).Name
Next x
' Or with every shape on one of the slides
' Since x is a "junk" variable, we'll just re-use it here
' And we'll use the With syntax to save some typing
With ActivePresentation.Slides(3)
For x = 1 To .Shapes.Count
Debug.Print .Shapes(x).Name
Next x
End With ' ActivePresentation.Slides(3)
End Sub
Sub PowerPointBasics_6()
' 处理异常错误
' You can trust computer users to do one thing and one thing only:
' The Unexpected
' You can trust computers to do pretty much the same
' That's where error handling comes in
' What do you think will happen when I run this code?
With ActivePresentation.Slides(42)
MsgBox ("Steve, you moron, there IS no slide 42!")
End With
End Sub
Sub PowerPointBasics_6a()
' Error Handling Continued
' Let's protect our code against boneheaded Steves
' If he does something that provokes an error, deal with it gracefully
On Error GoTo ErrorHandler
With ActivePresentation.Slides(42)
MsgBox ("Steve, you moron, there IS no slide 42!")
End With
' Words with a : at the end are "labels"
' and can be the destination of a "GoTo" command
' Using GoTo is considered Very Bad Form except in error handlers
' If we got here without error we need to quit before we hit the error
' handling code so ...
NormalExit:
Exit Sub
ErrorHandler:
MsgBox ("Error: " & Err.Number & vbCrLf & Err.Description)
' resume next
' exit sub
Resume NormalExit
End Sub
Option Explicit
Public strText As String
Public strOption As String
Sub Forms_1()
' Creating/Showing/Unloading a form
' Forms are a more sophisticated way of getting user input than
' simple InputBox commands
' For example:
frmMyForm1.Show
' now the user has dismissed the form
' let's see what they entered
Debug.Print frmMyForm1.TextBox1.Text
If frmMyForm1.OptionButton1.Value = True Then
Debug.Print "Yes"
End If
If frmMyForm1.OptionButton2.Value = True Then
Debug.Print "Chocolate"
End If
If frmMyForm1.OptionButton3.Value = True Then
Debug.Print "Teal"
End If
' we're done with the form so unload it
Unload frmMyForm1
' But what if we want to make the form data available until much later?
' And wouldn't it make more sense to keep all the form's logic
' in the form itself?
End Sub
Sub Forms_2()
' This uses a form with the logic built in
' Note that we had to declare a few PUBLIC variables
' so the form could get at them
frmMyForm2.Show
' we're done with the form so unload it
Unload frmMyForm2
' let's see what they entered - our variables still have the values
' the form code assigned them:
Debug.Print strText
Debug.Print strOption
' CODE RE-USE
' We can export the form to a file and import it into other projects
End Sub
This is the code from the Animation Tricks section of the seminar (modAnimationTricks)
Option Explicit
' This tells VBA how to call on the Windows API Sleep function
' This function puts our VBA code to sleep for X milliseconds
' (thousandths of a second) then lets it wake up after that
' Unlike other ways of killing time, this doesn't hog computer cycles
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub xYouClicked(oSh As Shape)
Dim oShThought As Shape
Set oShThought = oSh.Parent.Shapes("Thought")
' Make the thought balloon visible
oShThought.Visible = True
' Move it to just to the right of the clicked shape
oShThought.Left = oSh.Left + oSh.Width
' Position it vertically just above the clicked shape
oShThought.Top = oSh.Top - oShThought.Height
Select Case UCase(oSh.Name)
Case Is = "EENIE"
oShThought.TextFrame.TextRange.Text = "Pest!"
Case Is = "MEENIE"
oShThought.TextFrame.TextRange.Text = "This is annoying!"
Case Is = "MINIE"
oShThought.TextFrame.TextRange.Text = "This is REALLY annoying!!"
Case Is = "MOE"
oShThought.Visible = False
oSh.Parent.Shapes("STOP").Visible = True
End Select
End Sub
Sub yYouClicked(oSh As Shape)
' This time we'll use tags to make it easier to maintain
Dim oShThought As Shape
Set oShThought = oSh.Parent.Shapes("Thought")
' Make the thought balloon visible and move it next to the
' shape the user just clicked
oShThought.Visible = True
oShThought.Left = oSh.Left + oSh.Width
oShThought.Top = oSh.Top - oShThought.Height
' Use tags to pick up the text
oShThought.TextFrame.TextRange.Text = oSh.Tags("Thought")
End Sub
Sub AddATag()
' A little macro to add a tag to the selected shape
Dim strTag As String
' Our old buddy InputBox gets the tag text ...
strTag = InputBox("Type the text for the thought balloon", "What is the shape thinking?")
' Instead of forcing user to enter something, we'll just quit
' if not
If strTag = "" Then
Exit Sub
End If
' Must have entered something, so tag the shape with it
With ActiveWindow.Selection.ShapeRange(1)
.Tags.Add "Thought", strTag
End With
End Sub
Sub YouClicked(oSh As Shape)
' And now we'll add a WinAPI Sleep call to make it even smoother
Dim oShThought As Shape
Set oShThought = oSh.Parent.Shapes("Thought")
' Use tags to pick up the text
oShThought.TextFrame.TextRange.Text = oSh.Tags("Thought")
' Make the thought balloon visible and move it next to the
' shape the user just clicked
oShThought.Left = oSh.Left + oSh.Width
oShThought.Top = oSh.Top - oShThought.Height
oShThought.Visible = True
' give the system a little time to redraw
DoEvents
' Now wait a second (1000 milliseconds to be precise) ...
Sleep 1000
' and make it invisible again
oShThought.Visible = False
End Sub
Sub Reset()
' Re-bait our little trap so it's ready for the next
' unwary user
ActivePresentation.Slides("AnimationTricks").Shapes("STOP").Visible = False
ActivePresentation.Slides("AnimationTricks").Shapes("Thought").Visible = False
End Sub
This is the code from the Mass Quantities section of the seminar (modMassQuantities) that deals
with automating actions across many slides or many presentations.
Option Explicit
Sub GreenToRed()
' Object variables for Slides and Shapes
Dim oSh As Shape
Dim oSl As Slide
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
If oSh.Fill.ForeColor.RGB = RGB(0, 255, 0) Then
oSh.Fill.ForeColor.RGB = RGB(255, 0, 0)
End If
Next oSh
Next oSl
End Sub
Sub FolderFull()
' For each presentation in a folder that matches our specifications
' - open the file
' - call another subroutine that does something to it
' - save the file
' - close the file
Dim strCurrentFile As String ' variable to hold a single file name
Dim strFileSpec As String ' variable to hold our file spec
' give it a value that works for my computer:
strFileSpec
=
"C:\Documents
and
Settings\Stephen
Rindsberg\Desktop\PPTLive\Automation\LotsOfFiles\*.ppt"
' get the first file that matches our specification
strCurrentFile = Dir$(strFileSpec)
' don't do anything if we didn't find any matching files
' but if we did, keep processing files until we don't find any more
While Len(strCurrentFile) > 0
' open the presentation
Presentations.Open (strCurrentFile)
' by changing this next line to call a different subroutine
' you can have this same code do other tasks
Debug.Print ActivePresentation.Name
' call the Green to Red macro to process the file
Call GreenToRed
' save the file under a new name with FIXED_ at the beginning
ActivePresentation.SaveAs (ActivePresentation.Path & "\" _
& "Fixed_" _
& ActivePresentation.Name)
' close it
ActivePresentation.Close
' and get the next file that matches our specification
' if you don't supply a new file spec, Dir$ returns the next
' file that matches the previously supplied specification
strCurrentFile = Dir$
Wend
' Note: Don't use Dir in code that's called from within a loop
' that uses Dir - only one "Dir" can be "active" at a time.
' In production code, it's best to keep it in a very short loop or
' to collect file names in a short loop then process them after
' Arrays are useful for this
End Sub
Misc. Example code from the seminar (modMiscExamples)
Option Explicit
Sub FolderFullFromArray()
' Uses array to collect filenames for processing
' This is more reliable than processing the files within a loop
' that includes DIR
Dim rayFileNames() As String
Dim strCurrentFile As String ' variable to hold a single file name
Dim strFileSpec As String ' variable to hold our file spec
' give it a value that works for my computer:
strFileSpec
=
"C:\Documents
and
Settings\Stephen
Rindsberg\Desktop\PPTLive\Automation\LotsOfFiles\*.ppt"
' Redimension the array to 1 element
ReDim rayFileNames(1 To 1) As String
' get the first file that matches our specification
strCurrentFile = Dir$(strFileSpec)
' don't do anything if we didn't find any matching files
' but if we did, keep processing files until we don't find any more
While Len(strCurrentFile) > 0
' Add it to the array
rayFileNames(UBound(rayFileNames)) = strCurrentFile
strCurrentFile = Dir
' redimension the array
ReDim Preserve rayFileNames(1 To UBound(rayFileNames) + 1) As String
Wend
' If there were no files, the array has one element
' If it has more than one element, the last element is blank
If UBound(rayFileNames) > 1 Then
' lop off the last, empty element
ReDim Preserve rayFileNames(1 To UBound(rayFileNames) - 1) As String
Else
' no files found
Exit Sub
End If
' If we got this far, we have files to process in the array so
Dim x As Long
For x = 1 To UBound(rayFileNames)
' open the presentation
Presentations.Open (rayFileNames(x))
Debug.Print ActivePresentation.Name
' call the Green to Red macro to process the file
Call GreenToRed
' save the file under a new name with FIXED_ at the beginning
ActivePresentation.SaveAs (ActivePresentation.Path & "\" _
& "Fixed_" _
& ActivePresentation.Name)
' close it
ActivePresentation.Close
Next x
End Sub
This is the code from the Macro Recorder demonstration
The Macro Recorder is handy for little quickie macros and especially for learning how
PowerPoint's object model works, but it doesn't produce code that's very useful as is.
This demonstrates how you can make the recorder produce more useful code and how you can
take what you've learned from it and tweak it into something more generally useful.
Suppose the corporate colors have just changed from green to red. You've got dozens or hundreds
of presentations with the fills set to the old green and need to change them all. Fast.
You open one in PPT and record a macro while you select a shape and change its color from green
to red.
Here's what you end up with:
Sub Macro1()
ActiveWindow.Selection.SlideRange.Shapes("Rectangle 5").Select
With ActiveWindow.Selection.ShapeRange
.Fill.Visible = msoTrue
.Fill.ForeColor.RGB = RGB(255, 0, 102)
.Fill.Solid
End With
ActivePresentation.ExtraColors.Add RGB(Red:=255, Green:=0, Blue:=102)
End Sub
This has a few problems:
It only works IF there's a shape named "Rectangle 5" on the current slide
It will only change a shape by that name, no other
It changes things we may not WANT changed (.Fill.Solid, .Fill.Visible)
It adds extra colors to the PPT palette (.ExtraColors)
In short, it solves the problem of changing ONE shape on ONE slide from green to red. And that's
it. And it creates other potential problems in the process.
But it did show us how to change a shape's color in PowerPoint VBA, so it's not totally useless.
Let's see if we can get it to do something more general.
Select the green rectangle first, THEN record a macro while changing it to red:
Sub Macro2()
With ActiveWindow.Selection.ShapeRange
.Fill.ForeColor.RGB = RGB(255, 0, 102)
.Fill.Visible = msoTrue
.Fill.Solid
End With
End Sub
That's better. A lot better. It works on any selected shape and in fact it works on multiple selected
shapes.
It still sets a few extra properties but we can comment those out.
Now you can select all the shapes on each slide, run this macro and ...
No. Don't do that. It'll change all the green selected shapes to red, true. Also all the blue ones and
purple ones and so on. ALL the selected shapes.
So you still have to go from slide to slide selecting all (and ONLY) the green shapes, then running
the macro again and again.
Enough of this. Here's how you and the other VBA Pros really do this kind of stuff:
Sub GreenToRed()
Dim oSh As Shape
Dim oSl As Slide
' Look at each slide in the current presentation:
For Each oSl In ActivePresentation.Slides
' Look at each shape on each slide:
For Each oSh In oSl.Shapes
' IF the shape's .Fill.ForeColor.RGB = pure green:
If oSh.Fill.ForeColor.RGB = RGB(0, 255, 0) Then
' Change it to red
oSh.Fill.ForeColor.RGB = RGB(255, 0, 0)
End If
Next oSh
Next oSl
End Sub
In less time than it takes you to get your finger off the mouse button, that will change thousands of
shapes on hundreds of slides from green to red. And it only touches the shapes that are the exact
shade of green we've targeted, no other colors.
Is it safe to touch the text?
Not all shapes can have text. If you try to access a text property of one of these, PowerPoint errors
out.
In addition, some shapes created by PowerPoint 97 can be corrupted to the point where, though
they have the ability to hold text, they cause errors if you try to check for the text.
This is kind of a safety check function. It tests the various things that might cause errors and
returns True if none of them actually cause errors.
Public Function IsSafeToTouchText(pShape As Shape) As Boolean
On Error GoTo Errorhandler
If pShape.HasTextFrame Then
If pShape.TextFrame.HasText Then
' Errors here if it's a bogus shape:
If Len(pShape.TextFrame.TextRange.text) > 0 Then
' it's safe to touch it
IsSafeToTouchText = True
Exit Function
End If ' Length > 0
End If ' HasText
End If ' HasTextFrame
Normal_Exit:
IsSafeToTouchText = False
Exit Function
Errorhandler:
IsSafeToTouchText = False
Exit Function
End Function
What's the path to the PPA (add-in) file?
If your add-in requires additional files, you'll probably keep them in the same folder as the add-in
itself.
Ah, but where's that? A user might install an add-in from anywhere on the local hard drive or even
from a network drive, so you can't be certain where the add-in and its associated files are. At least
not without this:
Public Function PPAPath(AddinName as String) As String
' Returns the path to the named add-in if found, null if not
' Dependencies: SlashTerminate (listed below, explained later)
Dim x As Integer
PPAPath = ""
For x = 1 To Application.AddIns.count
If UCase(Application.AddIns(x).Name) = UCase(AddinName) Then
' we found it, so
PPAPath = Application.AddIns(x).path & GetPathSeparator
' no need to check any other addins
Exit Function
End If
Next x
' So we can run it from a PPT in the IDE instead of a PPA:
If PPAPath = "" Then
PPAPath = SlashTerminate(ActivePresentation.path)
End If
End Function
Function SlashTerminate(sPath as String) as String
' Returns a string terminated with a path separator character
' Works on PC or Mac
Dim PathSep As String
#If Mac Then
PathSep = ":"
#Else
PathSep = "\"
#End If
' Is the rightmost character a backslash?
If Right$(sPath,1) <> PathSep Then
' No; add a backslash
SlashTerminate = sPath & PathSep
Else
SlashTerminate = sPath
End If
End Function