msgbox that disappears automatically after certain time - vb.net

Is there any type of msgbox in vb.net that gives a message and it disappears automatically after a certain time?
Or is there any method to hide the msgbox, without user's clicking OK?

You Can use
CreateObject("WScript.Shell").Popup("Welcome", 1, "Title")
this msgbox will close automatically after 1 second

No, I don't think there's a built-in framework control that will do this for you. However, you could easily do this with a custom-built form that fires a timer in it's Load event. Then, when the set amount of time has passed, in the timer Elapsed event, you can simply close the form.

Linendra Soni's answer is good, but it may or may not work in the newer versions of Windows and/or Excel.
This works perfectly in the newer versions:
Function MessageTimeOut(sMessage As String, sTitle As String, iSeconds As Integer) As Boolean
Dim Shell
Set Shell = CreateObject("WScript.Shell")
Shell.Run "mshta.exe vbscript:close(CreateObject(""WScript.shell"").Popup(""" & sMessage & """," & iSeconds & ",""" & sTitle & """))"
MessageTimeOut = True
End Function
Use it like this:
Sub Example()
Dim chk As Boolean
chk = MessageTimeOut("Hello!", "Example Sub", 1) 'if chk returned FALSE that means the function was not executed successfully
End Sub
or
Sub Example()
Call MessageTimeOut("Hello!", "Example Sub", 1) 'you don't need to get the output of the function
End Sub
Output:

Use a timer or some type of delay/sleep and after time expires run
SendKeys.Send("~")
This is the same has hitting the ENTER key.
You may need to make it proceed it by activating the msgbox window again.

Inspired by the answers, this is what I came with, working nicely in simple cases, allowing to use all MsgBox features directly:
Imports System.Threading
Module FormUtils
Private sAutoClosed As Boolean
Private Sub CloseMsgBoxDelay(ByVal data As Object)
System.Threading.Thread.Sleep(CInt(data))
SendKeys.SendWait("~")
sAutoClosed = True
End Sub
Public Function MsgBoxDelayClose(prompt As Object, ByVal delay As Integer, Optional delayedResult As MsgBoxResult = MsgBoxResult.Ok, Optional buttons As MsgBoxStyle = MsgBoxStyle.ApplicationModal, Optional title As Object = Nothing) As MsgBoxResult
Dim t As Thread
If delay > 0 Then
sAutoClosed = False
t = New Thread(AddressOf CloseMsgBoxDelay)
t.Start(delay)
MsgBoxDelayClose = MsgBox(prompt, buttons, title)
If sAutoClosed Then
MsgBoxDelayClose = delayedResult
Else
t.Abort()
End If
Else
MsgBoxDelayClose = MsgBox(prompt, buttons, title)
End If
End Function
End Module
PS: You must add this to yourApp.config file:
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>

I dont think there is a tool such as that. But I think you can do that with follow this steps;
Create an instance of Form element, and design it like a messagebox.
In Form load event, get the system time or start the timer with interval value.
This timer tick how many seconds you want then call the Form Close event.
P.S : If I'm wrong, I'm sorry. I only try to solve something, maybe there is a better way to solve your problem.

You can do this by adding a Timer to your form.
'Timer to autoclose after 100 ms
Dim seconds As Integer = 100
'Existing code....
Timer1.Start()
MessageBox.Show("Window Timed Out", "TimeOut")
Me.Close()
'Tick Event Code
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
seconds = seconds - 1
If seconds < 1 Then`
Me.Close()
End If
End Sub

I have some code to show file updated time and close message box within 3 sec.
Please see below.
I hope that this code can support this topic.
Sub Workbook_Open()
Application.ScreenUpdating = False
SplashUserForm.Show
Windows(ThisWorkbook.Name).Visible = True
Application.ScreenUpdating = True
last_update = "Last updated : " & Format(FileDateTime(ThisWorkbook.FullName), "ddd dd/mm/yy hh:mm ampm")
'Close message after time if no action!
Dim myTimedBox As Object
Dim boxTime%, myExpired%, myOK%, myQuestBox%
'Access timed message box.
Set myTimedBox = CreateObject("WScript.Shell")
boxTime = 3
'User Selected "OK."
If myQuestBox = 1 Then
'Add any code in place of code below for this condition!
myOK = myTimedBox.Popup(last_update & vbCr & "Do nothing and this message will close in 3 seconds.", _
boxTime, "You Took Action!", vbOKOnly)
Else
'User took no Action!
myExpired = myTimedBox.Popup(last_update & vbCr & "Do nothing and this message will close in 3 seconds.", _
boxTime, "No Action Taken!", vbOKOnly)
End If
End Sub

This is the way
http://www.vbforums.com/showpost.php?p=3745046&postcount=5

Related

Access VBA Preventing form record entry on close

I am working with Access Database VBA.
I have noticed if a user has filled a few of the text boxes in and then clicks the windows close button, the form logs that into the records.
I am wondering what is the best way to prevent the form from entering the uncompleted record on close?
There were a few sites pointing to placing a code in the beforeupdate function.
This is what I have tried.
Private Sub frmRecLog_BeforeUpdate(Cancel As Integer)
DoCmd.SetWarnings False
Me.Undo
Cancel = True
Exit Sub
End Sub
This code does not work at all for me.. I tried my best, haha.
Anything helps.
So, what you need is to insert a command button Save. If user do not hit on Save then it will not save any records. They will get a warning that data is not saved. You need declare a private boolean variable and write codes to save and warning. So full code will be like below.
Option Compare Database
Option Explicit
Private blnSaveRecord As Boolean
Private Sub cmdSave_Click()
blnSaveRecord = True
DoCmd.RunCommand (acCmdSaveRecord)
blnSaveRecord = False
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim strMsg As String
If Not blnSaveRecord Then
Cancel = True
strMsg = "Please save the record.," & _
vbNewLine & "or press ESC from keyboard to cancel the operation."
Call MsgBox(strMsg, vbInformation, "Save Record")
'Me.Undo 'You can set undo option here if you do not want to press ESC.
End If
End Sub

Can you have a run-time window instead of a MsgBox for output?

The code I currently works as follows: I type in a UID and then a message box shows the slack of a task. However, it's not possible to edit the Microsoft Project file while the message box is open.
Is there another object I can use in VBA to show the same output but allow me to work on the project file while having the output out? And, is it possible to have the output be in real time? In other words, if I make changes in my schedule, can I see the output constantly change if the slack changes as I make changes without having to run the application again?
Sub SlackFinder()
Dim User_UID, User_ID As Integer
Dim Slack As Variant
Dim NewSlack As Variant
User_UID = InputBox("Enter UID for slack:")
If User_UID = "" Then Exit Sub
On Error GoTo Error_Not_Found
User_ID = ActiveProject.Tasks.UniqueID(User_UID).ID
On Error GoTo Error_Collapsed
Slack = ActiveProject.Tasks.UniqueID(User_UID).TotalSlack
NewSlack = Slack / 480
MsgBox "Total Slack: " & NewSlack
Exit Sub
Error_Not_Found:
MsgBox "UID " & User_UID & " not found in " & ActiveProject.Name
Exit Sub
Error_Collapsed:
MsgBox "UID is present but cannot be selected. Perhaps it is collapsed?", vbOKOnly, "COLLAPSED UID?"
Exit Sub
End Sub
You can show real-time slack using a modeless userform. Create a userform in VBA, for example something that has a textbox for entering the task UID and a label to display the Total Slack value:
Then add this code to the UserForm module:
Private Sub UID_Change()
UpdateTotalSlack
End Sub
Sub UpdateTotalSlack()
On Error Resume Next
Me.TSlack = "Total Slack = " & ActiveProject.Tasks.UniqueID(Me.UID).TotalSlack / 480
End Sub
Add this to the Project module:
Sub ShowSlack()
UserForm1.Show False
End Sub
Private Sub Project_Change(ByVal pj As Project)
UserForm1.UpdateTotalSlack
End Sub
To start, call the ShowSlack procedure. This shows the user form modelessly (e.g. it floats above the MS Project window, allowing you to make changes in the schedule). Enter a Task UID in the textbox and the Total Slack will be displayed immediately and updated whenever changes are made to the schedule (thanks to the Change event code).
Project Module:
Private Sub Project_Change(ByVal pj As Project)
MsgBox "hi"
UserForm10.UpdateTotalSlack
End Sub
Module 29:
Sub ShowSlack()
UserForm10.Show False
End Sub
Userform10:
Dim User_UID As Variant
Dim TSlack As Variant
Private Sub TextBox3_Change()
User_UID = UserForm10.TextBox3.Value
UpdateTotalSlack
End Sub
Sub UpdateTotalSlack()
On Error Resume Next
If Not User_UID = "" Then
TSlack = ActiveProject.Tasks.UniqueID(User_UID).TotalSlack / 480
Else
TSlack = ""
End If
UserForm10.Label1.Caption = TSlack
End Sub

Excel VBA Keep Userform Timer running when Userform or Excel are closed

Recently I've managed to find some code regarding a timer on a userform, my problem is that I need to keep the timer running even if the userform or excel file is closed... can someone take a look at the code and provide some feedback? My userform is: optionsForm
Dim dteStart As Date, dteFinish As Date
Dim dteStopped As Date, dteElapsed As Date
Dim boolStopPressed As Boolean, boolResetPressed As Boolean
Private Sub Reset_Timer_Click()
dteStopped = 0
dteStart = 0
dteElapsed = 0
Tech_Timer = "00:00:00"
boolResetPressed = True
End Sub
Private Sub Start_Timer_Click()
Start_Timer:
dteStart = Time
boolStopPressed = False
boolResetPressed = False
Timer_Loop:
DoEvents
dteFinish = Time
dteElapsed = dteFinish - dteStart + dteStopped
If Not boolStopPressed = True Then
Tech_Timer = dteElapsed
If boolResetPressed = True Then GoTo Start_Timer
GoTo Timer_Loop
Else
Exit Sub
End If
End Sub
Private Sub Stop_Timer_Click()
boolStopPressed = True
dteStopped = dteElapsed
End Sub
Private Sub optionsForm_Initialize()
Tech_Timer = "00:00:00"
End Sub
The idea of the timer is not that it runs, but that it remembers a point in time and can give you a difference between this point and the current moment. If you ask for this difference every second, then it would look like it is running like a watch.
Something like this would be a good start. In the xl_main write the following:
Option Explicit
Dim dtime As Date
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Cells(1, 1).Value = dtime
End Sub
Private Sub Workbook_Open()
If Cells(1, 1).Value = 0 Then
dtime = Now
Else
dtime = CDate(Cells(1, 1))
End If
End Sub
You may play around it and make it better as you wish. E.g. you may find a way to reset dtime or anything similar.
"Something" needs to be running to handle the timer procedure so if you want to use VBA then Excel can't be "closed" per se, however you could make it appear closed.
An obvious option is to minimize the Excel window (before showing the userform) with the WindowState property:
Application.WindowState = xlMinimized
...or, hide the Excel window completely with the Visible property:
Application.Visible = False
...or if the issue is that you need a "fresh" copy of Excel to work in, you could do so in a new instance by holding Alt while starting Excel.
            
I have posted code and a downloadable example of a countdown timer that displays the time remaining on a userform semi-independent of the Excel window, using the Windows Timer API (instead of Excel's procedure), in another answer here.
                   
That's not possible if the form is unloaded Unload optionsForm. But you can try to 'close' the form with optionsForm.hide() this only hides the form, the timer should keep running then.
The only way I see to calculate the time passed from a start time even if Excel is closed is to not save the start time in a variable dteStart but in an Excel cell.
Actually you can use a code that is placed in a module. The code is:
Option Explicit
Dim T
Sub stopTimer()
On Error Resume Next
Application.OnTime (T), Procedure:="Update", Schedule:=False
End Sub
Sub StartTimer()
T = Now + TimeValue("00:00:01")
Application.OnTime T, "Update"
End Sub
Sub Update()
UserForm1.TextBox1.Value = Format(Now - Sheets("Sheet1").Range("E11").Value,
"hh:mm:ss")
UserForm1.TextBox2.Value = Format(TimeValue("1:00:00") - (Now -
Sheets("Sheet1").Range("E11").Value), "hh:mm:ss")
Call StartTimer
End Sub
Thereafter, you can now reference it in the userform by calling it. Here is a typical example. It is
Private Sub Userform_Activate()
Sheet1.Activate
Sheets("Sheet1").Range("E11").Value = Now
Application.Run "StartTimer"
If Sheets("Sheet1").Range("K27").Value = "K29" Then
Me.CommandButton4.Caption = "Start"
Me.CommandButton2.Visible = False
End If
End Sub

Excel VBA ComboBox1_DropButtonClick Event

I got macro below which fires twice (showing same MessageBox twice). First when ComboBox1 opens and second when ComboBox1 closes.
Private Sub ComboBox1_DropButtonClick()
If Me.ComboBox2.Text = "" Then
MsgBox "Fill text box"
Else
'Do stuff
End If
End Sub
Is there any way to make it show MessageBox once. I want user to select the value in ComboBox1 first before clicking on ComboBox2 DropButton.
Here is a very unelegant work-around using a "count" variable that prompts the MsgBox only the first and not the second time.
Dim count As Integer
Private Sub ComboBox1_DropButtonClick()
count = count + 1
If Me.ComboBox2.Text = "" Then
If count = 1 Then
MsgBox "Fill text box"
Else
count = 0
End If
Else
'Do stuff
End If
End Sub
However, I highly suggest to use the ComboBox1_Change() event if it's not necessary to use the drop button one.
P.S.: the declaration of the "count" variable needs to stay out of the method. This is due to the fact that:
if it stays inside, it's a local variable of the method and so loses its modifications every time the method is ended;
if it stays outside, it will keep the modifications even once the method has ended its run.
I would do it using the combobox_enter event, but this only checks when the focus is switched
Private Sub ComboBox1_Change()
If ComboBox1.Text = "" Then
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenNever
Else
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenAlways
End If
End Sub
Private Sub ComboBox2_Enter()
If ComboBox1.Text = "" Then
MsgBox "Must first set value to combobox1"
ComboBox1.SetFocus
End If
End Sub
Private Sub UserForm_Initialize()
ComboBox1.AddItem "None", 0
ComboBox1.AddItem "Select Me", 1
ComboBox2.AddItem "None", 0
ComboBox2.AddItem "Select Me", 1
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenNever
End Sub
My code does some extra things that I just think look pretty, you really only need the _Enter function

VBA EventHandler firing twice?

I have MS Access 2003 DB.
Is it possible for an event handler for a button on a form to fire twice??
I seem to have evidence of this happening as I have a payroll process
that logs the whole process and process is duplicated in the log.
I didnt think this was possible in VBA???
EDIT:
I discovered that indeed it was firing twice as user was clicking twice and queueing the event twice.
This is the fix I made to the code which shows using a flag m_locked as an example to test with:
[code]
Private m_locked As Boolean
Private m_count As Integer
Private Sub Command0_Click()
On Error GoTo Err_Command0_Click
' wait
If Not m_locked Then
m_locked = True
Dim startTime As Date
startTime = Now()
While DateDiff("s", startTime, Now()) < 3
DoEvents
Wend
' increment counter
m_count = m_count + 1
Command0.Caption = m_count
m_locked = False
End If
Exit_Command0_Click:
Exit Sub
Err_Command0_Click:
MsgBox Err.Description
Resume Exit_Command0_Click
End Sub
[/code]
Malcolm
Seeing your "solution" I'ld recommend to specify the double click event, too. This will allow you to distinguish easily whether the user clicked once or twice by a "debug.print".
To prevent the user to perform an extra click, declare a private boolean variable on form module level, set it to TRUE in your event procedure, set it to FALSE in the timer event, and configure your form's timer to 1000 for example (it's milliseconds).
Option Explicit
Option Compare Database
Private oneClick As Boolean
Private Sub cmdMyButton_Click()
If not oneClick Then
' Perform your actions here
End If
oneClick = True
End Sub
Private Sub Form_Timer()
oneClick = False
End Sub
Oh, and please use variable and control names that tell their meaning :-)
If you do not want your user click the button twice just this simple code:
Private Sub Command0_Click()
Command0.Enabled = False
' Continue with your code here ...
End Sub