Outlook not saving attachment via VBA - vba

I have some VBA code that actually works fine on my machine, but not my clients. Where it gets hung up is the opening of an email attachment and saving it to a location on his computer.
For Each nm in file_names 'file_names is just an array of strings
found_file=False
curr_date=CDate("1-1-9999")
For Each olItem in olItems
If olItem.ReceivedTime < curr_date and olItem.SenderEmailAddress=email and TypeName(olItem)="MailItem" then
Set olAttach=olItem.attachments.Item(1)
If not olAttach is Nothing then
If olAttach.Filename Like nm & ".*" then
found_file=True
curr_date=olItem.ReceivedTime
end if
end if
end if
Next
If found_file then
olAttach.SaveAsFile pth & olAttach.Filename 'errors out here
...
The error message is Cannot save the attachment and does not specify a reason.
I have tried to have him enable all macros, switch off protected view options, restart excel and outlook, try different file locations to save to, there are no double \ that occur when file path is concatenated with the file name, and I made sure he wasn't using a Mac. Apparently one of the attachment files does open but it just refuses to save.

Looks like the file path/name string passed to the SaveAsFile method is not a well-formed path. For example, the FileName may contains forbidden symbols and etc. Try to use the following code as a test:
Sub SaveAttachment()
Dim myInspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myInspector = Application.ActiveInspector
If Not TypeName(myInspector) = "Nothing" Then
If TypeName(myInspector.CurrentItem) = "MailItem" Then
Set myItem = myInspector.CurrentItem
Set myAttachments = myItem.Attachments
'Prompt the user for confirmation
Dim strPrompt As String
strPrompt = "Are you sure you want to save the first attachment in the current item to the Documents folder? If a file with the same name already exists in the destination folder, it will be overwritten with this copy of the file."
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
myAttachments.Item(1).SaveAsFile Environ("HOMEPATH") & "\My Documents\" & _
myAttachments.Item(1).DisplayName
End If
Else
MsgBox "The item is of the wrong type."
End If
End If
End Sub

Related

excel attached email automatically saved in a folder

I would like, thanks to a code, that as soon as I receive an email from a certain person that the attachment of this email is automatically saved in a folder "TEST" here, then that the email is marked as read and then filed. Here is what I could find online but it does not work. I have no error message but I have no record either.
Can you please help me
Sub extrait_PJ_vers_rep(strID As Outlook.MailItem)
Dim olNS As Outlook.namespace
Dim MyMail As Outlook.MailItem
Dim expediteur
Set olNS = Application.GetNamespace("MAPI")
Set MyMail = olNS.GetItemFromID(strID.EntryID)
If MyMail.Attachments.Count > 0 Then
expediteur = MyMail.SenderEmailAddress
Repertoire = "c:\TEST" & "\"
If Repertoire <> "" Then
If "" = Dir(Repertoire, vbDirectory) Then
MkDir Repertoire
End If
End If
Dim PJ, typeatt
For Each PJ In MyMail.Attachments
typeatt = Isembedded(strID, PJ.Index)
If typeatt = "" Then
If "" <> Dir(Repertoire & PJ.FileName, vbNormal) Then
MsgBox Repertoire & PJ.FileName & " Done before"
If "" = Dir(Repertoire & "old", vbDirectory) Then
MkDir Repertoire & "old"
End If
FileCopy Repertoire & PJ.FileName, Repertoire & "old\" & PJ.FileName
End If
PJ.SaveAsFile Repertoire & PJ.FileName
End If
Next PJ
MyMail.UnRead = False
MyMail.Save
Dim myDestFolder As Outlook.MAPIFolder
Set myDestFolder = MyMail.Parent.Folders("test")
MyMail.Move myDestFolder
End If
Set MyMail = Nothing
Set olNS = Nothing
End Sub
I would like, thanks to a code, that as soon as I receive an email from a certain person that the attachment of this email is automatically saved in a folder "TEST" here, then that the email is marked as read and then filed
The code does exactly what you need, you just need to hook up the NewMailEx event of the Outlook Application class which is fired when a new message arrives in the Inbox and before client rule processing occurs. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item. Use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item, like you do in the code.
Go to the VBA environment in Outlook, select the Application on the lef-hand side dropdown list like shown on the screenshot:
Then you can add the NewMailEx event handler:
Viola! The event handler will be added, you just need to paste your code here.

Email generator called from Application_NewMail is generating duplicate emails

