VBA in Outlook is not being applied - vba

I'm suddenly in the position of maintaining a form in Outlook that helps users submit requests properly. Here's the how that goes:
Open the form
Fill in the form
Remove cruft, like signatures, etc
Click "Send"
At this point, a VBA script (Project1 -> Microsoft Outlook Objects -> ThisOutlookSession) should kick in and do a couple of things:
Ask the user if they want to send.
If so, turn their entries on the form into a JSON body suitable for the receiving system and send the email.
It appears that the VBA script is not being called at all. So, a couple of questions:
What conditions determine if the VBA script is called? Is it simply the name, "ThisOutlookSession"?
Is there some very basic thing that I can replace the script with temporarily that makes it very obvious? I'm thinking along the lines of what I do in Python when I'm not sure a condition is being met, so I add something like print('This function was called')
Any other suggestions?
As you can tell, I'm very new to this, so small words are appreciated, and thank you.

I think that you can start from this point with the Application.ItemSend event, that called when user clicks the send button:
' in ThisOutlookSession module
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If Item.Class = olMail Then
If MsgBox("Are you want to send the letter '" & Item.Subject & "'?", vbYesNo) = vbNo Then
Cancel = True 'don't send the original letter
Else
' process the letter as you want
Cancel = True 'debug
End If
End If
End Sub
The command in VBA like print("smth") in Python is Debug.Print "smth" that prints text in Immediate window in VBE

Related

Word Save As Default and Iteration

I have tried many different ways of doing this but I can't find one that works for the application.
I have a MS Word Template that will be used by another team.
This is the criteria I have been given.
The initial file name must be 'PL' & the right most figures of a text control box. It should also say Issue 01.
The user must be able to chose the save location.
If the user then opens the document at a later date and saves it should retain the name and path.
If the user 'saves as' then it should up issue the Issue number.
The closest I can get to this working is this: -
In the top section I have this: -
Private WithEvents App As Word.Application and Dim n as long
Then in the Document New I have: -
Private Sub Document_New()
Set App = Word.Application
n = 0
End Sub
Then for the execution I have done this: -
Private Sub App_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
ActiveDocument.SaveAs2 "PL" & Right(ActiveDocument.SelectContentControlsByTitle("Works Order Number").Item(1).Range.Text, 5) & " Issue " & Format(n, "00") & ".docx", wdFormatDocumentDefault
End Sub
However, this saves before the user has chosen a location. It works but the user needs to chose the location. So I tried this, this just does the same thing.
Private Sub App_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
If Cancel = False Then
n = n + 1
ActiveDocument.SaveAs2 "PL" & Right(ActiveDocument.SelectContentControlsByTitle("Works Order Number").Item(1).Range.Text, 5) & " Issue " & Format(n, "00") & ".docx", wdFormatDocumentDefault
ElseIf Cancel = True Then
Exit Sub
End If
End Sub
Any suggestions or help would very much be welcomed. I basically just want to suggest the filename which up issues with every save as. But I cant find a way to influence that without physically saving.
Thank you in advance for your time and support.
You can repurpose ribbon controls (Save) to call your event handler first. Moreover, if required, you may cancel the default action in the event handler. See Temporarily Repurpose Commands on the Office Fluent Ribbon for more information. Repurposing ribbon controls give you a big plus - corresponding keyboard shortcuts are handled by your code as well. So, you will be able to intercept keyboard shortcuts by the same code.
In case of Backstage UI you can hide the SaveAs button and add your own. Read more about the Backstage UI in the following articles:
Introduction to the Office 2010 Backstage View for Developers
Customizing the Layout of Columns in the Office 2010 Backstage View
You really need to learn how to use the online documentation for VBA. If you had looked up DocumentBeforeSave you would have learned that Cancel is always False when the event is triggered. If you set it to True in the event handler it cancels the save.
You need to intercept the save before the dialog has been displayed, but the event is only triggered after the dialog. Because the criteria for Save is to use the standard functionality it is only the FileSaveAs you need to intercept.
Prior to the implementation of the Backstage view (the File tab) this could be solved simply by creating a routine named FileSaveAs. You can still do this and it will intercept the keyboard shortcut or clicking the QAT button. But it will not intercept the backstage commands. Only the event can do that without rebuilding the Backstage view, and the event won't work for you...
As far as intercepting the dialog to set the initial file name, that has been covered on SO before, here for example.

