Display time left when running - vba

I have a form with a few buttons which execute code when pressed like running validations on the database.
Some code can run for a few minutes so is there any way to show the time remaining or a message to display the % of process completed?
Or pop out a message when code evaluation starts and the message should disappear once code running is completed?

What you are probably looking for is a "Progress Bar".
I've used the Microsoft ProgressBar control (you can find it under Insert->ActiveX Control), and it's not that hard to use. Just set the value of it to a percentage (as an integer, not a decimal).
'foo, being the ProgressBar
me.foo = 70 '70%
There is some good info here on another method: http://www.granite.ab.ca/access/progressbar.htm

In order to do this the "normal" way, you'd need to run your validation in another thread and have it report its progress back to the UI thread. However, I don't believe VBA supports any kind of multithreading.
If your validation routines involve a loop, or even just many separate discrete operations, you can try inserting a DoEvents statement in between loop iterations (or operations), and then have your progress display updated periodically (say, in an Application_OnTime event handler).

I usually have a form I name frmProgress or whatever, with a cancel button and a label for displaying a status message. Then embedded in the form code I have a boolean called bCancel, and when you hit the cancel button it simply sets bCancel as true.
Also in this code I have a routine called ShowPercDone( Idx , NumIdc ) where Idx is the step the code is on, and NumIdc is the number of steps the code will take (assuming each step takes the same amount of time). This works well when I'm running through a for loop, but basically any time I want to display a status update I just call the routine in the form with my message, which I should add runs the doevents command for me.
So that's how the status form works. In the macro I run, I start out by just calling frmProgress.show (0) so that it lets you click the cancel button. Then in my loop when I update the status message I then check frmProgress.bCancel and if it's true I exit out of the macro.
Hope that helps.

Finally to be simple i decided to use the method given here
http://oreilly.com/pub/h/3330#code

Related

In a VBA Userform, which event is triggered when exiting a filed

I'm using Microsoft Office Professional Plus (64 bit) on a Windows 10 (64 bit) platform. I have a subroutine that is processed when I make a change to a Userform field called MyDate. It's called Private Sub MyDate_AfterUpdate(). It's the second field on a form. It works fine as long as the contents of the MyDate field are edited. However, if the user doesn't need to update the contents of the MyDate field because they accept the default of the field and just presses the tab key past that second field, I'd still like the subroutine to be executed. What event can I use to activate code when I simply tab through the field and don't necessarily edit the contents? Thanks for looking at this.
If you look at the top of the code panes, you'll notice two dropdowns. The left one contains all interfaces and event providers you can implement in that class (a UserForm is a class).
Select your MyDate control from that dropdown; the right-side dropdown is now listing every event you could handle for this MyDate control:
In this particular case, the Exit event seems a good candidate:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'make Cancel.Value = True to prevent exiting the control.
'...ideally... make that conditional...
End Sub
By consistently using these dropdowns to let the VBE generate event handler procedures for you (instead of typing them up from memory), you avoid getting it wrong... and getting an event handler signature wrong can do anything from literally nothing at all, to compile errors if you're lucky, or weird and hard-to-diagnose behavior if you're less lucky.

How to prevent UiPath from getting stuck in Call Macro Stage?

I am calling a macro using call macro in UiPath Workflow. The concern is some time one of the excels that the macro handles will freeze forever, Causing the macro execution to hang and the process will get stuck in Call macro forever.
Is there some way I can modify the UiPath workflow so that, if the Call macro activity is not completed within 15 minutes, the bot throws an exception?
There is a way to do this, let me try to present it to you:
You will need 3 variables for your solution as per below:
One to store your wait time until exception will be thrown type of TimeSpan
One to declare your start time of your current execution type of DateTime
One to inform if the default wait time of execution was exceeded or not type of Boolean
Then you need to use Parallel activity where on your Excel Application Scope and Execute Macro will run together with a While loop that will constantly compare starting time and your set waiting time. If it will exceed the default time value set, an exception will be thrown. Check the solution example below:
In this case because we surround Parallel Action in Try-Catch block, you need to specify the exception expression in Catches section, since Throw will be overwritten by Catches as per below:
The second option is to do it without Try-Catch then the Throw exception will be displayed, check solution below:
Also you need to modify the Throw action by setting the exception message accordingly as per image below:
Hope this will be helpful.
You can wrap your call macro in a parallel where you in a second branch have a delay and a Throw Exception. The delay should be your desired timeout value, i.e. 15 minutes.
You also need to have a local variable of type boolean as input to the condition property in the parallel. When/if the macro call returns you set this boolean to True which in turn cancels the delay branch.
This way, if the exception is thrown the parallel is exited and the workflow continues. Based on your desired behavior you may want to wrap the parallel in a try-catch.
Answer by #Konstantinos Palaiodimos is in the right direction but the branch 2 is having loop which would continuously execute until maxWaitTime and eventually would throw exception. So to ensure the control goes back to Branch 1(Excel scope) after timeout checking in Branch 2(Do while Loop) a delay need to be added to the Branch 2.
If there is a delay in branch 2 the control will go back to Branch 1 during that delay to check if macro execution is completed or not , if macro is not completed then again control comes back to branch 2 and the cycle continues until maxWaitTime or till the macro execution completes

Wait for 1 second before starting code again - VB.NET