I have this macro which picks the file (pdf) out of a specified folder and then emails it as an attachment.
It is running via Application_NewMail and then links to an Excel file where the pdf is created and saved.
It works but the attachment is sent twice in two separate emails - I thought about writing another macro to remove duplicate emails but I am afraid this might delete emails I do not want to delete.
Folder path and email address have been replaced by placeholders.
Sub Any_help_appreciated()
Dim objMail As Outlook.MailItem
Dim fso As Object 'Scripting.FileSystemObject
Dim strFile As String
Dim fsoFile 'As Scripting.File
Dim fsoFldr 'As Scripting.Folder
Dim dtNew As Date, sNew As String
Set fso = CreateObject("Scripting.FileSystemObject")
strFile = "FOLDER PATH" 'path to pdf folder
Set fsoFldr = fso.GetFolder(strFile)
dtNew = Now - TimeValue("00:00:30") 'select pdf if created in last 30 secs
For Each fsoFile In fsoFldr.Files
If fsoFile.DateCreated > dtNew Then
sNew = fsoFile.Path
Set objMail = Application.CreateItem(olMailItem)
With objMail
.To = "email.address#email.com"
.Subject = "Subject"
.BodyFormat = olFormatPlain
.Attachments.Add sNew
.Send ' .send
End With
End If
Next fsoFile
End Sub
You get two emails because Application_NewMail event handler gets executed twice and two emails are sent consecutively (only two because it takes some time before server processes the e-mail). I guess it is because .To value of email.address#email.com is your email account for testing.
Try to add some check if the code for objMail.Send does get executed twice like writing something to a text file, log etc.
Or move the PDF file to a different folder after processing it.

Extract attachement from Outlook Contacts

I'm wondering if anyone managed to build a code to extract attachements within Outlook contacts? I have a lot of contacts in my outlook 2010 with several attachements and would like to create a copy for backup. Also, if an automated way exist, is it possible to link the downloaded attachement to the contacts?
update
I have used several pieces of code to do what i want but getting a "User-defined type not defined". Anyone know hoe to avoid that error?
Option Explicit
Sub GetAttachments()
Dim ns As Outlook.NameSpace
Dim contactFolder As Outlook.MAPIFolder
Dim myItem As Outlook.Item
Dim ContactItem As Object
Dim Attmt As Outlook.Attachments
Dim FileName As String
Dim i As Integer
Set ns = Application.GetNamespace("MAPI")
Set contactFolder = ns.GetDefaultFolder(olFolderContacts)
Set myItem = contactFolder.Items
Set Attmt = myItem.Attachments
i = 0
' Check each contacts for attachments
For Each ContactItem In contactFolder.Items
' Save any attachments found
For Each Attmt In ContactItem.Attachments
' This path must exist! Change folder name as necessary.
FileName = "C:\Temp\" & Attmt.FileName
Attmt.SaveAsFile FileName
i = i + 1
Next Attmt
Next ContactItem
End Sub
Use ContactItem.Attachments collection. To save an attachment, call Attachment.SaveAsFile.
You can develop a VBA macro or add-in to get the job done. Be aware, VBA macros are not designed for distributing the solution on multiple PCs. See Getting Started with VBA in Outlook 2010 for more information about VBA macros in Outlook.
If you need to automate Outlook from another applications, see How to automate Outlook by using Visual Basic.
As Dmitry suggested, you can use the SaveAsFile method of the Attachment class to save the attached file on the disk.
Sub SaveAttachment()
Dim myInspector As Outlook.Inspector
Dim myItem As Outlook.ContactItem
Dim myAttachments As Outlook.Attachments
Set myInspector = Application.ActiveInspector
If Not TypeName(myInspector) = "Nothing" Then
If TypeName(myInspector.CurrentItem) = "ContactItem" Then
Set myItem = myInspector.CurrentItem
Set myAttachments = myItem.Attachments
'Prompt the user for confirmation
Dim strPrompt As String
strPrompt = "Are you sure you want to save the first attachment in the current item to the Documents folder? If a file with the same name already exists in the destination folder, it will be overwritten with this copy of the file."
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
myAttachments.Item(1).SaveAsFile Environ("HOMEPATH") & "\My Documents\" & _
myAttachments.Item(1).DisplayName
End If
Else
MsgBox "The item is of the wrong type."
End If
End If
End Sub
To attach a file anew you can use the Add method of the Attachments class which creates a new attachment in the Attachments collection.
Sub AddAttachment()
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myItem = Application.CreateItem(olMailItem)
Set myAttachments = myItem.Attachments
myAttachments.Add "C:\Test.doc", _
olByValue, 1, "Test"
myItem.Display
End Sub

Outlook Rule Save email to text