How to automate saving attachments AND memo writing inside the messages

I want to automate these actions, on an open message (either received or sent):
save all the attachments in a folder through a popup letting the user to select the destination folder
This command already exist inside the Action > Other Actions submenu, but the problem is that no trace remains visible in the message about the former presence of attachments, so - as in Lotus Notes - I would like to:
edit the message to introduce some text at the beginning, something such a message like "Attachment removed on " and, even better, the path where the attachments have been saved.
I tried to start understanding Outlook VBA but I feel rather uncomfortable with it.
You have asked far too much in one question to hope for a complete answer. This site is for programmers to help one another develop. Your question should include some faulty code so a more experienced programmer can explain where you have gone wrong.
I understand you feeling uncomfortable with Outlook VBA. When I started, I bought a highly recommended book and found it very unhelpful. I learnt through experimentation. I still experiment when I want to understand something new. I also read through the Outlook questions and answers here. There are some extraordinarily knowledgeable people answering questions. I find that continually adding to my understanding of what can be achieved with Outlook helpful even if I do not expect to ever use some of the more exotic functionality.
You need to break your complete task into small sub-tasks. If your sub-task is small enough you can probably find something relevant if you search. My breakdown of your task is:
Allow user to identify Outlook folder from which attachments are to be saved.
Allow user to identify disc folder to which attachments are to be saved.
Read down Outlook folder looking for emails with user attachments.
For each email with user attachments:
4(a) save attachments to disc folder,
4(b) delete attachments from email
4(c) edit email body with details of deleted attachments.
I will provide some code to get you started with sub-tasks 1 and 3. You should be able to find help on sub-task 2 without too much difficulty. I will include some guidance on sub-tasks 4(a), 4(b) and 4(c).
I would have thought the easiest way for the user to identify the Outlook folder would be for the user to open that folder and then start the macro. That is the approach I have taken. Please copy this code to a module, open an appropriate Outlook folder and run the macro. I believe I have included enough comments to explain what the macro is doing but ask questions if necessary:
Option Explicit
Sub DemoSelectFolderFromEmail()
Dim Exp As Explorer
' VBA has two types of Folder: Outlook folders and disc folders.
' Since you will need access to disc folders, it is important to be clear
' which type you mean.
Dim FldrSrc As Outlook.Folder
Dim InxA As Long
Dim InxF As Long
Dim ItemCrnt As MailItem
' Get collection of emails selected by user.
Set Exp = Outlook.Application.ActiveExplorer
' Check that an email has been selected.
If Exp.Selection.Count = 0 Then
Call MsgBox("Please select an email then try again", vbOKOnly)
Exit Sub
ElseIf Exp.Selection.Item(1).Class <> olMail Then
Call MsgBox("Please select an email then try again", vbOKOnly)
Exit Sub
End If
' The parent of a selected email is the Outlook folder that contains it.
' In my view, this is the easiest way for the user to identify the source
' folder.
Set FldrSrc = Exp.Selection.Item(1).Parent
Debug.Print FldrSrc.Name
' FldrSrc.Items is a collection of the items in FldrSrc.
' Probably every itemn is a MailItem but I check to be sure.
' ReceivedTime and Subject are just two of the properties that you can access.
' If there are any attachments, I display their names.
' Note that for VBA, signatures and images count as attachments. You will need
' to add code to idetify these attachments if you do not want to save them.
For InxF = FldrSrc.Items.Count To 1 Step -1
With FldrSrc.Items(InxF)
If .Class = olMail Then
Debug.Print .ReceivedTime & " " & .Subject
If .Attachments.Count > 0 Then
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print " " & InxA & " " & .DisplayName
End With
Next
End If
End If
End With
Next
End Sub
SaveAsFile is the method that writes an attachment to a disc folder. Note that SaveAsFile will overwrite any existing file with the same name. If the same DisplayName is used for different attachments, you will need to have some system of making names unique.
You will need to edit the emails to delete the attachments and then save the edited emails.
An email can have a text body and or an Html body and or a RTF body. I have never seen a RTF body so you can probably ignore them. If an email has both a text and an Html body, the user sees the Html body. It is rare these days for an email not to have an Html body. You can probably get away with just adding a string at the start of the Html body but you will need to experiment to ensure the appearance is satisfactory. I would probably prefer to insert, at the beginning of the body section, a complete Html string controlling background colour, font colour, font size and font name so that I the appearance of the insert text was always the same.

