Mike
asked on
Outlook Script
Only a daily basis, I receive more than 10 to 20 reports from 12 people… that I have open and save the .csv document to different network drives. I have a separate folder in my outlook for each person who sends me the attachment. I have to spend more than hour every morning opening and saving each excel document to their respective network drive. This is where my problem begins… I am in search script that can pull each the attachment from outlook folder, change the .csv to .xls, and save it to its respective network drive.
I don’t know if this is possible, but I thought I would put the question out there and see if somebody can direct me to script or help me create one that I can use my version of Windows outlook 2010….. Is this possible….?
I don’t know if this is possible, but I thought I would put the question out there and see if somebody can direct me to script or help me create one that I can use my version of Windows outlook 2010….. Is this possible….?
You can also do this in VBA such that it will do the action automatically for you (No separate script to run). You will need to change some values in the code to work for your setup. For instance I set up my test code to route specific messages to a folder in my personal files called "trash". You will need to update that line for whatever folder you want to watch. The code then looks for any new mail item added to that folder. If it has a .csv attacment it saves it off. You will need to update the path to the correct path.
This code will need to go into the ThisOutlookSession module.
-Bear
This code will need to go into the ThisOutlookSession module.
Dim WithEvents AttachmentFolderItems As Outlook.Items
Private Sub Application_Startup()
Dim objNameSpace As Outlook.NameSpace
Dim objNewItems As Outlook.Items
Dim objFolders As Outlook.Folder
' Get Access to Outlook Folders
Set objNameSpace = Outlook.GetNamespace("MAPI")
' Get the particular folder we want to watch
Set objFolders = objNameSpace.Folders("Personal Folders").Folders("trash")
' Set up the item object so that it triggers the Item Add Event
Set AttachmentFolderItems = objFolders.Items
End Sub
Private Sub AttachmentFolderItems_ItemAdd(ByVal Item As Object)
Dim objAttachment As Outlook.Attachment
Dim objFSO As Scripting.FileSystemObject
Dim strNewName As String
' Use the FileSystemObject to get the extension
Set objFSO = New Scripting.FileSystemObject
' Make sure we have a mail item before proceeding
If Item.Class = Outlook.olMail Then
' Loop Through any attachments and look for a csv file
For Each objAttachment In Item.Attachments
Debug.Print objFSO.GetBaseName(objAttachment.FileName)
If objFSO.GetExtensionName(objAttachment.FileName) = "csv" Then
' Create the new file name
strNewName = "E:\EEtest\OOTest\" & objFSO.GetBaseName(objAttachment.FileName) & ".xls"
objAttachment.SaveAsFile (strNewName)
End If
Next
End If
End Sub
-Bear
Note that CSV isn't XLS, so you should not just change the file extension on save. It works, as Excel detects the real content, but you should not do that. The question is: Do you need an Excel file, or is CSV enough? E.g. it is possible to open Excel automatically with the CSV from Outlook VBA, and save as XLS(x).
Further, since you have different folders to maintain, I would use a more generic function of above:
Further, since you have different folders to maintain, I would use a more generic function of above:
Dim WithEvents mlItemsStaffA As Outlook.Items
Dim WithEvents mlItemsStaffB As Outlook.Items
' aso.
Private Sub Application_Startup()
Dim objNameSpace As Outlook.NameSpace
Dim objNewItems As Outlook.Items
Dim objFolders As Outlook.Folder
' Get Access to Outlook Folders
Set objNameSpace = Outlook.GetNamespace("MAPI")
' Get the particular folders we want to watch
' Set up the item objects so that they trigger the Item Add Event
Set mlItemsStaffA = objNameSpace.Folders("Personal Folders").Folders("StaffA").Items
Set mlItemsStaffB = objNameSpace.Folders("Personal Folders").Folders("StaffB").Items
' aso.
End Sub
Private Sub mlItemsStaffA_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, 'StaffA\')
End Sub
Private Sub mlItemsStaffB_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, 'StaffB\')
End Sub
Private Sub SaveAttachment(Item As Object, subfolder As String)
Dim objAttachment As Outlook.Attachment
Dim objFSO As Scripting.FileSystemObject
Dim strNewName As String
' Use the FileSystemObject to get the extension
Set objFSO = New Scripting.FileSystemObject
' Make sure we have a mail item before proceeding
If Item.Class = Outlook.olMail Then
' Loop Through any attachments and look for a csv file
For Each objAttachment In Item.Attachments
Debug.Print objFSO.GetBaseName(objAttachment.FileName)
If objFSO.GetExtensionName(objAttachment.FileName) = "csv" Then
' Create the new file name
strNewName = "\\server\share\" & subfolder & objFSO.GetBaseName(objAttachment.FileName) & ".csv"
objAttachment.SaveAsFile (strNewName)
End If
Next
End If
End Sub
ASKER
First of all, thanks for all of the suggestions and script you have post on this question. I really appreciate it... I do have one more question... Once I open the VB For applications using "ALT-F11" .. How do I set it so I can run it as a rule on my 2010 outlook client...
Application_Startup() is called when starting Outlook (resp. the application the sub is in). To activate the code without having to restart Outlook just put the cursor somewhere into that sub, and press F5. That should execute the code, and from then on the trigger code should work automatically whenever a mail is put into one of the monitored folders.
@Qlemo - nice changes to my code. I should have been more clear on the handling of the multiple folders. Also, excellent point on changing the extension.
If we keep the extensions the same then I would change this code:
@amstoots - You will still need your rule in outlook to move the email to your folder. This code then watches the folder for new email and triggers the code when one arrives. If all the attachments that will be sent to these folders are csv files or if we can assume that we can always save the attachment, then we can simplify the code even more. The subroutine could become:
As a side note, you will need to add a reference into your project to Microsoft Scripting Runtime if you keep the original code that looks for a csv file. (We could change to the code to late binding if you like)
Also you may need to self sign your macro depending on your security settings. This page has some old but still useful directions on how to accomplish that. I have attached a pdf of that website just in case that link ever dies.
self-sign-macro.pdf
If we keep the extensions the same then I would change this code:
strNewName = "\\server\share\" & subfolder & objFSO.GetBaseName(objAttachment.FileName) & ".csv"
TostrNewName = "\\server\share\" & subfolder & objAttachment.FileName
@amstoots - You will still need your rule in outlook to move the email to your folder. This code then watches the folder for new email and triggers the code when one arrives. If all the attachments that will be sent to these folders are csv files or if we can assume that we can always save the attachment, then we can simplify the code even more. The subroutine could become:
Private Sub SaveAttachment(Item As Object, subfolder As String)
Dim objAttachment As Outlook.Attachment
Dim strNewName As String
' Make sure we have a mail item before proceeding
If Item.Class = Outlook.olMail Then
' Loop Through any attachments and look for a csv file
For Each objAttachment In Item.Attachments
' Create the new file name
strNewName = "\\server\share\" & subfolder & objAttachment.FileName
objAttachment.SaveAsFile (strNewName)
Next
End If
End Sub
As a side note, you will need to add a reference into your project to Microsoft Scripting Runtime if you keep the original code that looks for a csv file. (We could change to the code to late binding if you like)
Also you may need to self sign your macro depending on your security settings. This page has some old but still useful directions on how to accomplish that. I have attached a pdf of that website just in case that link ever dies.
self-sign-macro.pdf
ASKER
ok.. I am just a little unsure here... after I open up VB for applications ( ALT+F11) , how would I add the "Application_Startup() " once I open up ThisOutlookSession... First time adding this type of code to outlook
outlook-pic.pdf
outlook-pic.pdf
Double-click ThisOutlookSession - you should get an empty window. Then just past the code, but change the mail and file folders, of course.
ASKER
Ok…Another quick question, when adding the outlook folders .. Should I add the name of the Folders where is says “Set mlItemsStaffA = objNameSpace.Folders("Pers onal Folders")” or should It be placed at “Folders("Region1").Items” .. Also I not for sure what I should put on the following string “call SaveAttachment(Item, 'StaffA\') ”…
Some of this assumes that the folders that you have are all personal folders in a personal .pst file. If not, then we may need more information.
So you will need to make a copy of this line
Also you will need to add this sub routine for each folder (I noticed an error in this code and changed the single quotes to double quotes):
The "StaffA\" would need to be the name of the sub folder in Windows explorer for each outlook folder where the file would be saved. This gets combined with the line "\\server\share\" to create the path. Please make sure that the path exists or this code will fail. We can add code to create the path if it is required.
So for example if you had three folders in Outlook for each of us (amstoots, Qlemo, Bear) you would need this code:
Then you need to make sure that where these files are going has folders for each of us. For example:
I hope this helps clarify some items.
-Bear
So you will need to make a copy of this line
Set mlItemsStaffA = objNameSpace.Folders("Personal Folders").Folders("StaffA").Items
for each folder that you have. Replace "STaffA" with the folder name in your personal folder. You can also rename the variable of mlItemsStaffA to something that makes more sense, but make sure you change it in all places.Also you will need to add this sub routine for each folder (I noticed an error in this code and changed the single quotes to double quotes):
Private Sub mlItemsStaffA_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, "StaffA\")
End Sub
The "StaffA\" would need to be the name of the sub folder in Windows explorer for each outlook folder where the file would be saved. This gets combined with the line "\\server\share\" to create the path. Please make sure that the path exists or this code will fail. We can add code to create the path if it is required.
So for example if you had three folders in Outlook for each of us (amstoots, Qlemo, Bear) you would need this code:
Private Sub Application_Startup()
Dim objNameSpace As Outlook.NameSpace
Dim objNewItems As Outlook.Items
Dim objFolders As Outlook.Folder
' Get Access to Outlook Folders
Set objNameSpace = Outlook.GetNamespace("MAPI")
' Get the particular folders we want to watch
' Set up the item objects so that they trigger the Item Add Event
Set mlItemsamstoots = objNameSpace.Folders("Personal Folders").Folders("amstoots").Items
Set mlItemsQlemo = objNameSpace.Folders("Personal Folders").Folders("Qlemo").Items
Set mlItemsBear = objNameSpace.Folders("Personal Folders").Folders("Bear").Items
' aso.
End Sub
Private Sub mlItemsamstoots_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, "amstoots\")
End Sub
Private Sub mlItemsQlemo_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, "Qlemo\")
End Sub
Private Sub mlItemsBear_ItemAdd(ByVal Item As Object)
call SaveAttachment(Item, "Bear\")
End Sub
Then you need to make sure that where these files are going has folders for each of us. For example:
\\192.168.1.100\csvfiles\a mstoots
\\192.168.1.100\csvfiles\Q lemo
\\192.168.1.100\csvfiles\B ear
I hope this helps clarify some items.
-Bear
(I noticed an error in this code and changed the single quotes to double quotes)
Ooops. Well put, all that, ltlbearand3.
BTW, in Outlook VBA you do not need to use
amstoots, of course you could provide the complete path instead of a subfolder if you need to store the attachments into completely different locations, or if you like to have that complete path in the call for visibility.
Ooops. Well put, all that, ltlbearand3.
BTW, in Outlook VBA you do not need to use
Set objNameSpace = Outlook.GetNamespace("MAPI")
as Outlook.Session or Session provides exactly that. Using that, the startup code would be:Private Sub Application_Startup()
' Get the particular folders we want to watch
' Set up the item objects so that they trigger the Item Add Event
Set mlItemsamstoots = Sessopm.Folders("Personal Folders").Folders("amstoots").Items
Set mlItemsQlemo = Session.Folders("Personal Folders").Folders("Qlemo").Items
Set mlItemsBear = Session.Folders("Personal Folders").Folders("Bear").Items
' aso.
End Sub
amstoots, of course you could provide the complete path instead of a subfolder if you need to store the attachments into completely different locations, or if you like to have that complete path in the call for visibility.
Cool. Thanks for the tip on the outlook.session object. I was not aware of it. [One of the great things about EE - I learn even when answering questions].
ASKER
Thanks for everybody help in this script so fare..... I have learned a lot so fore... currently I ran in to a problem where is not seeing the object " The Attempted operation failed. An object could not be found" It looks to be getting stuck on the first "set Set mlItemsRegion1" for some reason... I have attached script error, screenshot of my Mailbox tree on my client, and screen shot of the debug showing the string in yellow highlight. It says it not able to find the object... am i updating it incorrectly
outlookscriptscreenshot.jpg
EmailMailboxTree.jpg
Private Sub Application_Startup()
Dim objNameSpace As Outlook.NameSpace
Dim objNewItems As Outlook.Items
Dim objFolders As Outlook.Folder
' Get Access to Outlook Folders
Set objNameSpace = Outlook.GetNamespace("MAPI")
' Get the particular folders we want to watch
' Set up the item objects so that they trigger the Item Add Event
Set mlItemsRegion1 = objNameSpace.Folders("Personal Folders").Folders("Region1").Items
Set mlItemsRegion2 = objNameSpace.Folders("Personal Folders").Folders("Region2").Items
Set mlItemsRegion3 = objNameSpace.Folders("Personal Folders").Folders("Region3").Items
' aso.
End Sub
Private Sub mlItemsRegion1_ItemAdd(ByVal Item As Object)
Call SaveAttachment(Item, "Region1\")
End Sub
Private Sub mlItemsRegion2_ItemAdd(ByVal Item As Object)
Call SaveAttachment(Item, "Region2\")
End Sub
Private Sub mlItemsRegion3_ItemAdd(ByVal Item As Object)
Call SaveAttachment(Item, "Region3\")
End Sub
Private Sub SaveAttachment(Item As Object, subfolder As String)
Dim objAttachment As Outlook.Attachment
Dim strNewName As String
' Make sure we have a mail item before proceeding
If Item.Class = Outlook.olMail Then
' Loop Through any attachments and look for a csv file
For Each objAttachment In Item.Attachments
' Create the new file name
strNewName = "\\10.9.41.160\home_hlichrvaw3-ad1\mstoots\Completed Reports\EPO Reports\SQL EPOReportsLast24hrs Database portal\Region 1" & subfolder & objAttachment.FileName
strNewName = "\\10.9.41.160\home_hlichrvaw3-ad1\mstoots\Completed Reports\EPO Reports\SQL EPOReportsLast24hrs Database portal\Region 2" & subfolder & objAttachment.FileName
strNewName = "\\10.9.41.160\home_hlichrvaw3-ad1\mstoots\Completed Reports\EPO Reports\SQL EPOReportsLast24hrs Database portal\Region 3" & subfolder & objAttachment.FileName
objAttachment.SaveAsFile (strNewName)
Next
End If
End Sub
Outlookscripterrormessage.jpgoutlookscriptscreenshot.jpg
EmailMailboxTree.jpg
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I updated my script with what you suggested and did not get any error messages, but its not moving any of the attachments located in one of the 3 public folders. I not for sure if the script is running when close and reopen outlook client.... do I need to set up the script throw a rule for it to specified account. or do I need to wait for new mail to com in... thanks for all of your help in advance...
Private Sub Application_Startup()
Dim mlItemsRegion1 As Object
Dim mlItemsRegion2 As Object
Dim mlItemsRegion3 As Object
' Get the particular folders we want to watch
' Set up the item objects so that they trigger the Item Add Event
Set mlItemsRegion1 = Outlook.Session.Folders("Mailbox - Stoots, Mike").Folders("Region1").Items
Set mlItemsRegion2 = Outlook.Session.Folders("Mailbox - Stoots, Mike").Folders("Region2").Items
Set mlItemsRegion3 = Outlook.Session.Folders("Mailbox - Stoots, Mike").Folders("Region3").Items
End Sub
Private Sub mlItemsRegion1_ItemAdd(ByVal item As Object)
Call SaveAttachment(item, "Region1\")
End Sub
Private Sub mlItemsRegion2_ItemAdd(ByVal item As Object)
Call SaveAttachment(item, "Region2\")
End Sub
Private Sub mlItemsRegion3_ItemAdd(ByVal item As Object)
Call SaveAttachment(item, "Region3\")
End Sub
Private Sub SaveAttachment(item As Object, subfolder As String)
Dim objAttachment As Outlook.Attachment
Dim strNewName As String
' Make sure we have a mail item before proceeding
If item.Class = Outlook.olMail Then
' Loop Through any attachments and save to network drive
For Each objAttachment In item.Attachments
' Create the new file name
strNewName = "\\10.9.41.160\home_hlichrvaw3-ad1\mstoots\Completed Reports\EPO Reports\SQL EPOReportsLast24hrs Database portal\" & subfolder & objAttachment.FileName
objAttachment.SaveAsFile (strNewName)
item.Move item.Parent.Folders(1)
Next
End If
End Sub
Starting Outlook is sufficient to activate the code. But it only works for new mails. If you want to test, move mails out of the folder, and copy one back into it (moving does not always trigger the ItemAdd event). The attachment contained should be saved.
If you want to be sure whether the code is really executed, locate your cursor on a line within the SaveAttachment sub containing executive code (no DIM or Comment line), press F9, and then perform above test. Execution should halt at that line. Then press F9 again (to delete the breakpoint), and F5 to continue execution.
That is the basic method to start tests.
If you want to be sure whether the code is really executed, locate your cursor on a line within the SaveAttachment sub containing executive code (no DIM or Comment line), press F9, and then perform above test. Execution should halt at that line. Then press F9 again (to delete the breakpoint), and F5 to continue execution.
That is the basic method to start tests.
ASKER
Sorry for getting back to you guys so late.. the script works great and moves the excel files w/o any problem...... thanks...
http://chris.dziemborowicz.com/blog/2013/05/18/how-to-batch-extract-attachments-from-msg-files-using-powershell/
Will.