I wrote a VBA script for Outlook 2010. The purpose of this script is to clean some elements from the tasks and contacts for the user. This needs to be done following a migration to a new client managing solution. Since Exchange is connected to the new solution some items are doubled so we need to delete the items from outlook. Ideally this would be done on the Exchange server but we don't have access to it directly...
My script is already working but my problem lies with the distribution of said script. We don't have direct access to the computers of these people so what we need is a way to package it in a download, have them run it once from a link in an email and forget about it. Most of these users have about zero computer knowledge. Ideally I don't want this script to remain in Outlook after that one execution.
I searched for a solution but found nothing...
Here's my script if that helps. Also, I'm not a good programmer... So if there's a better way to do this don't hesitate to tell me.
Private Sub CleanUp()
Dim TaskFolder As Folder
Set TaskFolder = Session.GetDefaultFolder(olFolderTasks)
Dim Task As TaskItem
Dim objProperty As Outlook.UserProperty
Dim uProperty As String
Dim collTasks As New Collection
Dim ContactFolder As Folder
Set ContactFolder = Session.GetDefaultFolder(olFolderContacts)
Dim Contact As ContactItem
Dim objPropertyCLS As Outlook.UserProperty
Dim uPropertyCLS As String
Dim collContacts As New Collection
uProperty = "crmxml"
uPropertyCLS = "crmLinkState"
For Each Task In TaskFolder.Items
Set objProperty = Task.UserProperties.Find(uProperty, Outlook.OlUserPropertyType.olText)
If objProperty Is Nothing Then
Debug.Print "objProperty is Nothing"
ElseIf InStr(objProperty, "phonecall") > 0 Then
collTasks.Add Task
ElseIf InStr(objProperty, "letter") > 0 Then
collTasks.Add Task
ElseIf InStr(objProperty, "fax") > 0 Then
collTasks.Add Task
End If
Next
For Each Contact In ContactFolder.Items
Set objPropertyCLS = Contact.UserProperties.Find(uPropertyCLS, Outlook.OlUserPropertyType.olNumber)
If objPropertyCLS Is Nothing Then
Debug.Print "objPropertyCLS is Nothing"
ElseIf Not objPropertyCLS Is Nothing Then
collContacts.Add Contact
End If
Next
For Each Task In collTasks
Task.Delete
Next
For Each Contact In collContacts
Contact.Delete
Next
End Sub
Thanks a lot!
VBA scripts were not designed for deploying them on multiple PCs. If you need to run your code on multiple PCs you have to develop an add-in instead. Add-ins can be installed by users easily like any other Windows programs. If the add-in is not required any longer, it can be un-installed or disabled from the COM add-ins dialog in Outlook. See Walkthrough: Creating Your First VSTO Add-In for Outlook to get started quickly.
Related
Currently at the office we have Outlook 2003. We will be migrating to Outlook 2013.
In Outlook 2003 we have a commandbar that as example saves a mail item to a user specified folder or moves the item to the desired team.
In a userform the end-user can set his settings to his desired folder or select the team he is currently on. In this settings form there are multiple input field the user can fillout.
Whenever he clicks a button on the commandbar, outlook checks his settings to see on what team he is on, his desired save folder is, etc.
This userdefined settings are stored and called on by it's tags
(Application.ActiveExplorer.CommandBars("Toolbar").Controls.Item(1).tag)
As far i found on the internet Outlook 2013 does not support commandbars. I can instal the commandBar, but as soon as you restart outlook the bar is gone and the settings are gone.
Is there a way to save/store the settings made by the end-user in a userform so the scripts saves the mail item based on his settings to the correct folder or team?
I've tried to find a solution but haven't found it yet, or do not know where to look.
Hope you can guide me into the right direction to look for a solution.
(note: I know a little bit of VBA, can read and write it, but found it hard to explain how it works. If i left out some critical information in the question please let me know.)
Outlook doesn't allow to customize the Ribbon UI using VBA. The only thing you can do is to assign a macro to QAT button (or add controls manually in Outlook).
You need to develop an add-in to be able to customize the Ribbon UI (aka Fluent UI). See Walkthrough: Creating a Custom Tab by Using the Ribbon Designer for more information.
Read more about the Fluent UI in the following series of articles in MSDN:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
Is there a way to save/store the settings made by the end-user in a userform so the scripts saves the mail item based on his settings to the correct folder or team?
Using the Tag property is not the best way to store the user settings. Of course, you can standard ways for storing settings on the PC - files (XML, text or your own binary format), windows registry and etc.
But the Outlook object model provides hidden items for that. The GetStorage method of the Folder class returns a StorageItem object on the parent Folder to store data for an Outlook solution. See Storing Data for Solutions for more information.
As promised a few code samples wich i used to store and get the settings.
Maybe not the best way to do it, but it solved my problem to store the settings and maybe it could help someone else.
First of all I made a little check to see if the settings are already there.
Function Hidden_Settings_Aanwezig() As Boolean
Dim oNs As Outlook.Namespace
Dim oFL As Outlook.folder
Dim oItem As Outlook.StorageItem
On Error GoTo OL_Error
Set oNs = Application.GetNamespace("MAPI")
Set oFld = oNs.GetDefaultFolder(olFolderInbox)
Set oItem = oFld.GetStorage("Hidden Settings", olIdentifyBySubject)
If oItem.Size <> 0 Then
Hidden_Settings_Aanwezig = True
Else
Hidden_Settings_Aanwezig = False
End If
Exit Function
OL_Error:
MsgBox (Err.Description)
Err.Clear
End Function
If not, the following code creates the settings based on tekstboxes and checkboxes on a userform with the following code
Function Maak_Settings_Hidden()
Dim oNs As Outlook.Namespace
Dim oFld As Outlook.folder
Dim oSItem As Outlook.StorageItem
On Error GoTo OL_Error
Set oFld = Application.Session.GetDefaultFolder(olFolderInbox)
Set oSItem = oFld.GetStorage("Hidden Settings", olIdentifyBySubject)
'repeat the next to lines for every setting you want to store
oSItem.UserProperties.Add "Export Folder", olText
oSItem.UserProperties("Export Folder").Value = TextBox1.Text
oSItem.Save
Exit Function
OL_Error:
MsgBox (Err.Description)
Err.Clear
End Function
The functions above are called on with the following code:
If Hidden_Settings_Aanwezig = True Then
Call Get_Hidden_Settings_Startup
Else
Maak_Settings_Hidden
End If
To use one of the settings i use the following code.
In the main sub I use the following line:
DestFolder = Get_Hidden_Settings("Export Folder")
To call on this function:
Function Get_Hidden_Settings(Setting) As String
Dim oNs As Outlook.Namespace
Dim oFL As Outlook.folder
Dim oItem As Outlook.StorageItem
On Error GoTo OL_Error
Set oNs = Application.GetNamespace("MAPI")
Set oFld = oNs.GetDefaultFolder(olFolderInbox)
Set oItem = oFld.GetStorage("Hidden Settings", olIdentifyBySubject)
If oItem.Size <> 0 Then
Get_Hidden_Settings = oItem.UserProperties(Setting)
End If
Exit Function
OL_Error:
MsgBox (Err.Description)
Err.Clear
End Function
If I understand your problem correctly, what I would do is the following:
1) Export your VBA stuff into a *.bas files (for modules) and *.frx (for user forms) This is done in the VBA editor, File --> Export. You do this for each item (module and user form). Save these files e.g. on a memory stick, or whereever it suits you.
2) Import these files in Outlook 2013 into the VBA editor (same way, but --> File --> Import of course) e.g. by loading them from your memory stick.
This should make your VBA code available in your new Outlook 2013 environment.
3) Your command bars will not be available. But you can easily create something else: In the Office 2013 (etc.) products, you can add stuff to the "Ribbon". E.g. you can create a new tab called "My self-made tools", and you can place buttons there that call your VBA procedures. There you will find buttons for "Create new..."
To do so: --> File --> Optiobs --> Customize Ribbon --> Macros
Note: In a standard installation of Office 2013 (etc.) you will not have access to the VBA editor. To make the editor available, go through --> File --> Options --> Customize Ribbon and set a tick mark in the field for "Develooper tools". This will make a tab of that name appear in the "Ribbon".
I have VBA code in Outlook I use to send specific emails (with three asterics in the subject line) to the deleted folder after sent in 'This Outlook Session'.
It works correctly when Outlook is first opened, and all day long, however, the next day I find at some point overnight the VBA code has failed to function and only functions properly again if I close \ re-open Outlook??
This only started to occur when the company moved to the 2007 & 2010 versions.
I need it to run constantly on sent mail as I have early am batch processes that send out a lot of emails that I want to have removed from sent folder and placed in the deleted folder after eachis sent as this code does.
Here is the code. Since it worked well before, I can only assume the newer Outlook versions need some additional trigger to keep 'This Outlook Session' open or something of that nature.
Any thoughts would be appreciated.
Option Explicit
Private WithEvents olSentItems As Items
Private Sub Application_Startup()
Dim objNS As NameSpace
Set objNS = Application.GetNamespace("MAPI")
Set olSentItems = objNS.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub olSentItems_ItemAdd(ByVal Item As Object)
If Item.Class = olMail And InStr(1, Trim(Item.Subject), " * * * ", vbTextCompare) > 0 _
Then
Item.Delete
End If
End Sub
I suggest that you have a look at the Trust Center Settings >> Macros. Office 2003 has it in a different way and it is all new after Office 2003.
Try different settings and see which one fits your need. They are totally four setting levels.
Also it is good idea to use only one version of Outlook. Don't interchange between 2007 and 2010 if you have both of them. Outlook versions cannot co exist with creation of bugs.
This page should be able to give me more details.
Click Here
As a continuous process to improve our customer service at our helpdesk I'm looking to integrate a functionality in our outlook so that we can reply to existing e-mails using outlook template's (.oft).
My search online mostly gave me results for auto-reply'ing. However this is not what I (we) need.
We are in need for a tool that enables us to select from a list of standard templates (with subject oriented reply's). http://replywith.4team.biz/ Gives a solution in the right direction, however, as with any company, we would like a free tool.
Is this programmable in VBA? And if so, how?
Ours not to reason why, ours but to do and die.
Here is one small, untested, VBA sample based on http://msdn.microsoft.com/en-us/library/office/ff865637.aspx
Sub CreateReplyFromTemplate()
dim currItem As Outlook.MailItem
dim currItemReply As Outlook.MailItem
Dim MyItem As Outlook.MailItem
set currItem = activeinspector.currentitem
Set curritemReply = currItem.Reply
Set MyItem = Application.CreateItemFromTemplate("C:\HelpTopic1.oft")
MyItem.To = currItemReply.To
MyItem.htmlbody = MyItem.htmlbody & currItemReply.htmlbody
currItemReply.close oldiscard
currItem.close oldiscard
MyItem.Display
set curritemReply = nothing
set MyItem = nothing
set currItem = nothing
End Sub
For ways of deploying the VbaProject.OTM file http://www.outlookcode.com/article.aspx?id=28 or see if this works VbaProject.OTM deployment
Alternatively, the free version is built into Outlook.
Reply with a message template via Quick Steps - http://www.msoutlook.info/question/665
Working with message templates - http://www.howto-outlook.com/howto/messagetemplates.htm
If training for this is available, the cost of one day of training for each person could be $300.00 or more.
Of course you can do that in VBA, but would you really want to? You can buy 10 licenses of that tool for $99.50. I don't know where you work, but at most software companies $99.50 will buy you about an hour worth of programmer's time (benefits included). You probably could have bought 1 license if you saved the time it took you to post this question.
Just to add to the answer above, in sub CreateReplyFromTemplate() instead of
Set curritemReply = currItem.Reply
Replace with
Set currItem = Application.ActiveExplorer().Selection(1)
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.
This is my first time asking a question to y'all. I'm a SQL Developer by trade, and am very green when it comes to VB.
I manage a on-line database for my department, Quickbase, and with this website we manage report requisitions. I create a ticket for each one, and that ticket creates an e-mail notifying the dev. responsible for that assignment. We have folders set up for each request that comes in, and it is very laborious and frustrating to manually create said folders.
So I asked and looked around, coming across a script that was able to do what I needed, or so I am told. However, I'm not sure how to customize it to my needs, nor implement it correctly. This is where I need your assistance, fair programming gods of SO, please help me slay this dragon, and all the riches of the realm will be yours*!
Outlook VBA
Sub MakeFile(MyMail As MailItem)
myMailEntryID = MyMail.EntryID
Set outlookNameSpace = Application.GetNamespace(“MAPI”)
Set outlookMail = outlookNameSpace.GetItemFromID(myMailEntryID)
MyArgument = OutlookMail.Subject
Dim sMyCommand = “c:\makefile.bet ” & MyArgument
Shell “cmd /c ” & sMyCommand, vbHide
End Sub
Makefile.bat
#echo off
cls
mkdir %1
The webtsite URL is: www.quickbase.com
The root folder path: h:///ntsp/data/reports - criteria/quickbase docs/[Folder to be created]
*Riches are not monetary, but the feeling of goodness, and completeness only gained by helping a fellow nerd out, oh and it makes the e-peen grow might and strong!
being a fellow nerd I am going to get you started in the right direction. I think we can achieve what you want with VBA alone and do not need to use shell.
First we need to hook an event of when this all should happen. I imagine that is when your inbox gets an email. If I am right here is the start of this.
Please understand 2 important things.
This only works on items coming into your inbox. Thus if you already have a rule moving items to another folder it will not work.
You need to "Test" the email coming in - my example shows a test of the subject. It will only call you special routine IF and ONLY IF the subject has in it "My Test"
To enter the code in the Visual Basic Editor:
On the Tools menu, point to Macro, and then click Visual Basic Editor.
In the Project pane, click to expand the folders, and then double-click the ThisOutlookSession icon.
Type or paste the following code into the Code window.
Dim WithEvents objInboxItems As Outlook.Items
' Run this code to start your rule.
Sub StartRule()
Dim objNameSpace As Outlook.NameSpace
Dim objInboxFolder As Outlook.MAPIFolder
Set objNameSpace = Application.Session
Set objInboxFolder = objNameSpace.GetDefaultFolder(olFolderInbox)
Set objInboxItems = objInboxFolder.Items
End Sub
' Run this code to stop your rule.
Sub StopRule()
Set objInboxItems = Nothing
End Sub
' This code is the actual rule.
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
If Item.Subject = "My Test" Then
Call checkForFolder
End If
End Sub
Private Sub checkForFolder()
End Sub
On the File menu, click Save VbaProject.OTM.
You can now run the StartRule and StopRule macros to turn the rule on and off.
Quit the Visual Basic Editor.
(You might need to start and stop Outlook to get the variables to "Hook".
Once you get this working and understood, then you can remove the on off switches.
Then you have to decide your test for making a new folder so that we can then test the email and compare it to existing folders and then make a new one etc.