By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,097 Members | 1,405 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,097 IT Pros & Developers. It's quick & easy.

Animating a Picture

P: 44
How can I make a picture slide across the form in VBA. It can be pre-programmed or random what ever is easier. I need to be able to see it move at any given speed.

Thanks for your support.
Apr 3 '07 #1
Share this Question
Share on Google+
17 Replies


Expert 5K+
P: 8,434
How can I make a picture slide across the form in VBA. It can be pre-programmed or random what ever is easier. I need to be able to see it move at any given speed.
Moving it is easy - you can either set the .Top and/or .Left properties, or use the .Move method.
Apr 3 '07 #2

P: 44
Moving it is easy - you can either set the .Top and/or .Left properties, or use the .Move method.
I understand but this moves it so fast that I can't see it happen.
Apr 3 '07 #3

Expert 5K+
P: 8,434
I understand but this moves it so fast that I can't see it happen.
Have you tried putting a DoEvents in the loop? This might make a slight difference.

You could also invoke the Sleep function, which is somewhere in the API. Try a search for terms such as "VB SLEEP" on TheScripts. I think it allows you to put your program to sleep (basically, tell the CPU to ignore it) for a specified number of milliseconds.
Apr 4 '07 #4

P: 31
How are you using the picture's .Left and .Top properties or Move method? Are you using them in a loop of some kind?

One way of doing this at a fairly consistent pace, independent of the computer's overall speed, is by using a Timer control.

Example:
(to move from left to right)


Expand|Select|Wrap|Line Numbers
  1. Private Sub Timer1_Timer()
  2.  
  3.     Picture1.Move Picture1.Left + 15
  4.  
  5. End Sub
Set the Interval property of the Timer control to "50" (50 milliseconds). You may adjust this value after testing the code, to meet your needs.
Somewhere else in your program's code, you will switch the timer on by changing its Enabled property value to "True" (causing the picture to begin moving), and then switch the timer off by changing its Enabled property value to "False" (stopping the movement of the picture).

The direction in which the picture moves can be adjusted by changing the "+" (plus) to a "-" (minus), causing it to move right; and/or by giving the Move method a Top value to move the picture up or down.

Example
(to move diagonally down-right)

Expand|Select|Wrap|Line Numbers
  1. Private Sub Timer1_Timer()
  2.  
  3.     Picture1.Move Picture1.Left + 15, Picture1.Top - 15
  4.  
  5. End Sub
If the form's ScaleMode property is set to "Twips", the number added or subtracted is equal to the number of twips that the picture is moved, when the Timer's Timer event is executed each interval. One pixel is equal to 15 twips.

Get the picture?
Apr 4 '07 #5

P: 44
How are you using the picture's .Left and .Top properties or Move method? Are you using them in a loop of some kind?

One way of doing this at a fairly consistent pace, independent of the computer's overall speed, is by using a Timer control.

Example:
(to move from left to right)


Expand|Select|Wrap|Line Numbers
  1. Private Sub Timer1_Timer()
  2.  
  3.     Picture1.Move Picture1.Left + 15
  4.  
  5. End Sub
Set the Interval property of the Timer control to "50" (50 milliseconds). You may adjust this value after testing the code, to meet your needs.
Somewhere else in your program's code, you will switch the timer on by changing its Enabled property value to "True" (causing the picture to begin moving), and then switch the timer off by changing its Enabled property value to "False" (stopping the movement of the picture).

The direction in which the picture moves can be adjusted by changing the "+" (plus) to a "-" (minus), causing it to move right; and/or by giving the Move method a Top value to move the picture up or down.

Example
(to move diagonally down-right)

Expand|Select|Wrap|Line Numbers
  1. Private Sub Timer1_Timer()
  2.  
  3.     Picture1.Move Picture1.Left + 15, Picture1.Top - 15
  4.  
  5. End Sub
If the form's ScaleMode property is set to "Twips", the number added or subtracted is equal to the number of twips that the picture is moved, when the Timer's Timer event is executed each interval. One pixel is equal to 15 twips.

Get the picture?
I get it but VBA has no Private Sub Timer1_Timer() type control. It has OnTime.
Apr 4 '07 #6

Expert 5K+
P: 8,434
Unfortunately, VBA doesn't have a timer control. Unbelievable, but that's MS for you.

There are ways to simulate it, and third-party controls you can use. For example, see this thread.

(Sorry, I typed this a couple of hours ago but forgot to hit Submit.)
Apr 4 '07 #7

P: 44
Unfortunately, VBA doesn't have a timer control. Unbelievable, but that's MS for you.

There are ways to simulate it, and third-party controls you can use. For example, see this thread.

(Sorry, I typed this a couple of hours ago but forgot to hit Submit.)
I know that I have this code so far:

Expand|Select|Wrap|Line Numbers
  1. Sub ShapeMover()
  2.     Image1.Left = Image1.Left + 6
  3.     Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="ShapeMover"
  4. End Sub
