Avoid blocking user interaction with form - Access VBA 2007 - vba

This may seem like a very odd thing to do in VBA but I'm curious so hear me out.
I created a procedure that moves an image across the screen when it's clicked. This works, albeit alright, but still - it works.
Here is the code:
'Start primitive animation
Private Sub imgBean_Click()
'Limit for movement to right
Dim coordinates, limit As Integer
coordinates = 0
limit = Form.Width
Do While coordinates < limit
coordinates = coordinates + 5
'Move the image
Me.imgBean.Move coordinates
'Needed to add this to see the image move - updates the form
Form.Repaint
Loop
Debug.Print "Coordinates " & coordinates
Debug.Print limit
'Reset the limit
limit = 0
End Sub
As said before the code works - but while the image is moving the screen is frozen i.e. I can't close the form or interact with other components. (This is similar to blocking the UI thread in the Android environment - something that you never do!)
So is there a way to avoid this?
Thanks
P.S. Setting the focus to the form makes the image sporadically appear and disappear.

Turns out I couldn't find a way to visually prevent interaction with the GUI once the animation has started. I said visually because it is possible to click buttons and enter input while the animation is running.
It involved the use of the DoEvents command which acts as a way of multitasking in MS Access. In mine I added the command above the Do-While loop (see below):
'Essentially allow multitasking
DoEvents
Do While coordinates < limit
coordinates = coordinates + 5
'Move the image
Me.imgBean.Move coordinates
Form.Repaint
Loop
It should be noted that it didn't work when I placed it in the Do-While loop. So, when I started the animation by clicking on the image I could still press the other buttons because I entered a value one one field and clicked a button to convert it to another - while the animation is running.
The only question is how to do this in a visual sense.

Related

How to resize an access form to fit the screen

So I've recently upgraded from Access 2003 to Access 2016 and of course, I hate having to deal with the obnoxious white background that can not be changed in 2016. Maximizing forms/reports is not an option for us as we oftentimes will be using multiple forms/reports at any given time and need to be able to view and change between them to do our job.
I've come up with what I think is a pretty smart solution, I created a background form that is empty except that it has a dark gray background to make it easier on your eyes. When you open a new form or report (On Open Event), it then places that form on top of a stack so that you have a hierarchy of open forms and reports.
Should you click on a form or report that isn't on top (On Activate Event), then it gets moved back to the top of the stack. Then should you accidentally click on the background form, instead of covering up everything you've been working on, it goes through the stack, starting at the bottom and setting focus to each form or report in order. Here's how I do it for those of you interested:
Private Sub Form_GotFocus()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("SELECT ID, FormName, FrmRpt FROM FormStack ORDER BY ID", dbOpenSnapshot)
If rst.EOF Then
DoCmd.OpenForm "frmMenu"
Else
While Not rst.EOF
If rst.Fields("FrmRpt") = "Form" Then
Forms(rst.Fields("FormName")).SetFocus
Else
DoCmd.SelectObject acReport, rst.Fields("FormName")
End If
rst.MoveNext
Wend
End If
rst.Close
Set rst = Nothing
End Sub
This is all working perfectly, I just need to make sure I add the code to any new forms or reports that I create.
So here is my dilemma, this background form needs to be big enough to fill the screen of whoever is using it, otherwise, you would see white around the edges. Since everyone has different monitors I decided to make the form extremely large (21"x13") so that it would fill the screen of anyone who is using it. I have Auto Center, Auto Resize, and Fit To Screen all set to yes.
I have No border, record selectors, navigation buttons, diving lines, scroll bars, control boxes, close buttons, or min-max buttons, and it also is not moveable. The Detail section can grow and can shrink. So now everything is working, except since this form is bigger than anyone's Access window, there are now scroll bars on the Access window itself so that you can move around to see the whole background form in all of its drab, dark gray glory.
It would be great if it could be fit to fill the Access window perfectly so that these scroll bars won't appear and confuse users.
Does anyone know how to solve this problem?
Go to Access settings=> document window options and select tabbed documents. Any form you want to have specific size, you can then set as "popup".
You can still have your custom form with custom bg colour, size 1cmx1cm, no scroll, no navigation bar, no record selctor, borderstyle none. Place a rectangle and set the Anchoring property to "strech down and across" that'll fill the whole access app and user won't be able to close it.
settings page
sample result
I would
Maximize the background form to cover the Access background.
Set all Forms+Reports to Popup = Yes, then they won't be maximized, even if a maximized form is open.
Educate the users that they now have more freedom where to move the windows, and that they should avoid covering the menu bar.
If some of them have a two-monitor setup, they can also move some windows to the 2nd monitor (outside the Access main window). This can be very useful.
(And most importantly) do away with all this code in all forms.
Late answer, but best solution I've found is Shrinker-Stretcher over at Peter's Software. It cycles through all controls and resizes everything on a form (and its subforms) to fit the application window. Developer's license is reasonable for what it does.
Well this doesn't resize a form to fit the screen, but Access now has a Dark Gray theme which gives me a dark background and solves my problem.

