How to prevent saving of Outlook.AppointmentItem in case some rules are broken defined by Outlook Plugin - vsto

I want to write an OutlookPlugin which prevents the user from saving / updating an AppointmentItem in case the title is shorter than n characters.
I can handly the updateEvent (Item_Change) event. But it does not prevent Outlook from finally saving the title anyways.
Any ideas?

Try hooking into the AppointmentItem.Write event. You can set the Cancel argument to false to prevent the changes from being saved.

Related

How to ask for confirmation before allowing a Word document to close?

I work with 2 different keyboard layouts (qwerty and azerty), and am constantly switching between the two using Alt-Shift. Sometimes when I reach for Ctrl-Z to undo, I get instead Ctrl-W which closes the document. Generally speaking I would in these situations get a Save Prompt, which would alert me to my mistake. However, I am now using OneDrive, with Autosave on the documents I'm working on. As a result, there is never this save prompt. The document is instantly closed and, worse, the undo that I was trying to effect is no longer present when the document is re-opened.
I would like to use VBA attached to the Normal Template, such that, on closing any document created with the VBA template, I will check to see if Autosave is turned on, and if it is, confirm before closing with a messagebox.
Obviously if the user doesn't confirm (e.g. chooses Cancel) then the document should not be closed.
Initially I put my code on Document_Close, but soon realised that here it's too late to Cancel the close. This is no good to me.
Then, based on some online code, I put my code in a class module (EventClassModule). In the ThisDocument module, I initiate the class, and activate the event handler.
My code doesn't ever seem to run, or in anycase, breakpoints don't kick in.
I'm a little unsure of where Normal stops and my normal document begins...
In ThisDocument of Normal Template, I have this VBA
Dim X As New EventClassModule
Sub Register_Event_Handler()
Set X.App = Word.Application
End Sub
Private Sub Document_Open()
Register_Event_Handler
End Sub
And I have a class module called EventClassModule with the following
Public WithEvents App As Word.Application
Private Sub App_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
Dim res As VbMsgBoxResult
If Me.AutoSaveOn Then
res = MsgBox("OK to Confirm", vbOKCancel, "Closing Document")
If res = vbCancel Then
Cancel = True
End If
End If
End Sub
I would like a prompt to confirm saving, any time a document is closed and the autosave option is turned off.
The Document_Open event handler will only fire if the Normal template is opened via File | Open. To get code to respond when starting Word you need to use an AutoExec routine. Simply rename your routine as below. You can find further info on Auto macros here
Public Sub AutoExec()
Register_Event_Handler
End Sub
Here is an easy way, include a method like this:
Public Sub DocClose()
' Disables Ctrl + W (but not other close methods, e.g. Alt + F4, menus, [X])
' Your code here:
ActiveDocument.Close
End Sub
Basically there are some method names that are used internally by MS-Word, and if you include them in your code they will prevent the default action. If you leave the sub empty it will effectively disable Ctrl + W.
See here for more information: Reserved method names in MS Word VBA
Advantage 1 of this technique
If you use Public WithEvents App As Word.Application and your project gets reset for any reason, and fails to restart... App will be Nothing and none of the events will fire.
Advantage 2 of this technique
On the occasions that you actually want to close a document... with this technique you wont get bugged by a (soon to become) annoying confirmation message - just sayin ;-)

Setting Default Signature selection in Outlook

I can't find an answer to this on the forum, or maybe i'm not typing my query in accurately enough.
With my Outlook 2010 at my workplace the default Signature block keeps getting changed to a default option when I load up Outlook. I don't have access to the source file to make any changes as it is all Server side.
What I want to do is change the default selection of my Signature from the old one to a new one.
Under File -> Options -> Mail -> Signatures I want to change my default Signature to something else upon start up of Outlook 2010 using a VBA code of some form. Is there any way that this can be done?
I have already created the new Signature but I need to reselect it as the default option every time I log onto my terminal, which is frustrating.
Looking for any help please.
After some cursory searching, it looks like Outlook signatures are managed through the Windows registry (for example, see here and here). Specific registry paths seem to depend on your version of Outlook.
Of course, if it's your work email, it's likely you can't make any changes to your registry.
However, if all you want is to automatically insert some specific text to any new email, that can be done via VBA. Basically, you want to use the Open event of a new email to insert specific text. To do that, you need to add the Open hook during the ItemLoad event. Something like this:
' declare the mail item that will have the Open event available
Public WithEvents myItem As Outlook.mailItem
' defines how the Open event will be handled
' note that you only want to do this with unsent items
' (hence the .Sent check)
Private Sub myItem_Open(cancel As Boolean)
If Not myItem.Sent Then
'insert your signature text here
End If
End Sub
' hooks the Open event to a mail item using the ItemLoad event
Private Sub Application_ItemLoad(ByVal Item As Object)
Dim mailItem As Outlook.mailItem
If Item.Class = OlObjectClass.olMail Then
Set myItem = Item
End If
End Sub
For more information, see the relevant Microsoft articles on the Application.ItemLoad event and MailItem.Open event.

