Permission error running "Application.CreateItemFromTemplate" method on an EML file - vba

I'm trying to run a macro that copies EML files into my inbox.
When I get to the Application.CreateItemFromTemplate line to apply it to an EML file I get a runtime error:
We can't open [filename.path]. It's possible the file is already open, or you don't have permission to open it.
I tried running Outlook as ADMIN. Also tried the Session.OpenSharedItem method. I'm using Outlook for Microsoft 365 MSO.
Full code:
Sub ImportMessagesToOutlookFolder()
Dim fso As Scripting.FileSystemObject
Dim SourceFolder As Scripting.Folder
Dim SourceFolderName As String
Dim FileItem As Scripting.File
Dim strFile, strFileType As String
Dim oMsg As Object
Dim objNS As NameSpace
Dim copiedMsg As MailItem
Dim Savefolder As Outlook.Folder
Set fso = New Scripting.FileSystemObject 'Source folder
'Ask for folder with items to import
SourceFolderName = BrowseForFolder("My Computer")
Set SourceFolder = fso.GetFolder(SourceFolderName)
'Set the Outlook folder name
Set objNS = Application.GetNamespace("MAPI")
Set Savefolder = objNS.PickFolder
For Each FileItem In SourceFolder.Files
'Set oMsg = FileItem
Set oMsg = Outlook.Application.CreateItemFromTemplate(FileItem.Path)
'On Error Resume Next
Set copiedMsg = oMsg.Copy
copiedMsg.Move Savefolder
Set copiedMsg = Nothing
Debug.Print FileItem.Name & " " & FileItem.DateCreated
oMsg.Delete
Set oMsg = Nothing
'FileItem.Delete
Next FileItem
Set FileItem = Nothing
Set SourceFolder = Nothing
Set fso = Nothing
End Sub

The Application.CreateItemFromTemplate method creates a new Microsoft Outlook item from an Outlook template (.oft) and returns the new item. It is not designed for EML files by default. You may try to use the ShellExecute method for opening EML in the default application (you can set Outlook, see Open .eml Files in Outlook for more information):
Dim objShell : Set objShell = CreateObject("Shell.Application")
Dim objFolder : Set objFolder = objShell.BrowseForFolder(0, "Select the folder containing eml-files", 0)
Dim Item
If (NOT objFolder is Nothing) Then
Set WShell = CreateObject("WScript.Shell")
Set objOutlook = CreateObject("Outlook.Application")
Set Folder = objOutlook.Session.PickFolder
If NOT Folder Is Nothing Then
For Each Item in objFolder.Items
If Right(Item.Name, 4) = ".eml" AND Item.IsFolder = False Then
objShell.ShellExecute Item.Path, "", "", "open", 1
WScript.Sleep 1000
Set MyInspector = objOutlook.ActiveInspector
Set MyItem = objOutlook.ActiveInspector.CurrentItem
MyItem.Move Folder
End If
Next
End If
End If
MsgBox "Import completed.", 64, "Import EML"
Set objFolder = Nothing
Set objShell = Nothing

Related

Save outlook email to my internal drive as .msg file