How to implement disappearing animations in VBA?

I'm trying to test effect animations on shapes in a VBA procedure.
I've already achieved one which is adding some new animations in the MainSequence, defining in which position in the Timeline... but I am not able to create disapearing animations.
I checked in the beginning of the code some already there...and the EffectType seems to return the same value as related appearing animation, so that I sadly believe there's no way of creating disapearing animations in VBA.
Please tell me I am wrong, I have to do the same creations on over 300 slides...
Yes, you are wrong, however documentation to that is... well, I guess you know that already.
Here's the trick. To add a disappearing animation you have to add appearing animation but set it's 'Exit' property to 'msoTrue'
Take a look at this code example:
Private Sub SetAnimation()
Dim effNewEffect As Effect
With ActiveWindow.View.Slide
Set effNewEffect = .TimeLine.MainSequence.AddEffect(.Shapes(.Shapes.Count), msoAnimEffectAppear, trigger:=msoAnimTriggerWithPrevious, Index:=-1)
End With
effNewEffect.Timing.TriggerDelayTime = 1.0
effNewEffect.Exit = msoTrue
End Sub
It will add a Disappear animation to the last Shape in a current slide as the last in the MainSequence with delay 1.0 s to the previous animation.
The solution I found is to use an "Exit" property on the "Effect" object.
The "Exit" property is msoFalse by default.
Can't believe I have the answer to anything but here goes.
Select object to disappear
Go to animations an select fade out (red one)
Open animation pane
go to the click down menu for the object
Select Effect options
Go to timing menu
Click triggers
Click "start effect on click of" and find the object number that matches the one on the animation panel for it.
Job done.

Issues with event created buttons not aligning as expected

new bloke having issues again.I have a button on a form which is set to create another button in it's current location, then using a timer that runs
button.top = button.top + 10
for every tick, the design created (aka button creator) button moves down to just under the new button, and in the same alignment. Due to the size of the form I'm working on, once this has been done 3 times, the creator button is now askew, slightly to the right of the added buttons above it, rather than than in the same place, due to the controls now extending past the form size and the scrollbar becoming visible.
I've done some searching around, but so far the answers I have found haven't helped - probably more due to me not understanding correctly - and it's starting to do my head in because it should logically be so simple.
I thought I'd figured out the issue this evening when I realised that it's the previously added buttons which are moving from
location.x = 100
to
location.x = 91
and not the creator button changing it's habits.
Can anyone point out what is probably something so simple that I am overlooking in order to get these aligned?
Thanks in advance.
instead of using the location.x property try using LEFT property of the object...
so when you create the NEW button and set its inital position use the ThisButton.Left = Value to position it....
where ThisButton is the NAME of your button
and Value is the X location numeric value.

How to auto advance a PowerPoint slide after an exit animation is over?

