今天我们就来虚拟一张“IT之家电视台”的测试图。用到的软件,PowerPoint就够了。
1、先从网上找到空白(即不含台标、报时等信息)的测试图大图,并将其设置为幻灯片的背景,再在合适的位置上加上台标、电视台信息、主报时和右上角角标报时,并应用上美观的格式。做完以后,就像下图。
这就完成了吗?当然不是,那就没必要写一篇文章了。现在的幻灯片还是静态的,我们可要让它动起来,让报时器变成名副其实的报时器。于是VBA就登场了。
2、启动VBA编辑器(该编辑器的入口在“开发工具”选项卡下。该选项卡默认隐藏,可以在功能区设置中取消隐藏),从“插入”菜单中新建一个标准模块。
新建一个过程,名为Tick,并填充如下代码。
Sub Tick()
With ActivePresentation.Slides(1)
.Shapes(3).TextFrame.TextRange = Format(Date, "yyyy-MM-dd")
.Shapes(4).TextFrame.TextRange = Format(Time, "hh:mm:ss")
.Shapes(5).TextFrame.TextRange = Format(Time, "hh:mm:ss")
End With
End Sub
代码说明:文本框和形状等本质上是属于shape类型的,在一张幻灯片上添加的shape可以通过其下的shapes集合来访问。在本例中,shapes(3)表示主报时的日期部分,shapes(4)表示主报时的时间部分,shapes(5)则表示右上角的角标报时。所以上述代码的作用是刷新一次报时器。
3、刷新报时器的代码是写完了,但是无论你进行什么操作,这段代码都不会运行,因为没有触发条件。而我们希望在启动幻灯片放映后,执行该代码。于是便引入了一个能够自动运动的宏OnSlideShowPageChange。如若把过程命名为该名称,则它所包含的代码会在放映时幻灯片切换时被执行——其实并不是启动时执行,但是因为现在只有一张幻灯片,所以可以大致等效。于是就有了这样的代码:
Sub OnSlideShowPageChange()
Call Tick()
End Sub
然后启动幻灯片放映,发现时间确实被刷新了!但是,好像哪里不对劲。时间刷新了一次后,它就不走了。于是我们应该来个定时器之类的控件,让Tick过程能每秒执行一次。然而,VBA并不像VB6.0一样提供定时器控件。
4、这并不意味着我们就束手无策了。既然没有定时器控件,那就不用控件来实现呗。我们仍可以通过Windows API来实现定时器的功能,先声明API函数:
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
代码说明:SetTimer和KillTimer是相反的,前者是设置计时器(开始计时),后者是取消计时器(停止计时)。它们的参数中,hwnd是窗口的句柄(类似于ID),nIDEvent是计时器的ID,uElapse是计时间隔(以毫秒为单位),lpTimerFunc是要让计时器执行的函数或者过程。而因为参数中还要求句柄,那么需要再来一个函数来获取活动窗体的句柄。
Public Declare Function GetActiveWindow Lib "user32" () As Long
5、接着,我们把OnSlideShowPageChange过程中的代码修改如下:
Sub OnSlideShowPageChange()
SetTimer GetActiveWindow, 101, 1000, AddressOf Tick
End Sub
再次启动幻灯片放映,我们发现时间真的一秒一下地走起来了!(文末会上效果图)但是注意到角标报时一直悬挂在右上角,而通常电视台只会在半点和整点时显示角标报时。有什么办法可以做到这点呢?当然有!
6、新建一个判断是否为半点或整点的函数ifHalfHour:
Function ifHalfHour()
Dim TimeValue As Double
TimeValue = CDbl(Time) * 86400
If TimeValue Mod 1800 >= 1770 Or TimeValue Mod 1800 <= 30 Then
ifHalfHour = True
End If
End Function
代码说明:time是date类型,转成double表示的当前时间占全天的比值。比如12:00:00正好时一天的正中,因此表示12:00:00的date转换为double后正好是0.5。那么可以再乘上一天的总秒数86400秒,来表示是一天中的第几秒,再根据除以1800秒(半个小时是1800秒)所得的余数,即可判断是否到半点或整点了。余数1770表示XX:29:30或XX:59:30,余数30表示XX:30:30或XX:00:30。
7、接着我们把表示角标报时的shapes(5)的visible(是否可见)属性与该函数的返回值绑定在一起。在Tick过程的With块中,新增一行:
.Shapes(5).Visible = ifHalfHour
这样任务就基本完成了。另外,我们还希望能在退出幻灯片放映后能够停止计时,能重置报时器等,于是就引入了OnSlideShowTerminate(在放映结束时自动运行)和Reset(尚未定义触发条件)过程:
Sub OnSlideShowTerminate()
KillTimer GetActiveWindow, 101
End Sub
Sub Reset()
With ActivePresentation.Slides(1)
.Shapes(3).TextFrame.TextRange = "0000-00-00"
.Shapes(4).TextFrame.TextRange = "00:00:00"
.Shapes(5).TextFrame.TextRange = "00:00:00"
.Shapes(5).Visible = True
End With
End Sub
现在奉上半点报时时的效果动图,报时长达1分钟(动图效果:点此观看)。
更多设想:为了丰富测试图的内容,大家还可以加入背景音乐;当然也可以把“IT之家电视台”再办下去,让它开播等等。
最后给出做好的PowerPoint文档、效果图、测试卡底图等(点此下载),打开的时候别忘了允许宏运行。大家发挥想象,自己玩去吧。
广告声明:文内含有的对外跳转链接(包括不限于超链接、二维码、口令等形式),用于传递更多信息,节省甄选时间,结果仅供参考,IT之家所有文章均包含本声明。