I desperately need help with a game I am making. For a bit of context, i am making a memory game and i have the following piece of code that is being troublesome. I have a bunch of labels on the form, 16 to be exact, with 1 randomly generated symbol placed in each. Each symbol appears in the labels twice.
------------------------------Continued----------------------------------------
'MsgBox("hello") 'used to check if the second inccorect press shows up - it does show but instantly changes colour
'''''''''''''''''NEED SOME CODE THAT PAUSES IT HERE'''''''''''''''
labels(0).ForeColor = Color.DarkRed
sender.ForeColor = Color.DarkRed
End If
flips = 1
End If
End If
tmrmemory.Enabled = True ' starts the timer after the user clicks the first label
End Sub
What's supposed to happen is that when the labels clicked don't match, it should show both the clicked labels for a short period before changing them both back to "DarkRed" which is the colour of the form's background.
I have tried using a timer but then i can't use sender.forecolor=color.darkred because it is not declared globally.
I have also tried using the command Threading.Thread.Sleep(500) but it still doesn't show the second incorrect click. I know that the code i have used works because when i use the message box, i can see both symbols and when the two clicks are correct, it stays.
Threading.Thread.Sleep(500) will actually pause your code for half a second. However during this time it won't do anything, not even refresh your controls. To get the effect you want, you need to call the YourControl.Refresh method before calling Threading.Thread.Sleep to force the control to redraw immediately.
On a side note, I would advise you not to call Threading.Thread.Sleep on UI thread. It will give a feeling of program hang. Instead do your work on a separate thread. You can either do all the work yourself right from creating a separate thread to destroying it, or use the BackgroundWorker control which has all the functionality built in.
Here is the link to an article I wrote a long time ago regarding BackgroundWorker that might be useful for you:
http://www.vbforums.com/showthread.php?680130-Correct-way-to-use-the-BackgroundWorker
Declare a variable outside the sub that stores what label should be flipped when the timer ends.
Label click sets
storedLabel = sender
Timer tick sets storedLabel.ForeColor = Color.DarkRed

How to test that agent is running In Debug?

Is there a way to know that an agent in running in debug mode (Tools/Debug LotusScript has been activated) ?
I found nothing in NotesAgent class, something like RunOnServer but RunInDebugger.
I need this to avoid using the progress bar function located in NNOTESWS.DLL, which pops over the debugger and prohib any click (step into, or watching variables). BTW if it occurs to someone you still can press F8 / F5, this help at least not to kill Notes.
There Is a very good example for doing this in OpenNTF. You can find it here.
And in fact it IS for the progress bar, so you can use tho whole class from there.
The trick is: you add a function with a stop statement. You measure the time before the stop statement and after. If the time passed is bigger than 100ms, than a user had to click on "continue", what he never manages to do in such a small amount of time. If debugger is not enabled, the stop is ignored - no delay...
Here is the function used in the linked openntf article:
Public Function IsDebugMode() As Boolean
Dim start As Variant
start = Getthreadinfo(6) ' LSI_THREAD_TICKS
Stop
If Getthreadinfo(6) - start > 100 Then IsDebugMode = True
' If you debug the application you will not be able to press the CONTINUE-Buton
' within less then 100 milliseconds, otherwise the STOP-statement is not in function
' and you will always be quicker then 100 milliseconds
End Function
Although the comment is in fact wrong (100 tics are not 100ms, you would have to devide by ticks per second to get that value), the code still works and does exactly what you want.

Visual Basic form .close() method

I have the below snippet of code:
'Handle level specific properties
Select Case ScoreCard.CurrentDifficulty
Case 1
intImageCount = 2 'This is the number of images to show at any given time on screen +1
'debug
ScoreCard.CurrentDifficulty = 6
Case 2
intImageCount = 3 'This is the number of images to show at any given time on screen +1
Case 3
intImageCount = 5 'This is the number of images to show at any given time on screen +1
Case 4
intImageCount = 2 'This is the number of images to show at any given time on screen +1
Case 5
intImageCount = 5 'This is the number of images to show at any given time on screen +1
Case 6
frmLevel3_HouseOfMirrors.Show()
Me.Close()
Return
End Select
When case 6 is executed frm3_HouseOfMirrors.Show() executes and my new form opens. Me.close executes as well but my problem is that the script then gets to the return line. Isn't me.Close() suppose to stop all execution of code on the current form and unload its self from memory?
Just call frmLvl3_HouseOfMirrors.ShowDialog() instead of .Show(), this will stop the execution of code until the new form is closed.
Or if you want to cancel the execution of the rest of code try the Exit instruction. You have to detect you want to finish and add it outside this Sub, because .Close() didnt stop the execution of code.
No, the "close" method just closes the form, but the program execution will continue. If you want to stop code execution until a form is closed, you could make it modal.
In VBA it would look like this:
frmLevel3_HouseOfMirrors.Show vbModal
Isn't me.Close() suppose to stop all execution of code on the current form and unload its self from memory?
No. Close does exactly what it says: it closes the visual, interactive representation of the form.1 It doesn’t affect code execution directly. It does make sure that Form_Closing and then Form_Closed are called, however. But the rest of the code execution is unaffected; in particular, the current method runs through normally. After that, other methods on the form may or may not be called as necessary (and, as mentioned, Closing and Closed will be called).
1 And, yes, it releases the form’s resources unless the form was shown via ShowDialog rather than plain Show.