I'm trying to save Outlook emails into my H:Drive. I want it as a run a script rule but I can't get it to work. There are no attachments involved and all I need it is to save it as a .msg file. Please lmk if you find a different way to tackle this problem.
Thanks
Sub ExtractEmailToFolder2(itm As Outlook.MailItem)
Dim OlApp As Outlook.Application
Set OlApp = New Outlook.Application
Dim Mailobject As Object
Dim Email As String
Dim NS As NameSpace
Dim Folder As MAPIFolder
Set OlApp = CreateObject("Outlook.Application")
Dim fso As Object
Dim fldrname As String
Dim fldrpath As String
' Setup Namespace
Set NS = ThisOutlookSession.Session
' Display select folder dialog
Set Folder = NS.PickFolder
' Create Folder File
Set fso = CreateObject("Scripting.FileSystemObject")
' loop to read email address from mail items.
For Each Mailobject In Folder.Items
fldrpath = "H:\Backup stuff\"
If Not fso.folderexists(fldrpath) Then
fso.createfolder (fldrpath)
End If
Set objCopy = Mailobject.Copy
objCopy.SaveAs fldrpath & "\" & objCopy.Subject, olMSG
Next
Set OlApp = Nothing
Set Mailobject = Nothing
End Sub
First of all, there is no need to create a new Outlook Application instance (twice in your sample code!) if your VBA macro is run by the rule. Instead, you can use the global Application property:
Sub ExtractEmailToFolder2(itm As Outlook.MailItem)
Dim fso As Object
Dim fldrname As String
Dim fldrpath As String
' Create Folder if required
Set fso = CreateObject("Scripting.FileSystemObject")
fldrpath = "H:\Backup stuff\"
If Not fso.folderexists(fldrpath) Then
fso.createfolder (fldrpath)
End If
itm.SaveAs fldrpath & "\" & "your_unique_filename.msg", olMSG
Set OlApp = Nothing
Set Mailobject = Nothing
End Sub
The sample code which is shown above saves the item against which the rule is run to the folder specified/hardcoded.
Problem:
Folder Check was included in the Loop
FileName had Subject in it. That always creates problem unless some kind of manipulation is done. Because it contains various characters that are not permitted in the Name of a File in Windows.
Note:
Put it in any Module in Outlook and Run using F5 or by Creating a Shortcut.
Try:
Sub ExtractEmailToFolder2()
Dim OlApp As Outlook.Application
Set OlApp = New Outlook.Application
Dim Mailobject As Object
Dim Email As String
Dim NS As NameSpace
Dim Folder As MAPIFolder
Set OlApp = CreateObject("Outlook.Application")
Dim fso As Object
Dim fldrname As String
Dim fldrpath As String
' Setup Namespace
Set NS = ThisOutlookSession.Session
' Display select folder dialog
Set Folder = NS.PickFolder
' Create Folder File
Set fso = CreateObject("Scripting.FileSystemObject")
fldrpath = "H:\Backup stuff\"
If Not fso.folderexists(fldrpath) Then
fso.createfolder (fldrpath)
End If
' loop to read email address from mail items.
i = 1
For Each Mailobject In Folder.Items
Mailobject.SaveAs fldrpath & "\mail" & i & ".msg", olMsg
i = i + 1
Next
Set OlApp = Nothing
Set Mailobject = Nothing
End Sub

Save Attachment on arriving email

I created an Outlook rule to save an attachment then move it to the Deleted Items folder. The code works when I highlight the arrived email in the Inbox then move the email to the Deleted Items folder.
When the new email arrives, it is saving the attachment(s) from different email in the inbox and not moving the email to the Deleted Items folder.
The Outlook rule is:
Apply this rule after the message arrives
from Sender
and with Gift Card in the subject
and on this computer only
run Project1.SaveAttachments
Public Sub SaveAttachments(MItem As Outlook.Mailitem)
Dim objOL As Outlook.Application
Dim objMsg As Outlook.Mailitem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim objNamespace As Outlook.NameSpace
Dim objDestFolder As Outlook.MAPIFolder
On Error Resume Next
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
strFolderpath = "Y:\"
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
strDeletedFiles = ""
If lngCount > 0 Then
For i = lngCount To 1 Step -1
strFile = objAttachments.Item(i).FileName
strFile = strFolderpath & strFile
objAttachments.Item(i).SaveAsFile strFile
Next i
Set objNamespace = objOL.GetNamespace("MAPI")
Set objDestFolder = objNamespace.GetDefaultFolder(olFolderDeletedItems)
objMsg.Move objDestFolder
End If
Next
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
Set objNamespace = Nothing
Set objDestFolder = Nothing
End Sub
According to my test, you could save email attachment and delete it using the below code:
Sub SaveAutoAttach()
Dim object_attachment As Outlook.attachment
Dim saveFolder As String
Dim oOutlook As Object
Dim oOlns As Object
Dim oOlInb As Object
Dim unRead, m As Object, att As Object
Dim some As String, other As String
Const olFolderInbox = 6
'~~> Get Outlook instance
Set oOutlook = GetObject(, "Outlook.application")
Set oOlns = oOutlook.GetNamespace("MAPI")
Set oOlInb = oOlns.GetDefaultFolder(olFolderInbox)
'~~> Check if there are any actual unread emails
Set unRead = oOlInb.Items.Restrict("[UnRead] = True")
If unRead.Count = 0 Then
MsgBox "NO Unread Email In Inbox"
Else
some = ""
other = ""
saveFolder = "D:\"
For Each m In unRead
If m.Attachments.Count > 0 Then
For Each object_attachment In m.Attachments
' Criteria to save .doc files only
If InStr(object_attachment.DisplayName, ".doc") Then
object_attachment.SaveAsFile saveFolder & "\" & object_attachment.DisplayName
End If
Next
End If
m.Delete
Next m
End Sub
For more information, please refer to this link:
Auto Download Outlook Email Attachment – Code in VBA by Topbullets.com