Forwarding mail automatically

I receive emails with subjects of the form “### auto fax” where “###” is a variable number of digits. Each of these emails must be forwarded to “####mail2fax.com”. I am looking for ideas on how to automate this.
Your addition “and it needs me to be at office” may be a problem. I am a home user of Outlook. If I want Outlook to do any while I am away, I need to leave my computer switched on. I assume you are an Outlook Exchange user. You can leave instructions that will be obeyed while you are away even if your computer is switched. However, for security reasons, the default is that you cannot leave instructions to forward an email outside your company. As I understand it, you would need to forward the “Auto fax” emails to a colleague. Since we hope to automate the process, this should not be an imposition on your colleague. You would need to create a version of your rule and macro and install it on your colleague’s computer but this should not be too difficult if my reading of this functionality is correct. The point is, that this will not be part of this answer.
A difficulty with VBA is that there are usually several ways of achieving the same effect. This does not matter if you develop your own VBA; pick your favourite way of achieving an effect and experiment until you have a full understanding of that favourite. However, if you ask for help or look for useful snippets of code, you must have a basic familiarity with every way of achieving effects because others will not share your favourite. You may find you have to get the idea of what a snippet does and then rewrite it your way. This code is written using my favourite techniques.
When you write a macro to process emails, you have two issues:
How do you select the emails you wish to process?
How do you process the selected emails?
There are four methods of selecting emails:
The user selects one or more emails and then runs the processing macro.
The macro scans one or more folders looking for emails with particular characteristics and then processes them.
You instruct Outlook to monitor a particular folder and to run a macro every time a new email arrives in that folder.
You set up a rule to select emails as the arrive and link a macro to that rule to process them.
I believe method 4 will be the easiest method to implement your requirement. However, it may not be available. It works fine on my system but apparently those responsible for an Outlook Exchange installation can forbidden it. If method 4 does not work for you, I believe method 3 will be the next best method. However, this answer will use method 1.
I use method 1 whenever I am developing a new email processing macro. If gives me total control of which emails are processed in which order. I can start with simple emails and I can run the macro against the same email again and again until I get the macro working just the way I want. Once I am satisfied with the macro, I can switch to whichever of the other methods is most appropriate.
This is the first version of my processing macro:
Public Sub ForwardAndMoveEmail(ByRef ItemCrnt As Object)
Dim FaxNum As String
Dim ItemNew As MailItem
Dim Subject As String
If ItemCrnt.Class <> olMail Then
' Ignore item if it is not an email
Exit Sub
End If
Subject = ItemCrnt.Subject
If LCase(Right$(Subject, 9)) = " auto fax" Then
‘ Only process email if the subject ends with case-insensitive " auto fax"
FaxNum = Mid$(Subject, 1, Len(Subject) - 9)
With ItemCrnt
Subject = "Fax from " & .Sender & " (" & .SenderEmailAddress & ")"
Set ItemNew = .Forward
End With
With ItemNew
.Subject = Subject
' Clear existing recipient(s)
Do While .Recipients.Count > 0
.Recipients.Remove (1)
Loop
.Recipients.Add FaxNum & "#mail2fax.com"
.Save
End With
End If
ItemCrnt.Move ItemCrnt.Parent.Parent.Folders("Faxed")
End Sub
The item to be processed is a parameter to this macro. Note that I have typed it as an Object rather than as a MailItem. Then note that the first statements of the macro checks that the item is a MailItem (Class = olMail). With method 1, the user could select something other than a MailItem. This check ensures this user error causes no problem for the macro.
Next the macro checks the Subject ends in “ auto fax” or “ Auto fax” or “ AUTO FAX” or any other variation. With method 1, the user could select the wrong MailItem. With method 3, every email is passed to the macro. Hence, the check that it is a macro to be forwarded to the fax service.
If I decided in advance which selection method I was going to use, I would not need to perform all these checks. I think that being able to change the selection method is worth the extra checks.
The macro extracts the leading characters of the Subject. I do not check that they are numeric although such a check could be added if it was important.
The macro creates a new Subject for the forwarded email. I do not know if you would want a new Subject but this demonstrates what you can do if it was helpful.
Set ItemNew = .Forward creates the item to be forwarded. Note that this statement is within a With block. This is the same as Set ItemNew = ItemCrnt.Forward.
The macro then works on ItemNew. It changes the Subject, it clears the existing recipients and adds the new one and then saves the new email as a draft.
The last statement of the macro is something else you did not ask for but which may be useful. I have created a folder named “Faxed” and I move the original email to it. This saves the original email without cluttering your Inbox.
Consider ItemCrnt.Parent.Parent.Folders("Faxed"). This is the folder to which the item is to be moved. I have chained properties together in a way that probably looks strange but is straightforward once you understand it.
ItemCrnt is the original mail item.
ItemCrnt.Parent is a property of ItemCrnt. Many objects have parents. For a MailItem it is the folder holding the MailItem; that is, folder “Inbox”.
`ItemCrnt.Parent.Parent is a property of folder “Inbox”. For a folder, its parent is the folder containing it. Since folder “Inbox” is a top-level folder, its parent is the store holding it. A “store” is a file in which Outlook stores folders, mail items, calendar items, tasks and many other things.
Having gone all the way up to the store, ItemCrnt.Parent.Parent.Folders("Faxed") goes down to a folder within the store.
The macro that calls ForwardAndMoveEmail is:
Option Explicit
Sub SelectEmailsUser()
Dim Exp As Explorer
Dim ItemCrnt As Object
Dim MailItemCrnt As Object
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Please select one or more emails then try again", vbOKOnly)
Exit Sub
End If
For Each ItemCrnt In Exp.Selection
If ItemCrnt.Class = olMail Then
Call ForwardAndMoveEmail(ItemCrnt)
End If
Next
End Sub
Don’t worry too much about this macro at this stage. Study it later when you are ready to develop your next processing email. It is a macro I wrote a long time ago. Each time I want to test a new email processing macro I simply change statement Call ForwardAndMoveEmail(ItemCrnt) to call the new macro.
This is not the final version of the processing macro although it is probably the final version of this evening. Please:
Copy the two macros to an Outlook module. The two macros can be in either order but Option Explicit must be at the top of the module.
Create folder “Faxed”. At the same level as folder “Inbox”.
Select one or more of the “Auto fax” emails and run macro SelectEmailsUser.
Check the processed “Auto fax” emails are now in folder “Faxed”.
Review the emails in folder Drafts. I think these emails are unsatisfactory. I will tell why later and what I think you should do to make them satisfactory.
Part 2
I ended the first part of this answer by saying I did not think the draft email my macro had created was satisfactory.
The problem for me is that the original email is headed up by a typical “forwarded” header: original sender, my name, date sent and subject. The author of the email has presumably spent some time creating the text of the email and would not want this irrelevant header prefixing their text. So how was I to stop this header being included in the email sent to “mail2fax.com”?
My first idea was to use method “Copy” instead of method “Forward”. This did give a satisfactory appearance but was slight awkward. With the statement Set ItemNew = ItemCrnt.Forward, ItemNew is a draft email ready to be finished and saved in folder “Drafts” or sent. But with the statement Set ItemNew = ItemCrnt.Copy, ItemNew is a received email and, when saved, is placed in folder “Inbox”. I have sent a copied email and the appearance when it arrives at one of my secondary email addresses looks satisfactory.
My second idea needs an introduction. An email can have three bodies: plain text, HTML or RTF. I have never seen an email containing a RTF (Rich Text Format) body. RTF was probably a sensible format 20 years ago if you wanted more that plain text. But today, HTML is so powerful that the same email can be rearranged for a large PC screen, a tablet or a smart phone so it is always easy to read. So for all practical purposes there are only two formats for an email: plain text and HTML. If an email has both plain text and HTML bodies, it is the HTML body that is shown to the reader. The VBA programmer can look at either or both bodies but the reader is not told that there is a plain text body. Very occasionally, I have seen a carefully constructed plain text body that has been designed for an email package that cannot handle HTML. But normally the plain text body is just the HTML body with the HTML tags stripped out.
My second idea was to use method “Forward” but then to copy the text and HTML bodies from the original email.
In the above code, you will find:
.Subject = Subject
' Clear existing recipient(s)
Please replace these two lines with:
.Subject = Subject
.Body = ItemCrnt.Body
.HtmlBody = ItemCrnt.HtmlBody
' Clear existing recipients
With this change, the draft emails will not have a “forwarded” header.
I assume you know who these emails are being faxed to. I suggest you contact one or two and say you are going to conduct an experiment. They will have already received faxes as a result of you using the keyboard interface to forward these emails. Send some of the draft emails created by my macro and ask for the recipients’ opinion on the new appearance. If they prefer the new appearance, we will be ready to move on to stage 3: Automating these emails. If they do not like the new appearance, you will need to ask them what is wrong about the new appearance and we will have to attempt to fix the problem.
Part 3
Please do not follow the instructions in this part until you are convinced that emails created by macro ForwardAndMoveEmail are as they should be. This part is about automating the process so the emails will be sent without you having any opportunity to check or correct them before they are sent.
Please make the following changes to macro ForwardAndMoveEmail:
Replace Public Sub ForwardAndMoveEmail(ByRef ItemCrnt As Object)
by Public Sub ForwardAndMoveEmail(ByRef ItemCrnt As MailItem).
With email selection method 1, it is possible (difficult but possible) to select items that are not MailItemss. I set the type of ItemCrnt to Object so this would not cause an error. To use a macro with a rule, ItemCrnt must be MailItem.
These statements are now redundant:
If ItemCrnt.Class <> olMail Then
' Ignore item if it is not an email
Exit Sub
End If
You can leave these statements since they will do no harm. Alternatively, you could delete them or place a quote in front of each statement.
Replace .Save by .Send.
On my system I can attach a macro to a rule. If you can do the same, it will be the easiest approach. However, some IT departments consider attaching a macro to a rule to be a security risk and disable it. If you find you cannot attach a macro to a rule, you will have to try the event approach. I will add additional instructions if necessary.
The screenshots below are from my home Outlook installation. You have functionality I lack so the screens you see will not be identical. However, my screenshots should be similar enough to yours to be useful.
Select one of these “auto fax” emails. From the “Home” tab click “Rules” then “Create Rule...”. You will get a pop-up window like this:
I created an “Auto fax” email in one of my secondary accounts and sent it to me main account. This is why I am shown as both the sender and the receiver. Because I had selected the “Auto fax” email, its subject is shown. Edit this subject to remove the leading digits. A tick will appear in the box next to the subject to get:
Click “Advanced Options...” to get this pop-up window:
Notice that subject in the line near the top has not been edited. This does not matter; it is the value in the “Step 2” box that matters. Note that if you click “ Auto fax” in the “Step 2” box, you can add extra values. So if some of these emails have slightly different subjects, you can add these alternative values. Click “Next” to get a pop-up window like this:
Near the bottom is “Run a script”. You will have more options and may have to scroll down to see this option. Click the box next to this option. “Run a script” will appear in the “Step 2” box. Click “Run a script” in the “Step 2” box. You will be asked to “Enable macros” if you have not done so already. A new pop-up window will appear showing all the macros that could be selected for this option. I have several possible macros so I will not show you my list. You should only see one macro: ForwardAndMoveEmail. To appear in this list, a macro must be Public and the first parameter must be a MailItem. Select ForwardAndMoveEmail if it isn’t selected and click “OK”. “Run a script” now reads “Run ForwardAndMoveEmail”. Click “Next”. You will get a pop-up window of exceptions which I assume are irrelevant to you. Click “Next” to get the final pop-up:
You can click the box against ‘Run this rule now on messages already in “Inbox”’ to forward any of “Auto fax” emails already received but not forwarded. Click “Finish”.
The “Auto fax” rule is now operational and any “Auto fax” emails will be forwarded automatically. It would be a good idea to monitor folder “Faxed” and check the intended recipients received their faxes.

Disable Save As but not Save in Word 2010

I am looking to disable Save As in a Word 2010 file but still allow save. In other words I want users to be able to update the existing file but not create copies. I realize that this is impossible to truly do for people who know workarounds but for the general user I have successfully done this in Excel but am pretty new to word VBA.
When I add the following to a brand new document everything works as intended:
Sub FileSaveAs()
MsgBox "Copies of this file cannot be created. Please save changes in the original document." & _
, , "Copy Cannot be Created"
End Sub
My document has other macros for various command buttons but none of them involve saving the document (under original name or save as). There is also a macro running on open but that is 1 line going to a bookmark. When I try to "save as" in this document I get the message box as intended. When I try to "save" though things get strange: I get the save as dialogue (problem 1). Whether I try to save either under same name or other name the dialogue behaves as it normally would except it doesn't save and the dialogue box opens again automatically essentially creating an endless loop until I hit cancel (problem 2). I also intermittently get a "disk is full" warning pop-up after trying to save which I can dismiss but appears a few minutes later as long as he file is open (perhaps related to autosave?)
Since the macro works in the test file I assumed this strange behavior must be something elsewhere in my code but my document with the other macros saves normally as long as I don't include the save as code above so now I'm totally confused. Before I put up the rest of my code which is lengthy and for the reasons stated above I would not think impact things, I figured I'd ask this:
1. Is there any place other than my other command button macros that could be causing this behavior?
2. Is there a better method people recommend to achieve my ultimate goal of disabling save as but not save?
Thanks in advance for any advice you can provide.
The Word application has a DocumentBeforeSave event. To enable application events I suggest to create a class module by the name of ThisApplication and paste the following code into it.
Option Explicit
Private WithEvents App As Application
Private Sub Class_Initialize()
Set App = Word.Application
End Sub
Private Sub App_DocumentBeforeSave(ByVal Doc As Document, _
SaveAsUI As Boolean, _
Cancel As Boolean)
If SaveAsUI Then
MsgBox "Please always use the ""Save"" command" & vbCr & _
"to save this file.", _
vbExclamation, "SaveAs is not allowed"
Cancel = True
End If
End Sub
Add the following code to your ThisDocument module.
Dim WdApp As ThisApplication
Private Sub Document_Open()
Set WdApp = New ThisApplication
End Sub
You may add the Set App = ... line to your existing Document_Open procedure. After the WdApp variable has been initialised all application events will be received by the ThisApplication class where the DocumentBeforeSave event procedure is programmed not to allow SaveAs.
Of course, this is a blanket refusal for all documents. Therefore you may wish to add code to the procedure to limit the restriction to certain documents only. The proc receives the entire document object with all its properties, including Name, Path, FullName and built-in as well as custom properties. You can identify the files you wish to be affected by any of these.
Note that the WdApp variable will be erased in case of a program crash. If this happens the application events will no longer fire. It may be useful to know that application events occur before document events. This is if you wish to use the application's DocumentOpen event as well as or instead of the document's Document_Open event.

How do I make Outlook purge a folder automatically when anything arrives in it?

I hope it's okay to ask this kind of question. Attempting to write the code myself is completely beyond me at the moment.
I need a macro for Outlook 2007 that will permanently delete all content of the Sent Items folder whenever anything arrives in it. Is it possible? How do I set everything up so that the user doesn't ever have to click anything to run it?
I know I'm asking for a fish, and I'm embarrassed, but I really need the thing...
edit:
I've pasted this into the VBA editor, into a new module:
Public Sub EmptySentEmailFolder()
Dim outApp As Outlook.Application
Dim sentFolder As Outlook.MAPIFolder
Dim item As Object
Dim entryID As String
Set outApp = CreateObject("outlook.application")
Set sentFolder = outApp.GetNamespace("MAPI").GetDefaultFolder(olFolderSentMail)
For i = sentFolder.Items.Count To 1 Step -1
sentFolder.Items(i).Delete '' Delete from mail folder
Next
Set item = Nothing
Set sentFolder = Nothing
Set outApp = Nothing
End Sub
It's just a slightly modified version of a piece of code I found somewhere on this site deleting Deleted Items. It does delete the Sent Items folder when I run it. Could you please help me modify it in such a way that it deletes Sent Items whenever anything appears in the folder, and in such a way that the user doesn't have to click anything to run it? I need it to be a completely automated process.
edit 2: Please if you think there's a better tool to achieve this than VBA, don't hesitate to edit the tags and comment.
edit 3: I did something that works sometimes, but sometimes it doesn't. And it's ridiculously complicated. I set a rule that ccs every sent email with an attachment to me. Another rule runs the following code, when an email from me arrives.
Sub Del(item As Outlook.MailItem)
Call EmptySentEmailFolder
End Sub
The thing has three behaviors, and I haven't been able to determine what triggers which behavior. Sometimes the thing does purge the Sent Items folder. Sometimes it does nothing. Sometimes the second rule gives the "operation failed" error message.
The idea of acting whenever something comes from my address is non-optimal for reasons that I'll omit for the sake of brevity. I tried to replace it with reports. I made a rule that sends a delivery report whenever I send an email. Then another rule runs the code upon receipt of the report. However, this has just one behavior: it never does anything.
Both ideas are so complicated that anything could go wrong really, and I'm having trouble debugging them. Both are non-optimal solutions too.
Would this be an acceptable solution? Sorry its late but my copy of Outlook was broken.
When you enter the Outlook VB Editor, the Project Explorer will be on the left. Click Ctrl+R if it isn't. It will look something like this:
+ Project1 (VbaProject.OTM)
or
- Project1 (VbaProject.OTM)
+ Microsoft Office Outlook Objects
+ Forms
+ Modules
"Forms" will be missing if you do not have any user forms. It is possible "Modules" is expanded. Click +s as necessary to get "Microsoft Office Outlook Objects" expanded:
- Project1 (VbaProject.OTM)
- Microsoft Office Outlook Objects
ThisOutlookSession
+ Forms
+ Modules
Click ThisOutlookSession. The module area will turn white unless you have already used this code area. This area is like a module but have additional privileges. Copy this code to that area:
Private Sub Application_MAPILogonComplete()
' This event routine is called automatically when a user has completed log in.
Dim sentFolder As Outlook.MAPIFolder
Dim entryID As String
Dim i As Long
Set sentFolder = CreateObject("Outlook.Application"). _
GetNamespace("MAPI").GetDefaultFolder(olFolderSentMail)
For i = sentFolder.Items.Count To 1 Step -1
sentFolder.Items(i).Delete ' Move to Deleted Items
Next
Set sentFolder = Nothing
End Sub
I have taken your code, tidied it up a little and placed it within an event routine. An event routine is automatically called when the appropriate event occurs. This routine is called when the user has completed their log in. This is not what you requested but it might be an acceptable compromise.
Suggestion 2
I have not tried an ItemAdd event routine on the Sent Items folder before although I have used it with the Inbox. According to my limited testing, deleting the sent item does not interfere with the sending.
This code belongs in "ThisOutlookSession".
Option Explicit
Public WithEvents MyNewItems As Outlook.Items
Private Sub Application_MAPILogonComplete()
Dim NS As NameSpace
Set NS = CreateObject("Outlook.Application").GetNamespace("MAPI")
With NS
Set MyNewItems = NS.GetDefaultFolder(olFolderSentMail).Items
End With
End Sub
Private Sub myNewItems_ItemAdd(ByVal Item As Object)
Debug.Print "--------------------"
Debug.Print "Item added to Sent folder"
Debug.Print "Subject: " & Item.Subject
Item.Delete ' Move to Deleted Items
Debug.Print "Moved to Deleted Items"
End Sub
The Debug.Print statements show you have limited access to the sent item. If you try to access more sensitive properties, you will trigger a warning to the user that a macro is assessing emails.