PowerPoint entrance animation set up with "Start: With Previous" starts right when a new slide is advanced. However, if you set up an exit animation in the same way, it doesn't start with a slide ending sequence. Instead, the "Start: On Click" trigger needs to be used and after your exit animation is over you still need one extra click just to advance to the next slide.
Workarounds to this are obvious: create a duplicate slide, make your ending animations from the original slide being your starting animations on the duplicate slide and let them be followed with whatever you want or create a transition slide with those ending animations only and set up "Change Advance slide -> Automatically after -> [the time it takes your animations to finish]".
These workarounds will make it work for your audience, visually. However, it has an impact on slide numbers you might need to adjust accordingly and/or duplicate content changes. If you are the only one creating and using your presentation, this might be just fine. But if you are creating a presentation in collaborative mode with three other people and don't even know who will be the presenter at the end, you can mess things up.
Let's be specific: most of my slides have 0.2s fly in entrance animation applied to blocks of content coming from right, bottom or left. Advancing to the next slide I want them to fly out in another 0.2s exit animation being followed by new slide 0.2s fly in entrance animation of the new blocks. The swapping of the blocks should be triggered while advancing to the next slide, as usually.
As mentioned, I'm not able to achieve this without one extra click between the slides.
I wrote a VBA script that should start together with an exit animation and will auto advance a slide after 0.3s when the exit animation is over. That way I should get rid of those extra clicks which are needed right now.
Sub nextslide()
iTime = 0.3
Start = Timer
While Timer < Start + iTime
DoEvents
Wend
With SlideShowWindows(1).View
.GotoSlide (ActivePresentation.SlideShowWindow.View.Slide.SlideIndex + 1)
End With
End Sub
It works well when binded on a box, button or another object. But I can't make it run on a single click (anywhere on the slide) so that it could start together with the exit animation onclick trigger. Creating a big transparent rectangular shape over the whole slide and binding the macro on it doesn't help either. By clicking it you only get the macro running, exit animation is not triggered.
Anyway, I don't want to bind the macro to any other workaround object but the slide itself.
Anyone knows how to trigger a PowerPoint VBA script on slide onclick event?
Anyone knows a secret setting that will make the exit animation work as expected i.e. animating right before exiting a slide while transitioning to the next one?
Anyone knows how to beat this dragon?
Thank you!
You could also set the TRANSITIONS (tab) -> Advance Slide After 00:00:00 seconds. You will need to set the SLIDESHOW (tab) to Use (Rehearsal) Timings. This will automatically advance the slide after the last animation action. You could, of course give it some seconds to wait, but it sounds like you just want to advance the slide.
You can intercept events in powerpoint using class module
In Class Module
In left combo (object) in VBA Explorer you can see ppt and in right your events
Private WithEvents ppt As PowerPoint.Application
In common module use
set x= new class1
Now you can use all events of presentation.
[]'s
OnSlideShowPageChange: VBA working while going to a slide without pressing any button
Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
If SSW.View.CurrentShowPosition = SSW.Presentation.Slides(x).SlideIndex Then
'PUT CODE HERE
End If
End Sub
Theire is a code havy workaround
You do that using the duplicate methode. However you duplicate using vba not manualy.
You can use the OnSlideShowPageChange
Test if the slide is one that need to be duplicated using a naming scheme of your choice. Then duplicate the slide. Then set the trasition effect to non and make it transition after 0 sec duration. Then remove all animations and add the exit animations desired.
Then you use the SlideShowEnd event to delete all the duplicate slides.
Note that you can use the SlideShowBegin to duplicate all the slides at once however duplicating a slide is not a fast tasck. So if you have a lot of havy slides to duplicate strating you presentation may take few seconds.
Sorry for not providing the code since it needs several lines.
For naming the slides you use also a macro.

How to pause execution for few seconds and continue the loop?

I am creating a small applicaiton for simulating dice roll. To simulate bounces I change the position of the picture randomly. Now to simulate more than one bounce, I used a for loop to continuously change the position of the picture box. But it is not happening as I planned, the form only displays the position of the last loop. I even tried using System.Threading.Thread.Sleep(1000) hoping to show the bounces, but even they show the last loop only.
For bounceCount As Integer = 1 To bounces
bounce(pb_dice1)
bounce(pb_dice2)
System.Threading.Thread.Sleep(3000) 'I need to pause here and show the recent change in position then continue after 3 seconds
Next
the bounce method changes the position of the PictureBox.
How can I pause my for loop, display the newly positioned dices, and then continue after 3 seconds?
Controls don't refresh their graphics until event handlers finish executing. Otherwise, if several changes were made to one or more controls, they would refresh repeatedly when all you really want is the end result.
To force a control to refresh it's graphics, you need to insert the following line before sleeping:
PictureBox1.Refresh()
You may have to change PictureBox1 to the name of another control, of course. Also, it may be worth refreshing the parent control (ie. the control that contains the dice.)
I guess you should use Application.DoEvents() before calling Sleep().