Select all items in a specific folder and move them to another folder

How do I select all Mails in the Deleted Items folder of a shared account (not my personal account) and then move them to a different folder not called "Deleted Items". For now, let's call the destination folder "Old Emails".
Here is what I have written so far:
'Macro for pseudo-archiving
Sub PseudoArchive()
On Error Resume Next
Dim objNamespace As Outlook.NameSpace
Dim sourceFolder As Outlook.MAPIFolder
Dim Messages As Selection
Dim Msg As MailItem
Set objNamespace = GetNamespace("MAPI")
Set sourceFolder = objNamespace.Folders("sharedemail#website.com")
Set sourceFolder = objFolder.Folders("Deleted Items")
'Define path to the target folder
Set destinationFolder = ns.Folders("sharedemail#website.com").Folders("Old Emails")
'Move emails in sourceFolder to destinationFolder
For Each Msg In sourceFolder
Msg.Move destinationFolder
Next
Set objNamespace = Nothing
Set sourceFolder = Nothing
Set Messages = Nothing
Set Msg = Nothing
End Sub
I am stuck on how to get the macro to select all items in the sourceFolder so it can then move them to the destinationFolder. I prefer not to manually select the emails in the folder before running the macro.
If anyone can provide assistance, that would be appreciated. Thanks!
You almost got it, try the following
Option Explicit
Sub PseudoArchive()
Dim objNamespace As Outlook.NameSpace
Dim sourceFolder As Outlook.MAPIFolder
Dim destinationFolder As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Item As Object
Dim Msg As String
Dim i As Long
Set objNamespace = GetNamespace("MAPI")
Set sourceFolder = objNamespace.Folders("sharedemail#website.com").Folders("Deleted Items")
Set destinationFolder = objNamespace.Folders("sharedemail#website.com").Folders("Inbox").Folders("Old Emails")
Set Items = sourceFolder.Items
'Move emails in sourceFolder to destinationFolder
Msg = Items.Count & " Items in " & sourceFolder.Name & ", Move?"
If MsgBox(Msg, vbYesNo) = vbYes Then
For i = Items.Count To 1 Step -1
Set Item = Items.Item(i)
DoEvents
Item.Move destinationFolder
Next
End If
End Sub
Here is a code snippet that should help.
Dim olApp As Outlook.Application
Dim olFol As Outlook.Folder, olDestFol As Outlook.Folder
Dim olItem As Object
Dim i as Long, j as Long
Set olApp = New Outlook.Application olApp.GetNamespace("MAPI").Folders("mailboxnamehere").Folders("Deleted Items")
Set olDestFol = olApp.GetNamespace("MAPI").Folders("mailboxnamehere").Folders("Inbox").Folders("Deleted Items") ' Destination Folder
Do Until olFol.Items.Count = 0
olFol.Items(1).Move olDestFolder
Loop

vba outlook - reply from a file from a folder