When I run this it says sub or function not defined and this is all the code I have. How can I fix this?
Apr 4 '07 #8

Expert 5K+
P: 8,434
I know that I have this code so far:

Expand|Select|Wrap|Line Numbers
  1. Sub ShapeMover()
  2.     Image1.Left = Image1.Left + 6
  3.     Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="ShapeMover"
  4. End Sub
When I run this it says sub or function not defined and this is all the code I have. How can I fix this?
At what point does it say this? When it runs, or when you try to compile it?

Maybe you need to qualify the name you pass, like "Module1.ShapeMover" or something. Or is it complaining about the TimeValue( ) function?
Apr 4 '07 #9

P: 44
At what point does it say this? When it runs, or when you try ti compile it?

Maybe you need to qualify the name you pass, like "Module1.ShapeMover" or something. Or is it complaining about the TimeValue( ) function?
It says this when I close the form. I run it and it moves the shape then I wait for the timer for about a minute but it never kicks in so I close it. At that point after I close it it shows the error message. The problem is that It is not a module I want to rerun the "ShapeMover" thing.
Apr 4 '07 #10

Expert 5K+
P: 8,434
It says this when I close the form. I run it and it moves the shape then I wait for the timer for about a minute but it never kicks in so I close it. At that point after I close it it shows the error message. The problem is that It is not a module I want to rerun the "ShapeMover" thing.
Well yes, but the ShapeMover routine will still reside in something. It might be a worksheet in Excel, or whatever.

Hm... after checking the doco, I think the parameter name When is wrong. Try LatestTime.

Correction: I think EarliestTime is required, but you should also set LatestTime (to the same value, in this case).
Apr 4 '07 #11

P: 44
Well yes, but the ShapeMover routine will still reside in something. It might be a worksheet in Excel, or whatever.

Hm... after checking the doco, I think the parameter name When is wrong. Try LatestTime.

Correction: I think EarliestTime is required, but you should also set LatestTime (to the same value, in this case).
This gave me a compile error saying that the named argument was not found.
Apr 4 '07 #12

Expert 5K+
P: 8,434
This gave me a compile error saying that the named argument was not found.
Oh. That's interesting.

According to the online help here, which is for VBA in Excel 2003, the syntax is...
expression.OnTime(EarliestTime, Procedure, LatestTime, Schedule)
Presumably you're using a different version. Can you check the parameters?

It looks as though I had the meaning of LatestTime wrong, anyway. I thought that if the procedure had not been run by this time, VBA would force it to run immediately. But in fact, the doco says...
If Microsoft Excel is not in Ready mode within 30 seconds, the procedure won’t be run.
(Note, the 30 seconds relates to their example.)

Perhaps you should look into obtaining a 3rd party ActiveX timer control, or something.
Apr 4 '07 #13

P: 31
I appologise for my earlier post. I didn't realise that VBA didn't have the Timer control. Oh well...

Another alternative is to create "Do" loops. Although not as smooth or independent of computer processing speed, this method should still be OK.

Example:

Declarations
Expand|Select|Wrap|Line Numbers
  1. Private I As Integer
  2. Private Mode As Integer
The example makes the use of a command button on the form, to activate and deactivate the movement of the picture.

General Code
Expand|Select|Wrap|Line Numbers
  1. Private Sub Command1_Click()
  2.  
  3.     Mode = Not Mode
  4.     If Mode = -1 Then Call PicMove
  5.  
  6. End Sub
  7.  
  8. Private Sub PicMove()
  9.  
  10.     If Mode = -1 Then
  11.         Do
  12.             Do
  13.                 I = I + 1
  14.             Loop Until I = 10000
  15.             I = 0
  16.             Picture1.Move Picture1.Left + 1
  17.             DoEvents
  18.         Loop Until Mode = 0
  19.     End If
  20.  
  21. End Sub
Again, the form's ScaleMode property should be set to "Twips". Note that the value added on the the Picture's Left property has changed from "15" to "1". You will also want to adjust the maximum loop value of "I", depending on the speed of the computer you want to use your program on.
Apr 4 '07 #14

P: 44
I appologise for my earlier post. I didn't realise that VBA didn't have the Timer control. Oh well...

Another alternative is to create "Do" loops. Although not as smooth or independent of computer processing speed, this method should still be OK.

Example:

Declarations
Expand|Select|Wrap|Line Numbers
  1. Private I As Integer
  2. Private Mode As Integer
The example makes the use of a command button on the form, to activate and deactivate the movement of the picture.

General Code
Expand|Select|Wrap|Line Numbers
  1. Private Sub Command1_Click()
  2.  
  3.     Mode = Not Mode
  4.     If Mode = -1 Then Call PicMove
  5.  
  6. End Sub
  7.  
  8. Private Sub PicMove()
  9.  
  10.     If Mode = -1 Then
  11.         Do
  12.             Do
  13.                 I = I + 1
  14.             Loop Until I = 10000
  15.             I = 0
  16.             Picture1.Move Picture1.Left + 1
  17.             DoEvents
  18.         Loop Until Mode = 0
  19.     End If
  20.  
  21. End Sub
