How to manage application options/advanced options? - vba

I need to quickly toggle File > Options > Advanced > Reminders > Play reminder sound setting.
In certain meetings I need to keep Outlook running to get reminders, but don't want the reminder sound.
Currently, I manually toggle the File > Options > Advanced > Reminders > Play reminder sound checkmark.
This needs to be an effective single-click.
I don't want to restart Outlook as there are usually many things open.
I cannot add it to the Quick Access Toolbar.
On the left the option is present in the list of QAT commands, but not in the list of Ribbon commands, otherwise we could access it with ExecuteMso.
Three reasons:
The button is disabled when not in the Calendar window. That's just inelegant.
When I click the button, Outlook crashes and I lose everything that wasn't saved. (Autosave isn't sufficient or functioning. That's a different problem.)
Understanding how to access Outlook settings with VBA opens a whole new world of possibilities.
This Microsoft article series starting at https://learn.microsoft.com/en-us/office/vba/outlook/concepts/getting-started/automating-outlook-from-a-visual-basic-application is about automating Outlook user tasks, like making a calendar appointment. That's not what I want, I want to manage Outlook's options.
There are some discussions about COM add-ins as one method, but that appears beyond me. The effort to learn COM add-ins is out of line with manual effort to achieve the desired goal.
I have some limited Outlook VBA experience but am reasonably comfortable with VBA in Word, Excel.

To disable reminder sound you need to set the below registry key to 0.
Registry key: PlaySound (REG_DWORD) to be set to 0.
Path: HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\options\Reminder
where 16.0 indicates the Outlook version.
Don't forget to restart Outlook to apply changes.

These settings can be overridden on the per appointment basis - you can simply set AppointmentItem.ReminderPlaySound property to false using VBA.

Simulate a button press with ExecuteMso.
https://learn.microsoft.com/en-us/office/vba/api/Office.CommandBars.ExecuteMso
Hover over the button where you would add it to the ribbon/QAT. See text in brackets at the end.
Are the command codes for ExecuteMso documented?
Private Sub ExecuteMso_TextInBrackets()
' https://learn.microsoft.com/en-us/office/vba/api/Office.CommandBars.ExecuteMso
' https://stackoverflow.com/questions/25610998/are-the-command-codes-for-executemso-documented
Dim oAppt As Object
Set oAppt = ActiveInspector.CurrentItem
Debug.Print oAppt.subject
ActiveInspector.CommandBars.ExecuteMso ("TextInBrackets")
End Sub

As with most things in life, the answer is a workaround. In this case, it's AutoHotkey to press the keys for me (ALT F, T, down x 9, ALT P, Enter):
;WIN-O toggles the Outlook alarm sound setting
#o::
SetTitleMatchMode,2 ;inexact match
WinGetActiveTitle, MyWindowTitle
If WinActive(" - email#company.com") ;Poor way to "prove" we're in Outlook
{
;MsgBox, We're in Outlook
Send !ft{Down 9}
Send !p{Enter}
}
Return

Related

Automatically Closing Outlook Windows via Script/Macro

I'm hoping someone on here can point me in the right direction with some expertise. I have a situation with a client's outlook where we need to close any open draft windows after a new message/draft is opened. Ideally after the 4th new window has opened.
Any "new message" window that opens after this we need the script to close 1st window that opened. Either killing the process, or something similar.
Recently have been looking into Outlook macros, but am unsure if they will help in this instance. (Maybe they are?). Being more familiar with Powershell, figured we could start there.
Looking to get help writing a powershell script, macro, etc to do this on the backend.
The Outlook object model provides all the required events, methods and properties for that. So, VBA macros is the right choice if you don't need to distribute the solution on multiple machines. Otherwise, you need to consider developing a COM add-in instead (for example, a VSTO based one should work for you). See Walkthrough: Create your first VSTO Add-in for Outlook for more information.
You can handle the NewInspector event which is fired whenever a new inspector window is opened, either as a result of user action or through program code. The event occurs after the new Inspector object is created but before the inspector window appears.
You can also check the number of opened inspector windows in Outlook by using the Inspectors.Count property which returns a long indicating the count of objects in the specified collection.
Finally, the Inspector.Close method closes the Inspector and optionally saves changes to the displayed Outlook item. For example, a VBA sample which closes the active inspector instance:
Sub CloseItem()
Dim myinspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Set myinspector = Application.ActiveInspector
Set myItem = myinspector.CurrentItem
myItem.Close olSave
End Sub

Purge an IMAP folder in Outlook 2016 using VBA

In Outlook 2016 I have connected an IMAP folder. Outlook is configured to mark items as deleted in IMAP folders. This is necessary because I want to process those items, that are marked for deletion seperately. After my macro is completed, that IMAP folder should be purged automatically.
In Outlook there is the ribbon "Folder" with the group "purge". In there is the menu "delete" with an menu item to purge the current folder. I can't find a way to execute the function from a VBA macro.
For Outlook 2010 there is this solution:
http://www.vboffice.net/en/developers/purge-deleted-imap-messages/
In Outlook 2016, the findControl method does not find the required control.
Is there any way to purge that folder?
Best solution would be some kind of API function.
Second best would be to simulate a click event on the control of the ribbon. "CommandBars" seems to contain some sort of context menus but not the ribbon controls.
Is it possible to define custom commandbars with standard controls in it? The control id seams to be still "12771".
I very briefly looked into the UI Automation toolkit but have found no good example of how to access the ribbon of a specific application.
Alternatively: can I get access to controls of the quick access toolbar? Adding the correct purge folder control to the quick access toolbar would rely on the user to click on that button at the right moment.
For buttons you can add to a ribbon or the QAT, the idMso can be seen at the end of the text when hovering over the command.
Sub PurgeFolder_Button_idMso()
' For buttons you can add to a ribbon or the QAT,
' the idMso can be seen at the end of the text when hovering over the command.
ActiveExplorer.CommandBars.ExecuteMso ("PurgeFolder")
End Sub

