OnSlideShowPageChange Not Advancing Slide - vba

I am trying to run a live clock on every slide in a PowerPoint presentation for a kiosk.
I am able to get the live time to run perfectly and in the preferred format on the first slide. The slide will not advance. The macro will not run on the second slide when advanced manually. Here is my code.
It seems that the code is overriding the default slideshow settings?
Sub OnSlideShowPageChange()
Dim i As Integer
Dim time As Date
time = Now()
time = DateAdd("n", minutes, time)
i = ActivePresentation.SlideShowWindow.View.CurrentShowPosition
Do
DoEvents
With ActivePresentation.Slides(i).Shapes("Rectangle 3").TextFrame.TextRange
.Text = Format(Now(), "hh:mm:ss")
End With
Loop
End Sub

I figured out that the slides wouldn't advance because I was stuck in the loop. Here is my fix...but its success is sporadic. Sometimes it will scroll through 5 slides and then get stuck on a slide, other times 2. I am not sure what is happening. Still digging at it.
Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
Dim i As Integer
Dim time As Date
Dim tstop As Date
time = Now()
time = DateAdd("n", minutes, time)
tstop = time + TimeValue("00:00:10")
i = ActivePresentation.SlideShowWindow.View.CurrentShowPosition
Do Until time = tstop
DoEvents
With ActivePresentation.Slides(i).Shapes("Rectangle 3").TextFrame.TextRange
.Text = Format(Now(), "hh:mm:ss AM/PM")
End With
time = Now()
Loop
End Sub

Related

VBA Time limit macro

I'm attempting to make a GUI for a school project in Excel of a basic security system. I'm trying to have the macro take the user to the alarm slide (slide 8) if the timer runs out and if the disarm boolean is false. However, as I have it now, no matter what the user is always taken to the alarm slide once the timer runs out. I'm not sure what the issue is exactly.
The ARM_DISARM is run by an action button on the disarmed slide.
Global Disarm As Boolean
Sub timelimit()
Disarm = False
ActivePresentation.SlideShowWindow.View.GotoSlide (3)
Dim time As Date
time = Now()
Dim count As Integer
count = 5
time = DateAdd("s", count, time)
Do Until time < Now()
DoEvents
For i = 3 To 6 'slide numbers'
ActivePresentation.Slides(i).Shapes("countdown").TextFrame.TextRange = Format((time - Now()), "hh:mm:ss")
Next i
Loop
If Disarm = False Then
ActivePresentation.SlideShowWindow.View.GotoSlide (8)
End If
End Sub
Sub ARM_DISARM()
Disarm = True
End Sub

OnSlideShowChangePage doesn't run when Page Changed

I'm trying to create a countdown in Visual Basic for my PowerPoint presentation. This worked absolutely fine. I need the macro to start when The slide changes. The slide has to change after 20 seconds. This also works. But when I change the slide programmatically the method OnSlideShowChangedPage doesn't run. Does anyone have an idea why it doesn't work?
This is my code:
Sub OnSlideShowPageChange(ByVal Wn As SlideShowWindow)
MsgBox "Fired"
Dim pos As Integer
pos = Wn.View.CurrentShowPosition
Dim time As Date
time = Now()
Dim count As Integer
count = 20
time = DateAdd("s", count, time)
Do Until time < Now()
DoEvents
ActivePresentation.Slides(pos).Shapes("countdown").TextFrame.TextRange = Format((time - Now()), "hh:mm:ss")
Loop
ActivePresentation.SlideShowWindow.View.Next
End Sub

How to remove animation on PowerPoint after it has played in slideshow without using .AddShape with VBA

