Saving and renaming an Outlook attachment with static name on format xlsx
I'm trying to save the daily system generated report attached to the e-mail to a folder.
My script saves and renames the file, but when I try to open the file it says:
The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt.
Below the script:
Public Sub UnzipFileInOutlook(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
End Sub
outlook outlook-vba
add a comment |
I'm trying to save the daily system generated report attached to the e-mail to a folder.
My script saves and renames the file, but when I try to open the file it says:
The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt.
Below the script:
Public Sub UnzipFileInOutlook(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
End Sub
outlook outlook-vba
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
I believe the easiest correction is to replace"Order_History_Report.xlsx"
with"" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.
– Tony Dallimore
Nov 14 '18 at 12:55
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57
add a comment |
I'm trying to save the daily system generated report attached to the e-mail to a folder.
My script saves and renames the file, but when I try to open the file it says:
The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt.
Below the script:
Public Sub UnzipFileInOutlook(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
End Sub
outlook outlook-vba
I'm trying to save the daily system generated report attached to the e-mail to a folder.
My script saves and renames the file, but when I try to open the file it says:
The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt.
Below the script:
Public Sub UnzipFileInOutlook(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
End Sub
outlook outlook-vba
outlook outlook-vba
asked Nov 14 '18 at 11:28
felipe gomesfelipe gomes
1
1
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
I believe the easiest correction is to replace"Order_History_Report.xlsx"
with"" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.
– Tony Dallimore
Nov 14 '18 at 12:55
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57
add a comment |
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
I believe the easiest correction is to replace"Order_History_Report.xlsx"
with"" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.
– Tony Dallimore
Nov 14 '18 at 12:55
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
I believe the easiest correction is to replace
"Order_History_Report.xlsx"
with "" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.– Tony Dallimore
Nov 14 '18 at 12:55
I believe the easiest correction is to replace
"Order_History_Report.xlsx"
with "" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.– Tony Dallimore
Nov 14 '18 at 12:55
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57
add a comment |
1 Answer
1
active
oldest
votes
I do not understand: “When I use the code objAtt.SaveAsFile saveFolder
only, the file isn't corrupted.”
Unless I include a filename in the path, SaveAsFile
always stops with an error for me. I have tried every variation that I can think of but none will save the file.
I have never had SaveAsFile
corrupt a file. My theory is your emails have more than one attachment and you are saving the wrong one. Your code it:
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
If the email has two attachments, this code will:
- Save the first attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting any file of this name retained from yesterday.
- Save the second attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting the first attachment.
Most emails today use Html images for logos and pictures but a few still use embedded images which are carried as attachments but not reported to the user as attachments.
The code below will test my theory. Copy this code to a new module:
Option Explicit
Public Sub InvestigateEmails()
Dim Exp As Explorer
Dim InxA As Long
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From (Sender email address): " & .SenderEmailAddress
Debug.Print "Subject: " & .Subject
Debug.Print "Sent on: " & .SentOn
Debug.Print "Received: " & .ReceivedTime
If .Attachments.Count = 0 Then
Debug.Print "No attachments"
Else
Debug.Print "Attachments:"
Debug.Print "No.|Type|Path|Filename|DisplayName|"
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print InxA & "|";
Select Case .Type
Case olByValue
Debug.Print "Val";
Case olEmbeddeditem
Debug.Print "Ebd";
Case olByReference
Debug.Print "Ref";
Case olOLE
Debug.Print "OLE";
Case Else
Debug.Print "Unk;"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Type
Case olEmbeddeditem
Debug.Print "|";
Case Else
Debug.Print "|" & .PathName;
End Select
Debug.Print "|" & .Filename;
Debug.Print "|" & .DisplayName & "|"
End With
Next
End If
Debug.Print "--------------------------"
End With
Next
End If
End Sub
To use this code, select one or more of the emails you wish to process and then run InvestigateEmails
. It will output a selection of properties for each selected email. Your Immediate window will look something like:
From (Sender email address): a.j.dallimore@MyIsp.com
Subject: Test
Sent on: 15/11/2018 11:22:41
Received: 15/11/2018 11:22:49
Attachments:
No.|Type|Path|Filename|DisplayName|
1|Val||002 View from back of Neville Tower.jpg|002 View from back of Neville Tower.jpg|
2|Val||image001.jpg|image001.jpg|
--------------------------
I sent the above email to myself. Attachment 1 was a regular attachment that was listed in the header and could be dragged to a folder or clicked to open it. Attachment 2 was embedded and appeared as a picture in the body of the email but was not listed in the header.
My theory is that given one of your emails, InvestigateEmails
will list more than one attachment per email and the last attachment will not be an Excel workbook. You save that attachment with an extension of “xlsx” so Excel tries and fails to open it.
By the way, I use this routine whenever I am developed new code to process emails. I might plan for my new code to run off an event or a rule but this routine makes testing so much easier. I amend this code to call my new code and select a simple email. When I have debugged my code to work with a simple email, I try a more complicated one. There is no easier way of controlling which emails are passed to a macro for processing. I suggest you keep this macro for future use. Alternatively, I can tell you where to find a larger version which outputs to a desktop text file.
The rest of this answer assumes my theory is correct. If my theory is wrong, we may need to investigate further.
Before showing you how to save the correct attachment with a static file name, I will say that I doubt this is a good idea. If I understand correctly, each day you receive a workbook which overwrites the previous day’s workbook. You extract data from the workbook and save it in your database. This may seem like a good idea but this can go disastrously wrong. Years’ ago, I knew of a similar situation although, thankfully, I was not personally involved. Like you, they were receiving files, extracting data and then discarding the files. This all seemed to work for some months but they then discovered that the data was not being extracted correctly. If they had kept the original source files, fixing their database would have been difficult but possible. But without the original data, there was nothing they could do.
I recommend you save your files with a name like: “Order_History_Report 181115.xlsx”. This will allow you to archive all the original files against any future need to reprocess them. Processing a file with a name like this is a little more difficult but I can explain how to do this.
Returning to your code, the easiest correction is:
For Each objAtt In itm.Attachments
If LCase(Right$(objAtt.DisplayName, 4)) = ".xlsx" Then
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Exit For
End If
Next
This code ignores any attachments that are not regular workbooks and, once it has found a regular workbook, it does not look for more.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53299166%2fsaving-and-renaming-an-outlook-attachment-with-static-name-on-format-xlsx%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I do not understand: “When I use the code objAtt.SaveAsFile saveFolder
only, the file isn't corrupted.”
Unless I include a filename in the path, SaveAsFile
always stops with an error for me. I have tried every variation that I can think of but none will save the file.
I have never had SaveAsFile
corrupt a file. My theory is your emails have more than one attachment and you are saving the wrong one. Your code it:
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
If the email has two attachments, this code will:
- Save the first attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting any file of this name retained from yesterday.
- Save the second attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting the first attachment.
Most emails today use Html images for logos and pictures but a few still use embedded images which are carried as attachments but not reported to the user as attachments.
The code below will test my theory. Copy this code to a new module:
Option Explicit
Public Sub InvestigateEmails()
Dim Exp As Explorer
Dim InxA As Long
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From (Sender email address): " & .SenderEmailAddress
Debug.Print "Subject: " & .Subject
Debug.Print "Sent on: " & .SentOn
Debug.Print "Received: " & .ReceivedTime
If .Attachments.Count = 0 Then
Debug.Print "No attachments"
Else
Debug.Print "Attachments:"
Debug.Print "No.|Type|Path|Filename|DisplayName|"
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print InxA & "|";
Select Case .Type
Case olByValue
Debug.Print "Val";
Case olEmbeddeditem
Debug.Print "Ebd";
Case olByReference
Debug.Print "Ref";
Case olOLE
Debug.Print "OLE";
Case Else
Debug.Print "Unk;"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Type
Case olEmbeddeditem
Debug.Print "|";
Case Else
Debug.Print "|" & .PathName;
End Select
Debug.Print "|" & .Filename;
Debug.Print "|" & .DisplayName & "|"
End With
Next
End If
Debug.Print "--------------------------"
End With
Next
End If
End Sub
To use this code, select one or more of the emails you wish to process and then run InvestigateEmails
. It will output a selection of properties for each selected email. Your Immediate window will look something like:
From (Sender email address): a.j.dallimore@MyIsp.com
Subject: Test
Sent on: 15/11/2018 11:22:41
Received: 15/11/2018 11:22:49
Attachments:
No.|Type|Path|Filename|DisplayName|
1|Val||002 View from back of Neville Tower.jpg|002 View from back of Neville Tower.jpg|
2|Val||image001.jpg|image001.jpg|
--------------------------
I sent the above email to myself. Attachment 1 was a regular attachment that was listed in the header and could be dragged to a folder or clicked to open it. Attachment 2 was embedded and appeared as a picture in the body of the email but was not listed in the header.
My theory is that given one of your emails, InvestigateEmails
will list more than one attachment per email and the last attachment will not be an Excel workbook. You save that attachment with an extension of “xlsx” so Excel tries and fails to open it.
By the way, I use this routine whenever I am developed new code to process emails. I might plan for my new code to run off an event or a rule but this routine makes testing so much easier. I amend this code to call my new code and select a simple email. When I have debugged my code to work with a simple email, I try a more complicated one. There is no easier way of controlling which emails are passed to a macro for processing. I suggest you keep this macro for future use. Alternatively, I can tell you where to find a larger version which outputs to a desktop text file.
The rest of this answer assumes my theory is correct. If my theory is wrong, we may need to investigate further.
Before showing you how to save the correct attachment with a static file name, I will say that I doubt this is a good idea. If I understand correctly, each day you receive a workbook which overwrites the previous day’s workbook. You extract data from the workbook and save it in your database. This may seem like a good idea but this can go disastrously wrong. Years’ ago, I knew of a similar situation although, thankfully, I was not personally involved. Like you, they were receiving files, extracting data and then discarding the files. This all seemed to work for some months but they then discovered that the data was not being extracted correctly. If they had kept the original source files, fixing their database would have been difficult but possible. But without the original data, there was nothing they could do.
I recommend you save your files with a name like: “Order_History_Report 181115.xlsx”. This will allow you to archive all the original files against any future need to reprocess them. Processing a file with a name like this is a little more difficult but I can explain how to do this.
Returning to your code, the easiest correction is:
For Each objAtt In itm.Attachments
If LCase(Right$(objAtt.DisplayName, 4)) = ".xlsx" Then
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Exit For
End If
Next
This code ignores any attachments that are not regular workbooks and, once it has found a regular workbook, it does not look for more.
add a comment |
I do not understand: “When I use the code objAtt.SaveAsFile saveFolder
only, the file isn't corrupted.”
Unless I include a filename in the path, SaveAsFile
always stops with an error for me. I have tried every variation that I can think of but none will save the file.
I have never had SaveAsFile
corrupt a file. My theory is your emails have more than one attachment and you are saving the wrong one. Your code it:
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
If the email has two attachments, this code will:
- Save the first attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting any file of this name retained from yesterday.
- Save the second attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting the first attachment.
Most emails today use Html images for logos and pictures but a few still use embedded images which are carried as attachments but not reported to the user as attachments.
The code below will test my theory. Copy this code to a new module:
Option Explicit
Public Sub InvestigateEmails()
Dim Exp As Explorer
Dim InxA As Long
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From (Sender email address): " & .SenderEmailAddress
Debug.Print "Subject: " & .Subject
Debug.Print "Sent on: " & .SentOn
Debug.Print "Received: " & .ReceivedTime
If .Attachments.Count = 0 Then
Debug.Print "No attachments"
Else
Debug.Print "Attachments:"
Debug.Print "No.|Type|Path|Filename|DisplayName|"
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print InxA & "|";
Select Case .Type
Case olByValue
Debug.Print "Val";
Case olEmbeddeditem
Debug.Print "Ebd";
Case olByReference
Debug.Print "Ref";
Case olOLE
Debug.Print "OLE";
Case Else
Debug.Print "Unk;"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Type
Case olEmbeddeditem
Debug.Print "|";
Case Else
Debug.Print "|" & .PathName;
End Select
Debug.Print "|" & .Filename;
Debug.Print "|" & .DisplayName & "|"
End With
Next
End If
Debug.Print "--------------------------"
End With
Next
End If
End Sub
To use this code, select one or more of the emails you wish to process and then run InvestigateEmails
. It will output a selection of properties for each selected email. Your Immediate window will look something like:
From (Sender email address): a.j.dallimore@MyIsp.com
Subject: Test
Sent on: 15/11/2018 11:22:41
Received: 15/11/2018 11:22:49
Attachments:
No.|Type|Path|Filename|DisplayName|
1|Val||002 View from back of Neville Tower.jpg|002 View from back of Neville Tower.jpg|
2|Val||image001.jpg|image001.jpg|
--------------------------
I sent the above email to myself. Attachment 1 was a regular attachment that was listed in the header and could be dragged to a folder or clicked to open it. Attachment 2 was embedded and appeared as a picture in the body of the email but was not listed in the header.
My theory is that given one of your emails, InvestigateEmails
will list more than one attachment per email and the last attachment will not be an Excel workbook. You save that attachment with an extension of “xlsx” so Excel tries and fails to open it.
By the way, I use this routine whenever I am developed new code to process emails. I might plan for my new code to run off an event or a rule but this routine makes testing so much easier. I amend this code to call my new code and select a simple email. When I have debugged my code to work with a simple email, I try a more complicated one. There is no easier way of controlling which emails are passed to a macro for processing. I suggest you keep this macro for future use. Alternatively, I can tell you where to find a larger version which outputs to a desktop text file.
The rest of this answer assumes my theory is correct. If my theory is wrong, we may need to investigate further.
Before showing you how to save the correct attachment with a static file name, I will say that I doubt this is a good idea. If I understand correctly, each day you receive a workbook which overwrites the previous day’s workbook. You extract data from the workbook and save it in your database. This may seem like a good idea but this can go disastrously wrong. Years’ ago, I knew of a similar situation although, thankfully, I was not personally involved. Like you, they were receiving files, extracting data and then discarding the files. This all seemed to work for some months but they then discovered that the data was not being extracted correctly. If they had kept the original source files, fixing their database would have been difficult but possible. But without the original data, there was nothing they could do.
I recommend you save your files with a name like: “Order_History_Report 181115.xlsx”. This will allow you to archive all the original files against any future need to reprocess them. Processing a file with a name like this is a little more difficult but I can explain how to do this.
Returning to your code, the easiest correction is:
For Each objAtt In itm.Attachments
If LCase(Right$(objAtt.DisplayName, 4)) = ".xlsx" Then
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Exit For
End If
Next
This code ignores any attachments that are not regular workbooks and, once it has found a regular workbook, it does not look for more.
add a comment |
I do not understand: “When I use the code objAtt.SaveAsFile saveFolder
only, the file isn't corrupted.”
Unless I include a filename in the path, SaveAsFile
always stops with an error for me. I have tried every variation that I can think of but none will save the file.
I have never had SaveAsFile
corrupt a file. My theory is your emails have more than one attachment and you are saving the wrong one. Your code it:
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
If the email has two attachments, this code will:
- Save the first attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting any file of this name retained from yesterday.
- Save the second attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting the first attachment.
Most emails today use Html images for logos and pictures but a few still use embedded images which are carried as attachments but not reported to the user as attachments.
The code below will test my theory. Copy this code to a new module:
Option Explicit
Public Sub InvestigateEmails()
Dim Exp As Explorer
Dim InxA As Long
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From (Sender email address): " & .SenderEmailAddress
Debug.Print "Subject: " & .Subject
Debug.Print "Sent on: " & .SentOn
Debug.Print "Received: " & .ReceivedTime
If .Attachments.Count = 0 Then
Debug.Print "No attachments"
Else
Debug.Print "Attachments:"
Debug.Print "No.|Type|Path|Filename|DisplayName|"
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print InxA & "|";
Select Case .Type
Case olByValue
Debug.Print "Val";
Case olEmbeddeditem
Debug.Print "Ebd";
Case olByReference
Debug.Print "Ref";
Case olOLE
Debug.Print "OLE";
Case Else
Debug.Print "Unk;"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Type
Case olEmbeddeditem
Debug.Print "|";
Case Else
Debug.Print "|" & .PathName;
End Select
Debug.Print "|" & .Filename;
Debug.Print "|" & .DisplayName & "|"
End With
Next
End If
Debug.Print "--------------------------"
End With
Next
End If
End Sub
To use this code, select one or more of the emails you wish to process and then run InvestigateEmails
. It will output a selection of properties for each selected email. Your Immediate window will look something like:
From (Sender email address): a.j.dallimore@MyIsp.com
Subject: Test
Sent on: 15/11/2018 11:22:41
Received: 15/11/2018 11:22:49
Attachments:
No.|Type|Path|Filename|DisplayName|
1|Val||002 View from back of Neville Tower.jpg|002 View from back of Neville Tower.jpg|
2|Val||image001.jpg|image001.jpg|
--------------------------
I sent the above email to myself. Attachment 1 was a regular attachment that was listed in the header and could be dragged to a folder or clicked to open it. Attachment 2 was embedded and appeared as a picture in the body of the email but was not listed in the header.
My theory is that given one of your emails, InvestigateEmails
will list more than one attachment per email and the last attachment will not be an Excel workbook. You save that attachment with an extension of “xlsx” so Excel tries and fails to open it.
By the way, I use this routine whenever I am developed new code to process emails. I might plan for my new code to run off an event or a rule but this routine makes testing so much easier. I amend this code to call my new code and select a simple email. When I have debugged my code to work with a simple email, I try a more complicated one. There is no easier way of controlling which emails are passed to a macro for processing. I suggest you keep this macro for future use. Alternatively, I can tell you where to find a larger version which outputs to a desktop text file.
The rest of this answer assumes my theory is correct. If my theory is wrong, we may need to investigate further.
Before showing you how to save the correct attachment with a static file name, I will say that I doubt this is a good idea. If I understand correctly, each day you receive a workbook which overwrites the previous day’s workbook. You extract data from the workbook and save it in your database. This may seem like a good idea but this can go disastrously wrong. Years’ ago, I knew of a similar situation although, thankfully, I was not personally involved. Like you, they were receiving files, extracting data and then discarding the files. This all seemed to work for some months but they then discovered that the data was not being extracted correctly. If they had kept the original source files, fixing their database would have been difficult but possible. But without the original data, there was nothing they could do.
I recommend you save your files with a name like: “Order_History_Report 181115.xlsx”. This will allow you to archive all the original files against any future need to reprocess them. Processing a file with a name like this is a little more difficult but I can explain how to do this.
Returning to your code, the easiest correction is:
For Each objAtt In itm.Attachments
If LCase(Right$(objAtt.DisplayName, 4)) = ".xlsx" Then
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Exit For
End If
Next
This code ignores any attachments that are not regular workbooks and, once it has found a regular workbook, it does not look for more.
I do not understand: “When I use the code objAtt.SaveAsFile saveFolder
only, the file isn't corrupted.”
Unless I include a filename in the path, SaveAsFile
always stops with an error for me. I have tried every variation that I can think of but none will save the file.
I have never had SaveAsFile
corrupt a file. My theory is your emails have more than one attachment and you are saving the wrong one. Your code it:
saveFolder = "C:UsersachengDesktop"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Next
If the email has two attachments, this code will:
- Save the first attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting any file of this name retained from yesterday.
- Save the second attachment as “C:UsersachengDesktopOrder_History_Report.xlsx” overwriting the first attachment.
Most emails today use Html images for logos and pictures but a few still use embedded images which are carried as attachments but not reported to the user as attachments.
The code below will test my theory. Copy this code to a new module:
Option Explicit
Public Sub InvestigateEmails()
Dim Exp As Explorer
Dim InxA As Long
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From (Sender email address): " & .SenderEmailAddress
Debug.Print "Subject: " & .Subject
Debug.Print "Sent on: " & .SentOn
Debug.Print "Received: " & .ReceivedTime
If .Attachments.Count = 0 Then
Debug.Print "No attachments"
Else
Debug.Print "Attachments:"
Debug.Print "No.|Type|Path|Filename|DisplayName|"
For InxA = 1 To .Attachments.Count
With .Attachments(InxA)
Debug.Print InxA & "|";
Select Case .Type
Case olByValue
Debug.Print "Val";
Case olEmbeddeditem
Debug.Print "Ebd";
Case olByReference
Debug.Print "Ref";
Case olOLE
Debug.Print "OLE";
Case Else
Debug.Print "Unk;"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Type
Case olEmbeddeditem
Debug.Print "|";
Case Else
Debug.Print "|" & .PathName;
End Select
Debug.Print "|" & .Filename;
Debug.Print "|" & .DisplayName & "|"
End With
Next
End If
Debug.Print "--------------------------"
End With
Next
End If
End Sub
To use this code, select one or more of the emails you wish to process and then run InvestigateEmails
. It will output a selection of properties for each selected email. Your Immediate window will look something like:
From (Sender email address): a.j.dallimore@MyIsp.com
Subject: Test
Sent on: 15/11/2018 11:22:41
Received: 15/11/2018 11:22:49
Attachments:
No.|Type|Path|Filename|DisplayName|
1|Val||002 View from back of Neville Tower.jpg|002 View from back of Neville Tower.jpg|
2|Val||image001.jpg|image001.jpg|
--------------------------
I sent the above email to myself. Attachment 1 was a regular attachment that was listed in the header and could be dragged to a folder or clicked to open it. Attachment 2 was embedded and appeared as a picture in the body of the email but was not listed in the header.
My theory is that given one of your emails, InvestigateEmails
will list more than one attachment per email and the last attachment will not be an Excel workbook. You save that attachment with an extension of “xlsx” so Excel tries and fails to open it.
By the way, I use this routine whenever I am developed new code to process emails. I might plan for my new code to run off an event or a rule but this routine makes testing so much easier. I amend this code to call my new code and select a simple email. When I have debugged my code to work with a simple email, I try a more complicated one. There is no easier way of controlling which emails are passed to a macro for processing. I suggest you keep this macro for future use. Alternatively, I can tell you where to find a larger version which outputs to a desktop text file.
The rest of this answer assumes my theory is correct. If my theory is wrong, we may need to investigate further.
Before showing you how to save the correct attachment with a static file name, I will say that I doubt this is a good idea. If I understand correctly, each day you receive a workbook which overwrites the previous day’s workbook. You extract data from the workbook and save it in your database. This may seem like a good idea but this can go disastrously wrong. Years’ ago, I knew of a similar situation although, thankfully, I was not personally involved. Like you, they were receiving files, extracting data and then discarding the files. This all seemed to work for some months but they then discovered that the data was not being extracted correctly. If they had kept the original source files, fixing their database would have been difficult but possible. But without the original data, there was nothing they could do.
I recommend you save your files with a name like: “Order_History_Report 181115.xlsx”. This will allow you to archive all the original files against any future need to reprocess them. Processing a file with a name like this is a little more difficult but I can explain how to do this.
Returning to your code, the easiest correction is:
For Each objAtt In itm.Attachments
If LCase(Right$(objAtt.DisplayName, 4)) = ".xlsx" Then
objAtt.SaveAsFile saveFolder & "Order_History_Report.xlsx"
Set objAtt = Nothing
Exit For
End If
Next
This code ignores any attachments that are not regular workbooks and, once it has found a regular workbook, it does not look for more.
answered Nov 15 '18 at 13:25
Tony DallimoreTony Dallimore
10.3k42250
10.3k42250
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53299166%2fsaving-and-renaming-an-outlook-attachment-with-static-name-on-format-xlsx%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You save every attachment with the same name and without checking their type. Only the last attachment will be remain since the others will have been overwritten. The last attachment is likely to be a signature or a logo.
– Tony Dallimore
Nov 14 '18 at 12:48
I believe the easiest correction is to replace
"Order_History_Report.xlsx"
with"" & objAtt.DisplayName
. This will save each file with the sender's name and with the correct extension. If this is not an acceptable solution, please expand your question and I will endeavour to provide an answer that meets your requirement.– Tony Dallimore
Nov 14 '18 at 12:55
@Tony Dallimorec - objAtt.FileName. DisplayName will not necessarily be the same as the file name.
– Dmitry Streblechenko
Nov 14 '18 at 17:13
@Tony Dallimorec - The unique requeriments is save the file with static name. When I use the code (objAtt.SaveAsFile saveFolder) only, the file doesn't corrupted, but it not work for me because every day the file have a distinct name. Other point about file is that file have the same format always. Thank u in advanced and help me.
– felipe gomes
Nov 14 '18 at 17:57