I'm having trouble with automatically exporting the body of an email into a text file using a script.
I've managed a script that will save the text into a file on a macro but that won't work on a rule which is what I need.
My current code is as follows:
Sub SaveAsTXT()
Dim myItem As Outlook.Inspector
Dim objItem As Object
Dim myFolder As Folder
Set myItem = Application.ActiveInspector
If Not TypeName(myItem) = "Nothing" Then
Set myNamespace = Application.GetNamespace("MAPI")
Set myFolder = myNamespace.GetDefaultFolder(olFolderInbox)
Set objItem = myItem.CurrentItem
strname = objItem.Subject
strdate = Format(objItem.ReceivedTime, " yyyy mm dd")
objItem.SaveAs "c:\users\philip\documents\" & strname & strdate & ".txt", olTXT
End If
End Sub
Apologies if it looks a bit messy, I've edited it countless times trying to get it to work.
That's the code that will correctly run when I'm in the open email and run it as a macro but it won't work correctly when run as a rule
I have tried amending to Sub SaveAsTXT(Item as Outlook.Mailitem) but this also doesn't seem to work
So basically the question is how to I ensure the code will select the email (which will always be entitled "Rotas" without quotes) when it is run as a rule?
Info: Using office 2010 and I'm not a very good coder to start with.
Actually I managed to sort it out myself.
I didn't consider that the item as Outlook.Mailitem element was actually the thing that was selected by the rule. So I applied item as the object rather than objItem
Find the successful (and cleaned up) code below:
Sub SaveAsTXT(myMail As Outlook.MailItem)
Dim objItem As Object
Dim myFolder As Folder
If Not TypeName(myitem) = "Nothing" Then
If myMail.Subject = "Rotas" Then
strname = myMail.Subject
strdate = Format(myMail.ReceivedTime, " yyyy mm dd")
myMail.SaveAs "c:\users\philip\documents\" & strname & ".txt", olTXT
End If
End If
End Sub

Save outlook attachments and rename/append files with identifier from subject line

Im really new to VBA and need some help. I'm trying to write a VBA script (along with a Outlook rule) to automatically download attachments from daily emails and append the file names with the date that appears in the subject.
This is what the subject line looks like - "Email Alert for Department for 10/20/2014". I just need to isolate the rightmost 10 spaces that indicates the run date of the files.
So I found code online that works to automatically download the attachments and append by current date which does work. See below.
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim dateFormat
dateFormat = Format(Now, "yyyymmdd ")
saveFolder = "Z:\Daily Emails"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & dateFormat & objAtt.DisplayName
Set objAtt = Nothing
Next
End Sub
I also found online that something like this should point to the date (formatted like XX/XX/XXXX and always at the end of the subject line.
Subject = Right(itm.Subject, 10) but im having trouble incorporating it into the code above.
Can anyone help me? It would mean a lot
Thanks!
-Christina
Using Rules to run a macro is good.
I used the same set up before. The problem is if you are to work on the newly received mail, the sub wouldn't trap it. If you need to save the attachment of an incoming email with Email Alert for Department for mm/dd/yyyy as subject, try using an event instead. By default, Outlook doesn't provide Items Event so you'll have to create it.
In your ThisOutlookSession (not in a module) try something like:
Option Explicit
Private WithEvents olIBoxItem As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim olFolder As Outlook.MAPIFolder
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
'~~> change olFolder depending on what folder you're receiving the email
'~~> I assumed it is Outlook's default folder Inbox
Set olIBoxItem = olFolder.Items
End Sub
Private Sub olIBoxItem_ItemAdd(ByVal Item As Object)
Const strSub As String = "Email Alert for Department for "
If TypeOf Item Is Outlook.MailItem Then
Dim nMail As Outlook.MailItem
Set nMail = Item
If InStr(nMail.Subject, strSub) <> 0 Then
Const savefolder As String = "Z:\Details Mail\"
'~~> Extract your date
Dim dateSub As String: dateSub = Right(nMail.Subject, 10)
'~~> Make sure there is an attachment
If nMail.Attachments.Count > 0 Then
Dim olAtt As Outlook.Attachment
Set olAtt = nMail.Attachments.Item(1) '~~> if you only have 1
Dim attFName As String, addFExt As String
'~~> Get the filename and extension separately
attFName = Split(olAtt.Filename, ".")(0)
attFExt = Split(olAtt.Filename, ".")(1)
'~~> Reconstruct the filename
attFName = savefolder & attFName & " " & dateSub & attFExt
'~~> Save the attachment
olAtt.SaveAsFile attFName
End If
End If
End If
End Sub
So above routine automatically checks any received mail in the Inbox Folder. If the subject contains the specified string. If yes, it automatically saves the attachment.
If however you have more than one attachment, you'll have to look through it and then save each one. It may look confusing at first but you'll get the hang of it for sure. HTH.