How can I implement the PropertyChange event?

I wish to get the details of what has been changed in a MailItem.
I have been able to get ItemChange to trigger based upon Application.Session.Folders("TargetFolder") to a variable as such:
Private Sub olInvMbxItems_ItemChange(ByVal X As Object).
I would like to know the property changed in X. If I pass X to an global variable for Private Sub X_PropertyChange(ByVal x As Object), it will miss the first iteration as X was not initialized on the first pass of ItemChange.
How can I monitor a folder of MailItems to detect Category changes. Whilst ItemChange does this, it gives duplication of action, if I look for specific categories, as many changes trigger ItemChange as mentioned here:
Handle ItemChange event when outlook appointments are dismissed
and here:
Outlook Macro that will copy an email I flag and put it in a folder
The binary flag for the UserProperties in the second item will not function as it is not a one-off event.
Outlook Events VBA says to use PropertyChange but doesn't provide a technique for implementation.
There is no way to do that - even on the MAPI level, the store provider does not keep track on what changed. Your only solution is to compare the old (saved elsewhere by you) and new values to see what changed.
Here is a method that works for a single selection. Refinement yet needed, but this is a starting point:
Private WithEvents olExplorer As Outlook.Explorer
Private olCurSel As Selection
Private WithEvents olCurSelItem As Outlook.MailItem
Private Sub olExplorer_SelectionChange()
Set olCurSel = olExplorer.Selection
Set olCurSelItem = Nothing
Dim i As Long
For i = 1 To olCurSel.Count
If TypeName(olCurSel.Item(i)) = "MailItem" Then
Set olCurSelItem = olCurSel.Item(i)
End If
Next i
End Sub
Private Sub olCurSelItem_PropertyChange(ByVal Name As String)
Debug.Print Name; " is what changed!"
End Sub
Using Outlook.Explorer.Selection we can know that an item has been selected. We can then assign that item to and Outlook.MailItem conditionally and use the PropertyChange event of that Outlook.MailItem trigger the action we wish to take.
Problems:
Does not handle multiple selections
SelectionChange is triggered by the Reading Pane on each selection as well. Thus it is fired twice if the reading pane is open. As written above, olCurSelItem is set twice each SelectionChange.
This is only triggered by local changes. Other systems with access to the mailbox may change the item and it will not trigger the action.

Outlook Appointment - how to change the items in the Start Time dropdown list

I need to change the items in the start/end time dropdown list to be 5 minutes apart. Seems there's no simple way to set this up, so I'm trying VBA.
I can get an Inspector to look for when an appointment form is opened:
If Inspector.CurrentItem.Class = olAppointment Then
... but I don't know how to refer to or change the start/end time dropdown control to have the list of times I want it to.
If anyone out there knows of an alternative method of allowing the user to choose the times in intervals of 5 minutes, that would be great, too!
Check the Appointment.Start property. Use the following function to get current object
Function GetCurrentItem() As Object
Dim objApp As Outlook.Application
Set objApp = Application
On Error Resume Next
Select Case TypeName(objApp.ActiveWindow)
Case "Explorer"
Set GetCurrentItem = objApp.ActiveExplorer.Selection.Item(1)
Case "Inspector"
Set GetCurrentItem = objApp.ActiveInspector.CurrentItem
End Select
GetCurrentItem.UnRead = False
Set objApp = Nothing
End Function
This doesn't answer your question exactly - but I don't believe that it is possible to do what you need because there isn't a programmatic interface to those drop downs, nor is there a way to manually achieve what you want, so I don't know how having a macro recorder would help
This Website will tell you how to set a meeting up with a custom start time and duration, but you could build your own userform to popup whenever a meeting/appointment is created requesting a start and end time (or start time & duration if you prefer), which is probably the best workaround you'll get.
You could go crazy with this and make a non-modal userform that places itself over the existing controls and replicates their functionality - but that's a lot of coding, and it would be slow because it would be constantly updating its position or hiding itself when the appointment item loses focus, but its very achievable if you are determined.
Outside of VBA/Outlook, you could use Visual Studio to make a VSTO Add-In, creating a new ribbon in the appointment/meeting section, which has two custom controls which modify the start and end dates. You could also populate these with whatever code you want, but you'll probably need to learn C# to do this, although it may be possible with VB.net (which is much more similar to VBA). This Website is a reasonable starting point.
I'm sorry that this isn't really an answer, but I'm afraid that there isn't a satisfactory answer to this question.

How do I keep RecipientTime when executing MailItem.Move in an Outlook macro?

In an Outlook 2003 macro; Is there a way to move a message between folders without changing the ReceivedTime-header?
I currently use the method MailItem.Move. But that automatically sets the ReceivedTime property to the current time, which isn't really what I want.
I just tried moving a mailitem from my inbox to the deleted items folder, and it seems to have kept the receivedtime without a problem...
You may want to try using the MailItem.copy function and moving the resulting mailitem object, but like I said I'm not seeing the same problem...
Hope that helps...
Do an item.Save() and then do item.Move(), It will stamp current timestamp.