Add Microsoft Teams to Outlook Meeting Request

I have code that creates an outlook meeting request and it is working great. I want to be able to make this meeting request a Microsoft Teams Meeting. I cannot find any notes online on the objects to use for this and cannot find any objects in Outlook VBA that look like they will work. Does anyone know how to programmatically add Microsoft Teams to a meeting request?
The easiest way to run the command on the ribbon programmatically. You just need to know the idMso value of the built-in command. The ExecuteMso method of the CoommandBars class is useful in cases where there is no object model for a particular command. Works on controls that are built-in buttons, toggleButtons, and splitButtons. On failure, it returns E_InvalidArg for an invalid idMso, and E_Fail for controls that are not enabled or not visible.
But we deal with an add-in, so their idMso values are not disclosed. In that case your option is to use Accessibility API, see Microsoft Active Accessibility for more information. Microsoft Active Accessibility is a Component Object Model (COM)-based technology that improves the way accessibility aids work with applications running on Microsoft Windows. It provides dynamic-link libraries that are incorporated into the operating system as well as a COM interface and API elements that provide reliable methods for exposing information about UI elements.
As the last resort, you may consider using Windows API function to click the button programmatically.
P.S. You may find the Are the command codes for ExecuteMso documented? page helpful.
You can use this code
Sub teammetting()
Dim nm As Outlook.AppointmentItem
Set nm = Application.CreateItem(olAppointmentItem)
nm.MeetingStatus = olMeeting
nm.Subject = "Subject"
nm.Start = 'format:DD/MM/YYYY HH:MM:SS AM/PM
nm.End =""'format:DD/MM/YYYY HH:MM:SS AM/PM
nm.requiredattendees "mail address of the invitees"
nm.Body = "Set the body of the email"
'Show the meeting
nm.Display
SendKeys "{F10}", True
'Switch to ribbon shortcuts
SendKeys "H", True
'Hit the Microsoft teams meetings button, requires teams to be installed
SendKeys "TM", True
'Now to add signature: Switch to meeting location button
end sub
'use this code and try as there isn't any note of objects or

Attaching VBA Form to Outlook Application

I'm creating a custom form for appointments in Outlook for a project (add catering request to a meeting) - this is my first rodeo at doing this - and I'm striking out big time regardless of my intense (and failing) Google-Fu.
With a new appointment open, on the developer tab, I select "Design This Form". I go to tab "(P.2)" and build a stupid-simple, two-object form... CheckBox1 and TextBox1. In properties, TextBox1.Visible is False. Click View Code and input the following...
Private Sub CheckBox1_Click()
if CheckBox1.value=True Then
Me.TextBox1.Visible = True
Else Me.TextBox1.Visible = False
End If
End sub
I then click "Run This Form" and see/click CheckBox1 but nothing happens. If I could make this run, I might be in business. But it won't. So, I look for a work-around.
Grasping at straws, I open "Visual Basic" and basically do the same thing - create a form "UserForm1" with the same two objects and add the same code. Click the go-button and it works as expected. The TextBox1 appears and disappears with the CheckBox1 state.
As I can make the code function, I would build everything I need in the Visual Basic editor, however... Here's the problem - I have absolutely no idea how to get the form I create here into the Outlook application as a tab or button or whatever. I basically want the custom form VBA editor to be a selectable option in any Appointment.
I have watched tutorials, read doc, saw something about creating a macro - but nothing was written/stated dumbed-down enough for me to follow.
So my question: How do I get the UserForm1 that's built in VBA Editor to appear in a New Appointment when a button is clicked in Outlook?
You need to add the Click event handler for the CheckBox control, not just paste the code to your custom form.
Following the June 13 2017 security update, users discovered published custom forms no longer worked because VBScript behind the form and some controls are blocked by default. See Custom Form Security Changes and Custom form script is now disabled by default for more information.
Microsoft disabled custom form script functionality. If you need it enabled, you'll need to set two keys, one to enable scripting and a second one with the message class name of each form that has code behind it. For example:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Outlook\Security
DWORD: DisableCustomFormItemScript
Value: 0 (to enable)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Outlook\Forms\TrustedFormScriptList
REG_SZ: IPM.Contact.custom-form-name
Value: (leave blank)
In some cases, forms in secondary mailboxes and Public folders still don't work after the registry key settings. To fix this, enable scripts in the Trust Center:
Click File > Options. Then select Trust Center > Trust Center Settings > Email Security.
Under the Script in Folders section, click the checkbox for Allow script in shared folders and Allow script in Public folders and click OK and OK again to close out the windows.

Word Add-in - find if dialog has focus?

I am writing a word add-in in VB .NET (using Add-in Express, but I don't think that's relevant).
I have created shortcuts, but I only want them to take effect if the document itself is in focus, not a dialog - for example, "Find and replace" or any other.
How do I determine if a dialog has focus?
The "Selection" property of the application points to the selection in the document, even if a dialog is currently selected. I can't find any "HasFocus"-equivalent property anywhere either. I'm running out of ideas :o)
Thanks!
This workaround worked for me:
My add-in keeps a reference to the handle of the most recently activated Word window, by using the GetActiveWindow API during the WindowActivate event of the Word application. This is necessary since, up until Office 2013, the Window object does not expose a handle property.
When a shortcut is triggered, I compare that to the handle of the currently active window, using the same API. If they don't match, I simply don't proceed :o)