Again, the form's ScaleMode property should be set to "Twips". Note that the value added on the the Picture's Left property has changed from "15" to "1". You will also want to adjust the maximum loop value of "I", depending on the speed of the computer you want to use your program on.
This didn't do anything. No error, it just didn't do anything.
Apr 4 '07 #15

P: 5
Here are some ways to time things out in VB.

In this instance the program will not run until after 7 AM.

Do
If Time > #7:00:00 AM# Then
MsgBox ("Time is " & Time)
Exit Do
End If
Loop


This one simply delays a process for a set amount of time. This example would delay the process for 1 asecond. I am pulling it off the top of my head so it might not be exact.

Application.waitnow + (timevalue("00:00:01"))


There is also the timer function from Excel Help that can be used in Access with minor modifications.

This example uses the Timer function to pause the application. The example also uses DoEvents to yield to other processes during the pause.

Dim PauseTime, Start, Finish, TotalTime
If (MsgBox("Press Yes to pause for 5 seconds", 4)) = vbYes Then
PauseTime = 5 ' Set duration.
Start = Timer ' Set start time.
Do While Timer < Start + PauseTime
DoEvents ' Yield to other processes.
Loop
Finish = Timer ' Set end time.
TotalTime = Finish - Start ' Calculate total time.
MsgBox "Paused for " & TotalTime & " seconds"
Else
End
End If



And one last timer function for VBA taken from http://msdn2.microsoft.com/en-us/library/aa211461(office.11).aspx

Private Sub Form_Timer()
Clock.Caption = Time ' Update time display.
End Sub
Apr 4 '07 #16

Expert 5K+
P: 8,434
Here are some ways to time things out in VB.

In this instance the program will not run until after 7 AM.

Do
If Time > #7:00:00 AM# Then
MsgBox ("Time is " & Time)
Exit Do
End If
Loop
Thanks for the input. I would caution readers, though, that this is a good way to chew up heaps of CPU and slow things down. I'd suggest including a DoEvents statement inside the loop, to tell Windows it can go do other things.

Of course, this is less of a problem than it was under earlier versions of Windows, where you could completely lock up the system.

This one simply delays a process for a set amount of time. This example would delay the process for 1 asecond. I am pulling it off the top of my head so it might not be exact.

Application.waitnow + (timevalue("00:00:01"))
According to the online help here, the syntax is...
expression.Wait(Time)
The examples given are:
Example
This example pauses a running macro until 6:23 P.M. today.

Expand|Select|Wrap|Line Numbers
  1. Application.Wait "18:23:00"
This example pauses a running macro for approximately 10 seconds.

Expand|Select|Wrap|Line Numbers
  1. newHour = Hour(Now())
  2. newMinute = Minute(Now())
  3. newSecond = Second(Now()) + 10
  4. waitTime = TimeSerial(newHour, newMinute, newSecond)
  5. Application.Wait waitTime
There is also the timer function from Excel Help that can be used in Access with minor modifications.

This example uses the Timer function to pause the application. The example also uses DoEvents to yield to other processes during the pause.

Expand|Select|Wrap|Line Numbers
  1. Dim PauseTime, Start, Finish, TotalTime
  2. If (MsgBox("Press Yes to pause for 5 seconds", 4)) = vbYes Then
  3.     PauseTime = 5    ' Set duration.
  4.     Start = Timer    ' Set start time.
  5.     Do While Timer < Start + PauseTime
  6.         DoEvents    ' Yield to other processes.
  7.     Loop
  8.     Finish = Timer    ' Set end time.
  9.     TotalTime = Finish - Start    ' Calculate total time.
  10.     MsgBox "Paused for " & TotalTime & " seconds"
  11. Else
  12.     End
  13. End If
Nice one.

I do have a minor quibble, though. For efficiency reasons, it's generally not a good idea to include unnecessary calculations in a loop. In this example, you really should calculate Start + PauseTime once up front, store the result in a variable, then use that variable in the While condition.

What I generally do when I want a pause like this is to put it in a sub or function, so I can call it from more than one place. It also makes you code more readable, since you can just say something like:
Pause 3
...Private Sub Form_Timer()
Clock.Caption = Time ' Update time display.
End Sub
Good point. I was forgetting that a form has its own OnTimer event, and TimerInterval property. In Access, at least. Does this apply in Excel? I don't think I've ever used a form in Excel.
Apr 4 '07 #17

Expert 5K+
P: 8,434
This didn't do anything. No error, it just didn't do anything.
Generally speaking, I would avoid using delay loops. When processors ran at 1MHz they were useful. These days there is just too much variation, and too much speed. A loop that causes a one-second delay today, might produce no noticeable delay at all after the next upgrade.

Better to use one of the clock-based delay techniques as discussed in other messages here.
Apr 4 '07 #18

Post your reply

Sign in to post your reply or Sign up for a free account.