Here is my code: (Using PowerPoint 2016)
Sub MacroTest()
Dim Shp As Shape
Dim effNew As Effect
Dim sldOne As Slide
Set sldOne= ActivePresentation.Slides(1)
Set Shp = ActivePresentation.Slides(1).Shapes(2)
Set effNew = sldOne.Timeline.MainSequence _
.AddEffect(Shape:=Shp, _
effectid:=msoAnimEffectSpin, _
Trigger:=msoAnimTriggerWithPrevious)
End Sub
My goal with this code is to see if I can apply it to a PowerPoint game. I want to be able to have the user click a button to make a box spin, and then have the animation deleted immediately after so that if they click it again, it won't play two or more spin animations. Also, I want the animation deleted so the animation pane won't have hundreds of spin animations in it.
Most the examples I have seen use .AddShape, because the animation disappears with the shape - however, it would be easier to apply an animation to an existing shape that I can see and interact with when designing a game.
I am aware that this is achievable without VBA, using triggers, but I eventually want to incorporate if then statements and more code to this once I get the hang of it.
I appreciate any help, I am very new to VBA so it means a lot.
Okay so I figured it out. This is for anyone who is having a similar problem.
Code:
Sub MacroTest
Dim Shp As Shape
Dim effNew As Effect
Dim sldOne As Slide
Dim time As Date
Dim count As Integer
Set sldOne = ActivePresentation.Slides(1)
Set Shp = ActivePresentation.Slides(1).Shapes(2)
Set effNew = sldOne.TimeLine.MainSequence _
.AddEffect(Shape:=Shp, _
effectid:=msoAnimEffectSpin, _
Trigger:=msoAnimTriggerWithPrevious)
time = Now()
count = 2
time = DateAdd("s", count, time)
Do Until time < Now()
DoEvents
With effNew
With ActivePresentation.Slides(1).Shapes(4). _
TextFrame.TextRange
.Text = Format((time - Now()), "hh:mm:ss")
If .Text = ("00:00:00") Then
effNew.Delete
Else
End If
End With
End With
Loop
End Sub
So, What I had to do was create a timer, which lasts as long as the spin animation I am using. Then I used an if statement for when that timer reaches 00:00:00 to delete the effect. Hope this helps.

Setting up an Excel Doc to Save and Close after a period of inactivity

I'm trying to come up with a way to close an excel document after a period of inactivity. The problem i'm running into is that if excel is in Edit mode, the macro will not execute. This would be for a workbook that is on a server that multiple people have access to, the problem is that some people leave it open and forget that they have it open and no one else can edit it hence the need for this.
I've create a VBA macro code that only closes the excel document while the user is not in edit mode:
Sub OpenUp()
Dim Start, Finish, TotalTime, TotalTimeInMinutes, TimeInMinutes
Application.DisplayAlerts = True
TimeInMinutes = 1 ' sets timer for 1 minutes
If TimeInMinutes > 1 Then
TotalTimeInMinutes = (TimeInMinutes * 60) - (1 * 60)
' times 60 seconds to "minutize"/convert time from seconds to minutes
Start = Timer ' Sets the start time.
Do While Timer < Start + TotalTimeInMinutes
DoEvents ' Yield to other Excel processes.
Loop
Finish = Timer ' Set end time.
TotalTime = Finish - Start ' Calculate total time.
Application.DisplayAlerts = False
MsgBox "You've had this file open for " & TotalTime / 60 & " minutes. You have 1 minute to save all your files before Excel closes"
End If
Start = Timer ' Sets the start time.
Do While Timer < Start + (1 * 60)
DoEvents ' Yield to other Excel processes.
Loop
Finish = Timer ' Set end time.
TotalTime = Finish - Start ' Calculate total time.
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.Quit
End Sub
I know this request kind of defies logic as you don't want the workbook to close while someone is in the middle of a edit hence why you can't run a macro while in edit mode. But if there is any way to set up some code to save and close a workbook after a certain set time period has passed i would have need of it in this circumstance. Thanks
You need place the below code and save the file to XLSM type. Reopen the file to run the macro
Place the code in the standard module
Option Explicit
Public EndTime
Sub RunTime()
Application.OnTime _
EarliestTime:=EndTime, _
Procedure:="CloseWB", _
Schedule:=True
End Sub
Sub CloseWB()
Application.DisplayAlerts = False
With ThisWorkbook
.Save
.Close
End With
End Sub
Place the code in the Thisworkbook Module
Option Explicit
Private Sub Workbook_Open()
EndTime = Now + TimeValue("00:00:20") '~~> 20 Seconds
RunTime
End Sub
Place this in each worksheet to detect any changes in the worksheet
Private Sub Worksheet_Change(ByVal Target As Range)
If EndTime Then
Application.OnTime _
EarliestTime:=EndTime, _
Procedure:="CloseWB", _
Schedule:=False
EndTime = Empty
End If
EndTime = Now + TimeValue("00:00:20") '~~> 20 Seconds
RunTime
End Sub
I have got the answer from this site
http://www.excelforum.com/excel-programming-vba-macros/600241-excel-vba-close-workbook-after-inactivity.html

