I'm trying to mimic a screensaver on PowerPoint that will return to my first slide after X amount of seconds of inactivity.
The PowerPoint presentation is all just completely image based and every click will transition through the slides, so it doesn't have to be sophisticated at all, just that at the start of each slide it counts down 5 seconds, then returns to slide 1 (which is my fake screensaver page).
I've already got something working in a basic format, it takes you to the first page after 5 seconds, but the timer doesn't restart once you go to a new slide, once it starts counting down, regardless of if you move to the next slide after 3 seconds, you don't get another 5 second countdown, it just finishes the remaining 2 seconds and redirects you.
VBA is definitely not my primary language, I'm just piecing this together with what I can find, but my current code is below
Sub Auto_NextSlide(Index As Long)
Dim Delay, Start
If Index > 1 Then
Delay = 5
Start = Timer
Do While Timer < Start + Delay
DoEvents
Loop
SlideShowWindows(1).View.GotoSlide (SlideShowWindows(1).Presentation.Slides(1).SlideIndex)
End If
End Sub
Try maybe something like below (using class events)
' AppEvents class module
Option Explicit
Public WithEvents App As Application
Const Delay As Integer = 5
Dim Start
Dim actualSlide As Integer
Private Sub App_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
With Wn.Presentation.SlideShowWindow
Start = Timer
actualSlide = .View.Slide.SlideIndex
If actualSlide > 1 Then
Do While Timer < Start + Delay
DoEvents
If .View.Slide.SlideIndex <> actualSlide Then
Start = Timer
actualSlide = .View.Slide.SlideIndex
End If
Loop
.View.GotoSlide (.Presentation.Slides(1).SlideIndex)
End If
End With
End Sub
Module code
' Module 1
Option Explicit
Public pApp As AppEvents
Sub GetAppClass()
Set pApp = New AppEvents
Set pApp.App = Application
ActivePresentation.SlideShowSettings.Run
End Sub
Related
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
I have a small scrip that basically presses "F2" for me every 4 minutes for the duration of 8hours for the active application.
It works and is really basic as my skills in VB are extremely limited.
I now thought of a new addition to the project but have no idea if it is possible or how to tackle it.
I would basically like to have a small window in which the timer is displayed as well as a Pause and Resume and Stop button. It would be of a huge advantage if I could have these buttons as if I´m in another application, i don´t want the F2 button pressed.
Here is what I have:
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
dim ti
ti=timer
Do
WshShell.SendKeys "{F2}"
For AA = 1 To 9
IF AA = 8 Then BB = "in 30 seconds"
IF AA = 9 Then BB = "now !"
WScript.Sleep 30000
Dim oShell
Set oShell= CreateObject("Wscript.Shell")
IF AA = 8 OR AA = 9 Then oShell.Popup " Refresh ... " & BB & " ",2,"Remind"
Next
Loop while (timer-ti)<8*60*60
MsgBox "VB End: " & Time()
Thank you
OK, just a high level answer as it's late and I'm going to bed.
On your form, place a timer control. Set it for a 1000 interval (1 sec).
Place your start & pause buttons also.
Here's the code that will run it.
Dim IsRunning As Boolean
Private Sub cmdPause_Click()
IsRunning = False
End Sub
Private Sub cmdStart_Click()
IsRunning = True
End Sub
Private Sub Timer1_Timer()
Static LastTime As Date
If IsRunning Then
If DateDiff("n", lastdate, Now()) >= 4 Then
'sendkeys
LastTime = Now()
End If
End If
End Sub
The IsRunning variable is outside any procedure and is called a shared variable. Any procedure within this form can see it. The start & pause buttons turn the value of it to true or false.
The Timer event will run every sec. Here we're checking if IsRunning is true and also if 4 minutes has expired yet. If so, then you can run your sendkeys.
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).
How can I make excel continuously calculate a sheet/range in realtime (not 1 calc/sec) and do it in the background?
I want this metric clock to run like a stopwatch....
=IF(LEN(ROUND((HOUR(NOW())*(100/24)),0))=1,"0"&ROUND((HOUR(NOW())*(100/24)),0),ROUND((HOUR(NOW())*(100/24)),0))&":"&IF(LEN(ROUND((MINUTE(NOW())*(100/60)),0))=1,"0"&ROUND((MINUTE(NOW())*(100/60)),0),ROUND((MINUTE(NOW())*(100/60)),0))&":"&IF(LEN(ROUND((SECOND(NOW())*(100/60)),0))=1,"0"&ROUND((SECOND(NOW())*(100/60)),0),ROUND((SECOND(NOW())*(100/60)),0))
I've used the following to produce the effect you are looking for:
Option Explicit
Public TimerRunning As Boolean
Dim CalculationDelay As Integer
Public Sub StartStop_Click()
If (TimerRunning) Then
TimerRunning = False
Else
TimerRunning = True
TimerLoop
End If
End Sub
Private Sub TimerLoop()
Do While TimerRunning
'// tweak this value to change how often the calculation is performed '
If (CalculationDelay > 500) Then
CalculationDelay = 0
Application.Calculate
Else
CalculationDelay = CalculationDelay + 1
End If
DoEvents
Loop
End Sub
StartStop_Click is the macro that I tie to the Start/Stop button for the stopwatch. You can get fancy, and change its name to "Start" or "Stop" depending on the value of TimerRunning, but I kept things simple to illustrate the concept.
The two key things here are:
Application.Calculate
Which forces Excel to calculate the worksheet, and:
DoEvents
Which allows VBA to run in the background (i.e. Excel does not stop responding to user input). This is what allows you to still press the "Stop" Button even though the timer is running.
I think this might fail your "(not 1 calc/sec)" criteria, but I achieved something similar as follows. Assumes your formula is in cell A1 of a worksheet named Sheet1.
In the ThisWorkbook code module:
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("00:00:01"), "RecalculateRange"
End Sub
... and in a regular code module:
Public Sub RecalculateRange()
Sheet1.Range("A1").Calculate
Application.OnTime Now + TimeValue("00:00:01"), "RecalculateRange"
End Sub
Good morning,
I am working on a macro to autorefresh excel links before slideshow, loop through slideshow and then restart over and over again. The issue I am having is the slideshow stops but doesnt exit so the wait timer doesnt have a chance to even kick in.
Can I get a suggestion of how I might fix this?
Sub LoopAllSlides()
Dim i As Integer
For i = 0 To 2000
Dim Endpoint As Single
Endpoint = Timer + 10
Do While Timer < Endpoint 'This loop works dont delete
DoEvents
Loop
ActivePresentation.UpdateLinks
With ActivePresentation.SlideShowSettings
.AdvanceMode = ppSlideShowUseSlideTimings
.LoopUntilStopped = msoFalse
.Run
End With
Next i
End Sub
You can always do this with the Application.Quit function, which will exit out of your current sub. So, something like this:
Sub LoopAllSlides()
Dim i As Integer
For i = 0 To 2000
Dim Endpoint As Single
Endpoint = Timer + 10
Do While Timer < Endpoint 'This loop works dont delete
DoEvents
Loop
ActivePresentation.UpdateLinks
With ActivePresentation.SlideShowSettings
.AdvanceMode = ppSlideShowUseSlideTimings
.LoopUntilStopped = msoFalse
.Run
End With
Next i
'Quit Application Function
IWishICouldQuitYou
End Sub
Function IWishICouldQuitYou()
With Application
For Each w In .Presentations
w.Save
Next w
.Quit
End With
End Function