I dragged an outlook msg to a specific folder named "email temp folder" and would like to reply on that msg automatically.
The title name of the msg which I saved in "email temp folder" could be anything. It is not possible for me to get the file's title name. So I try to loop through the file in "email temp folder" and Set FileItemToUse = objFile
However, there is an error: object doesn't support this property or method on this line. .ReplyAll
How am I able to turn FileItemToUse into an outlook item?
Sub outlookActivate1()
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Dim fso As New FileSystemObject
Dim objFolder As Object
Dim objFile As Object
Dim FileItemToUse As Object
Dim i As Long
Set OutApp = CreateObject("Outlook.Application")
strPath = "C:\Users\admin\Desktop\email temp folder" & "\"
strFiles = Dir(strPath & "*.*")
Set objFolder = fso.GetFolder(strPath)
For Each objFile In objFolder.Files
If i = 0 Then
Set FileItemToUse = objFile
End If
Next objFile
With FileItemToUse
.ReplyAll
.BCC = ""
.Subject = "Hi"
.HTMLBody = "testing"
.BodyFormat = olFormatHTML
.display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Your code should look similar to the following:
Sub ReplyToFilesInFolder(SourceFolderName As String)
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Scripting.Folder
Dim FileItem As Scripting.File
Dim strFile
Dim strFileType
Dim openMsg As MailItem
Dim strFolderpath As String
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(SourceFolderName)
For Each FileItem In SourceFolder.Files
strFile = FileItem.name
' This code looks at the last 4 characters in a filename
' If we wanted more than .msg, we'd use Case Select statement
strFileType = LCase$(Right$(strFile, 4))
If strFileType = ".msg" Then
Debug.Print FileItem.Path
Set openMsg = Application.CreateItemFromTemplate(FileItem.Path)
' do whatever is needed to reply
openMsg.Close olDiscard
Set openMsg = Nothing
' end do whatever
End If
Next FileItem
Set FileItem = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
End Sub
This (untested) snipped was inspired by this article. Microsoft Scripting Runtime has to be included as project reference.
So I try to loop through the file in "email temp folder" and Set FileItemToUse = objFile
It is not possible to get the job done that way.
When you drag a message file (.msg) file to a specific folder the ItemAdd event is fired. So, you need to handle the event to get a MailItem object which corresponds a dropped file. Then you can use the Reply or ReplyAll methods.

Accessing another maibox in outlook using vba

I have two mailboxes in my Outlook.
One that is mine and it automatically logs me in when I log in to my pc and another I have that is for mail bounces.
I really need to access the inbox of the mail's account but I just can't seem to do it.
And there is no way I can make the mailbox of the mail account to be my default mailbox
Here is the code I have so far:
Public Sub GetMails()
Dim ns As NameSpace
Dim myRecipient As Outlook.Recipient
Dim aFolder As Outlook.Folders
Set ns = GetNamespace("MAPI")
Set myRecipient = ns.CreateRecipient("mail#mail.pt")
myRecipient.Resolve
If myRecipient.Resolved Then
MsgBox ("Resolved")
Set aFolder = ns.GetSharedDefaultFolder(myRecipient, olFolderInbox)
Else
MsgBox ("Failed")
End If
End Sub
The problem I am getting is at the
Set aFolder = ns.GetSharedDefaultFolder(myRecipient, olFolderInbox)
I get the Resolved msgbox so I know that is working but after that I get an error:
Run-Time Error
which doesn't say much about the error itself.
Can anyone help me out here please?
Thanks
If the folder you wish to access is not an Exchange folder, you will need to find it, if it is an Exchange folder, try logging on to the namespace.
Log on to NameSpace
Set oNS = oApp.GetNamespace("MAPI")
oNS.Logon
Find Folder
As far as I recall, this code is from Sue Mosher.
Public Function GetFolder(strFolderPath As String) As Object 'MAPIFolder
' strFolderPath needs to be something like
' "Public Folders\All Public Folders\Company\Sales" or
' "Personal Folders\Inbox\My Folder" ''
Dim apOL As Object 'Outlook.Application '
Dim objNS As Object 'Outlook.NameSpace '
Dim colFolders As Object 'Outlook.Folders '
Dim objFolder As Object 'Outlook.MAPIFolder '
Dim arrFolders() As String
Dim I As Long
On Error GoTo TrapError
strFolderPath = Replace(strFolderPath, "/", "\")
arrFolders() = Split(strFolderPath, "\")
Set apOL = CreateObject("Outlook.Application")
Set objNS = apOL.GetNamespace("MAPI")
On Error Resume Next
Set objFolder = objNS.Folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For I = 1 To UBound(arrFolders)
Set colFolders = objFolder.Folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(I))
If objFolder Is Nothing Then
Exit For
End If
Next
End If
Set GetFolder = objFolder
Set colFolders = Nothing
Set objNS = Nothing
Set apOL = Nothing
End Function