Powerpoint macro - basic problem with counter

I am making my first Powerpoint 2007 macro and I am having a bit of trouble with it hanging, and not letting me move on to the next slide. I can press ESCAPE to quit the slideshow, but pressing space bar or anything else won't progress to the next slide. After a while, it just crashes. I come from a C++/Java background so I think its just something basic that I'm missing.
Basically I am trying to do a counter slide that counts the days/minutes/seconds from a particular date. When the slide loads I want it to show, in real time, how long its been since that date. I've put it through an infinite loop, which works fine to update the time, but then doesnt let me move on to the next slide.
Here's my code:
Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
'If SSW.View.CurrentShowPosition = 3 Then
Do While SSW.View.CurrentShowPosition = 3 ' infinite loop
Dim currentSlide As Integer
currentSlide = SSW.View.CurrentShowPosition
Dim startDate As Date
Dim currentDate As Date
Dim sngDiff As Single
Dim lngDays As Long
Dim lngHours As Long
Dim lngMinutes As Long
Dim lngSeconds As Long
startDate = #7/22/2011 2:00:00 PM#
currentDate = Now
sngDiff = currentDate - startDate
lngDays = CLng(sngDiff)
sngDiff = sngDiff - lngDays
lngHours = Hour(sngDiff)
lngMinutes = Minute(sngDiff)
lngSeconds = Second(sngDiff)
With ActivePresentation.Slides(currentSlide)
With .Shapes(2)
.TextFrame.TextRange.Text = "It has been:" & lngDays & " Days " & lngHours & " hours " & lngMinutes & " minutes " & lngSeconds & " Seconds"
End With
End With
DoEvents
Loop
End Sub
Do I need to listen for some sort of button click to stop this infinite loop, or how do I do this?
Thanks.
A user form is something you add in the VBA editor; it's what you'd normally think of as a dialog box, though forms can be used for other things and needn't even become visible; that's what we're going to do here:
Option Explicit
Public bFormCodeRunning As Boolean
Sub FormDemo()
' Set a flag to let us know the code in the form
' is running
bFormCodeRunning = True
' "show" the form
UserForm1.Show vbModeless
End Sub
Sub KillForm()
' call this at some other point in the presentation
' when you're sure you're done running the form code
If Not bFormCodeRunning Then
Unload UserForm1
End If
' You could actually call this from your slide change event handler
End Sub
Then Insert, User Form from the menu to add a new form; doubleclick it to view its code and add this:
Private Sub UserForm_Activate()
' Don't show my face
Me.hide
DoEvents
' prove that the form's loaded
MsgBox "I'm well-formed"
DoEvents
' and put your other code here
' and when the code's done, flag it
bFormCodeRunning = False
End Sub
For doing a time delay in a VBA context it is usually better to use a form_timer object so in your code have:
If SSW.View.CurrentShowPosition = 3 Then
Me.TimerInterval = 1000
Else
Me.TimerInterval = 0
End If
Or something similar. Then in the form timer code have your clock update code
Private Sub Form_Timer()
// Your clock update code here
End Sub
It's been years since I've done any VBA so I'm a bit rusty but I hope this helps. In general use timers instead of loops for threading tasks, VBA doesn't cope well with them.
The problem is that your routine "owns" the app; until it exits, you won't be able to do anything manually (ie, advance to the next slide).
Whether or not you use a timer on a form (and fwiw, the Timer control isn't shipped with VBA as it is with VB), I think a form may be your solution.
Have your event handler load a form modelessly then exit.
The code in the form can then do any mods to slides or whatever else you want.
Include DoEvents often enough that you don't slow down the main app, but the code in the form will run independently of what the main app is doing.
You don't need to make the form visible (and probably don't want to).