I am sending mail using outlook, on send event I am trying to display message, but msgbox is not getting displayed till I clicked on screen( anywhere).
(Once user click on Send in Outlook, I am changing the Outlook windowState to minimize.)
Public Sub oApp_ItemSend(ByVal Item As Object, Cancel As Boolean)
If(StrComp(clickedEvent, "ClickMe", vbTextCompare) = 0) Then
MsgBox "HI"
end if
End sub
Thanks
This is a known issue with several MS Office applications. Try adding this code and see if it helps:
AppActivate Application.Caption
or
AppActivate "Microsoft Excel" ' name of application that needs to be in focus
From the documentation:
The AppActivate statement changes the focus to the named
application or window but does not affect whether it is maximized or
minimized.
Related
I have a form Overview with a table that gets its data from a database. I would like to add a line to that database and update my table in Overview. I created a button in Overview which opens another form InputForm (that pops up in front of Overview). In VBA, I wrote some code that adds the data to the database using a query and then closes InputForm. When InputForm closes, Overview becomes visible again. Now, I would like to see the table in Overview updated with the new data. The problem is that it only updates when I click another button in Overview or when I close and reopen the form.
I tried the GotFocus, Activate, Click... events to Refresh the form but I guess that the form does not lose focus or is not deactivated when InputForm is opened so these events of course never happen. I also tried to Refresh Overview from within the InputForm. I also tried to find the Activate or Deactivate functions but they appear nowhere. I honestly don't know how to update the table in the Overview form.
EDIT:
Overview
Private Sub btnOpenInputForm_Click()
DoCmd.OpenForm FormName:="InputForm", OpenArgs:=0 & "," & 0
End Sub
InputForm
Private Sub btnAddRecord_Click()
'Read data from the input fields
'CurrentDb.Execute "INSERT..."
DoCmd.Close
End Sub
If I understand correctly, then your form named Overview is bound to the same table which will be a record added to by a button which also is on that form.
So the code to add the new record runs in the Click event of that button, right?
So then you would have to call Me.Requery after adding the record (The Me keyword is a reference to the form in that case).
Edit:
Regarding your new information I added this, showing how to call your InputForm as a modal dialog and read out the values in case the user didn't cancel it.
This would be your calling procedure:
Private Sub btnOpenInputForm_Click()
Const INPUT_FORM_NAME As String = "InputForm"
'Call the form as a modal dialog
DoCmd.OpenForm FormName:=INPUT_FORM_NAME, OpenArgs:=0 & "," & 0, WindowMode:=acDialog
'If the user cancelled the dialog, it is not loaded any more.
'So exit the sub (or maybe do some other stuff)
If Not CurrentProject.AllForms(INPUT_FORM_NAME).IsLoaded Then
Debug.Print "The user cancelled the dialog"
Exit Sub
End If
'You can now check a value in the dialog
If IsNull(Forms(INPUT_FORM_NAME).MyTextBox.Value) Then
Debug.Print "Null in the control"
Exit Sub
End If
'Or read a value into a variable
Dim myVariable As String
myVariable = Forms(INPUT_FORM_NAME).MyTextBox.Value
'Close the dialog form now
DoCmd.Close A_FORM, INPUT_FORM_NAME
'Build and execute your sql here, like you already did in the dialog form before
'CurrentDb.Execute "INSERT..."
Debug.Print "User entered: ", myVariable
'And finally requery the form
Me.Requery
End Sub
In the dialog form ("InputForm")
the Click procedure of the OK-button has to call Me.Visible = False to just hide the dialog.
the Click procedure of the Cancel-button has to call DoCmd.Close acForm, Me.Name to close the dialog.
I see this code all over the internet and everyone says how wonderful it works but it doesn't for me, I'm clueless, any ideas why?
I have Windows 7 and Outlook 2010.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim strSubject As String
strSubject = Item.Subject
If Len(Trim(strSubject)) = 0 Then
Prompt$ = "Subject is Empty. Are you sure you want to send the Mail?"
If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check for Subject") = vbNo Then
Cancel = True
End If
End If
End Sub
Please ensure you have set the correct references in your project for Outlook 2010 Library. Also ensure that Outlook 2010 should already be in running state. Thanks
you posted a link to a screen capture on May 20 at 16:04
go to that same place in the code and delete all the code in the sub, including sub and endsub (the code that you posted)
now click on "application" dropdown at top-left
you should see the following fill in
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
End Sub
if something else pops up, then click on ItemSend in dropdown on top right
put in one command to get this very minimal sub (if it does not work, then nothing else will)
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
msgbox "this works"
End Sub
now send any email, if it works then you should see a dialog box pop up
note: i have found that "just pasting in code" does not always work and you have to click on the dropdown menus, after you paste in the code, to get the sub to be registered
When showing a userform (running its Show method) it not only shows up on the screen but also takes the focus (the destination of e.g. keystrokes).
Say, the userform is a custom made toolbar. Its Show fires in Workbook_Open() but the form itself is used relatively rarely so we want the focus to go back to the main application window right after its appearance.
Unfortunately, it seems SetFocus method is not valid for application objects.
So how is this done?
I suppose the solution for my example comes after
Private Sub Workbook_Open()
[...]
UserForm1.Show
i use this one :
AppActivate Application.caption
this resets the focus from a userform to your Excel Sheet.
For me
AppActivate ThisWorkbook.Application
right after the Show statement seems to work fine.
In other cases
AppActivate "Microsoft Excel"
may also be ok.
This is a bit tricky, but this is what can do.
In the subroutine “Private Sub UserForm_Initialize()”, add this as the last line:
Private Sub UserForm_Initialize()
. . . . . . . . . .
Application.OnTime Now(), "MoveFocusToWorksheet"
End Sub
In any of the general code modules (add one if you have none), declare an API function:
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
In any of the general code modules (could be the one with the API declaration, of course), add this subroutine:
Public Sub MoveFocusToWorksheet()
Dim Dummy As Long
ThisWorkbook.Worksheets("Sheet1").Activate
' "Sheet1" here is the tab name of the sheet you want to move focus to. _
Or simply use then: With shtABC.Activate _
where "shtABC" being the worksheet's CodeName, _
same as ThisWorkbook.Worksheets("Sheet1").CodeName, _
same as the sheets module name showing in the Project Explorer panel.
Dummy = SetForegroundWindow(Application.hwnd)
End Sub
Both AppActivate Application.Caption and (the better) AppActivate ActiveWindow.Caption mentioned in the other answers do their job in focusing back on the application window itself ... but they do NOT focus on the actual cell/range where one typically wants the focus to be. For that, use:
ActiveCell.Activate
which has the benefit of not requiring an additional click on the cell area of the sheet where you want to return focus - an additional click that can potentially change the previous selection.
I create an object for the application e.g. Outlook, then change the WindowSate to Maximised (OlMaximized), then when I want to remove focus I minimise (olMinimized)
Set OutlookObj = GetObject(, "Outlook.Application")
OutlookObj.ActiveExplorer.WindowState = olMinimized
OutlookObj.ActiveExplorer.WindowState = olMaximized
Or you change the state from inside the application, you can also change its location and size etc for more info see: https://msdn.microsoft.com/en-us/library/office/ff838577.aspx
Application.WindowState = xlMaximized
An other form is:
AppActivate ThisWorkbook.Name
I use
AppActivate ActiveWindow.Caption
because
AppActivate Application.Caption
can focus the wrong window if multiple windows are opened for the same workbook.
As a footnote to this excellent discussion, in some circumstances you may avoid the focus problem by skipping the call to .Show, so the focus never moves in the first place. For example with Word, if you are updating a modeless form or dialog box, just update the required area and omit the call to .Show, e.g.:
Sub ShowProblems(ByVal ProbLoc)
EditBox2.TextBox.Text = "Here is the problem location: " & ProbLoc
' not needed: EditBox2.Show vbModeless
End Sub
Private Sub UserForm_Activate()
RefRangeIn.SetFocus
End Sub
it work for me, in excel 2013 VBA
Add a dummy form and add codes as below:
Private Sub SomeButton_Click()
frm_Dummy.Show vbModeless
Unload frm_Dummy
End Sub
OR
Sub SomeSub()
frm_Some.Show vbModeless
frm_Dummy.Show vbModeless
Unload frm_Dummy
End Sub
I created a floating menu with a user form and use this code to make my cursor leave the user form and jump/focus back to my worksheet. It works at the end of each command button code and with the initiation code of the user form as well.
AppActivate ThisWorkbook.Application
Just place the above line of code before the "End Sub" line of any command button code and the initial show userform code.
I have been searching the internet for this all day. But no luck.
Can you setup events for when you enter/leave a tab.
I.E.
OnExit(Tab1)
Do something
Thanks
Depending on your program flow, you might try:
Private Sub Combo3_Exit(Cancel As Integer)
If IsNull(Me.Combo3) Then
MsgBox "No exit"
Cancel = True
End If
End Sub
Private Sub Form_Current()
Me.Combo3.SetFocus
''Or to refer to a subform from the main form
Me.subformcontrolname.Form.Combo3.SetFocus
End Sub
Does the tab contain a subform or only controls from the main form?
A subform has an Exit event, so if you are only concerned that once you have entered the subform you should not leave without completing data, you could:
Private Sub subformcontrolname_Exit(Cancel As Integer)
If IsNull(Me.subformcontrolname.Form.Combo3) Then
Me.subformcontrolname.Form.Combo3.SetFocus
MsgBox "No exit"
Cancel = True
End If
End Sub
While this is not exactly what you want, you could instead of handling the exit simply prevent the user from clicking somewhere else. To do this, attach some code to your combobox1 that bascially set .Enabled=Xfor all elements outside your tab view - where X is determined by the state of the combobox...
Using VBA in Excel 2003, I'm trying to cancel an Application.OnTime event using the following code:
Application.OnTime EarliestTime:=varNextRunTime, Procedure:="SomeMethod", Schedule:=False
where varNextRunTime is a global variable containing the next time it is due to run. This code runs in the Workbook_BeforeClose event handler so is always run when the workbook is closed, which is my intention.
However, if the user tries to close the workbook, but changes their mind and hits the cancel button when prompted to Save (Yes, No, Cancel), the Application.OnTime event is still cancelled. BeforeClose is always run before they decide to hit cancel, so has anyone got any ideas how I can only cancel the Application.OnTime event when the workbook is closed?
Here's some ideas
http://www.dailydoseofexcel.com/archives/2004/06/16/beforeclose-vs-beforereallyclose/
Check the Saved property of the Workbook in your event handler. If the workbook is unsaved then display your own dialog to find out if the users wants to save changes, not save changes or cancel.
Here's some rough code. Obviously uncomment the line which deals with the Application.OnTime part and change the MsgBox title to something suitable
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim response As Integer
If Not (Me.Saved) Then
response = MsgBox("Do you want to save changes to '" & Me.Name & "'?", vbYesNoCancel, "put title here")
If (response = vbCancel) Then
Cancel = True
ElseIf (response = vbYes) Then
Me.Save
End If
End If
If Not (Cancel) Then
' Application.OnTime EarliestTime:=varNextRunTime, Procedure:="SomeMethod", Schedule:=False
End If
End Sub
Investigate using:
Application.Quit
If you find this command results in the Excel program remaining open although the document has closed, you may want to follow with
ActiveWorkbook.Close False
I'm not in position to test this or give more insights, unfortunately.
A bit late to the show but here is a simple solution that I've come across (and tested):
If a user deactivates the workbook by closing it, the workbook will still remain the ActiveWorkbook when the Workbook_WindowDeactivate event fires. If the user deactivates the workbook by switching to another workbook, then the new workbook will become the ActiveWorkbook by the time Workbook_WindowDeactivate fires. You can use this behavior to determine the action that caused the event to fire:
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
If Application.ActiveWorkbook.Name = Me.Name Then
'Your code here
End If
End Sub