Before I go asking for help I want to let you know that I am not very good at this and have just learnt bits and bobs from online pages and forums when coding.
I've got a spreadsheet which I set up for sending out for quotations to certain suppliers (repetitive). I have been using this spreadsheet for almost 2 years now and it's been working fine. Late last week I tried to click on both buttons and found that excel and outlook froze up for a minute but no email was ever generated or sent. I assume something in the settings has changed due to an update as it's suddenly stopped working. I am using Office365. I noticed in outlook options under Add-ins that 'Microsoft VBA for Outlook Addin' is listed under Inactive Application Add-ins...for whatever that's worth
Screenshot - (https://ibb.co/fv2Pzx7)
Normally I would add the details for each of the files that I wish to attach on the right hand side (the directory of the file and the file name). The Job Name at the bottom right is the subject.
In VBAProject Reference I have the following boxes ticked:
Visual Basic for Applications
Microsoft Excel 16.0 Object Library
OLE Automation
Microsoft Office 16.0 Object Library
My code is quite basic I think (seeing as though even I could do it!)
Sub GenerateAutoEmail3_Click()
On Error GoTo ErrHandler
' SET Outlook APPLICATION OBJECT.
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
' CREATE EMAIL OBJECT.
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(olMailItem)
With objEmail
.To = Range("E3")
.Subject = Range("F3")
.Body = "Hi " & Range("C3") & "," & Range("R13") & Range("D3") & Range("R14")
.Attachments.Add Range("I3").Text
.Attachments.Add Range("K3").Text
.Attachments.Add Range("M3").Text
.Attachments.Add Range("O3").Text
.Send ' DISPLAY MESSAGE.
End With
' CLEAR.
Set objEmail = Nothing: Set objOutlook = Nothing
ErrHandler:
Range("G3").Value = Now
'
End Sub
(Couldn't get those last few lines in the code box!...)
Sorry if I haven't done a good job of explaining my issue or if I've rabbled on for no reason!
Thanks
Related
Question: Is it possible to create a macro that opens outlook in a web browser and populates the fields of a new message as well as attach a file? The outlook portion of the current macro only opens outlook in a browser.
ActiveWorkbook.FollowHyperlink Address:="https://outlook.office365.com/mail/**shared mailbox address**"
Background: I am trying to update an excel macro that currently saves a pdf of the sheet, opens the outlook application, fills out the necessary fields and attaches the saved pdf to the email. This macro has worked fine, but we have recently moved to using a shared mailbox to send the message. Now the users have encountered problems sending from the shared mailbox using the outlook application. The solution is to use outlook in the browser (edge), but the macro I currently have can only open outlook in the browser and requires the user to fill out all the fields and find and attach the saved pdf. There have been problems with this and I was hoping there was a way to automate the process like our old macro would.
Old macro:
Set OlApp = CreateObject("Outlook.Application")
Set NewMail = OlApp.CreateItem(0)
On Error Resume Next
With NewMail
.To = ReportName
.CC = ""
.Subject = TempFileName
.Body = ""
.Attachments.Add FileFullPath '--- full path of the pdf where it is saved
.Display '.Send or use .Display to show you the email before sending it.
End With
On Error GoTo 0
Well, Yes and No.
Yes, you can get VBA to do this... but No, it won't be remotely as easy as running it through the desktop application.
A workaround that still uses desktop application, is to
Give all users that need to send the email access to this inbox from their own desktop apps.
Use the ".SendUsingAccount" property
Sub ExampleSub()
Dim OLApp As Object
Dim NewMail As Object
Set OLApp = CreateObject("Outlook.Application")
Set NewMail = OLApp.CreateItem(0)
On Error Resume Next
With NewMail
.SentOnBehalfOfName = "MySecondaryAddress#Domain.com"
.To = "someaddress#gmail.com"
.CC = ""
.Subject = "Example Subject"
.Body = "Good Morning..."
'.Attachments.Add FileFullPath '--- full path of the pdf where it is saved
.Display '.Send or use .Display to show you the email before sending it.
End With
On Error GoTo 0
End Sub
I came across a code in Excel VBA which sends mail via Outlook based on given time ranges in the code. The "TO, CC, Subject and Mail Body" are all input in excel only.
The code works fine but .Send giving error 287-Application or object defined error. The code works well in my colleague's laptop, so I am guessing it is some setting error in my outlook or excel. I keep my outlook open while executing the code. The code is written below. Can anyone point to what might be wrong?
Sub Send_Email()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
'''''''''' Update Next ''''''''''''''
Call Update_Next_Schedule_Time
Application.OnTime sh.Range("K20").Value, "Send_Email"
''''''''''''''''''''''''''''''''''''''
Dim oa As Object
Dim msg As Object
Set oa = CreateObject("outlook.application")
Set msg = oa.createitem(0)
With msg
.To = sh.Range("C2").Value
.CC = sh.Range("C4").Value
.Subject = sh.Range("C6").Value
.Body = sh.Range("C8").Value
.display
.send
End With
End Sub
I believe this is due to your Outlook security policy. Check if it allows programmatic access. If not, and you cannot convince your IT department to make any change, then you should automate the opened outlook app rather that creating a new Outlook instance. Also, are you trying to send the email to yourself, by any chance?
I have a macro that automatically send emails in Outlook based on fields in an Excel file using VBA. It works really well.
The problem I'm having is the client now needs to use Outlook Web Apps (OWA). From what I have read, my macro won't work with OWA because VBA is for applications and OWA is browser based.
Is there a way to convert my macro to work with OWA? The client will have OWA open so I don't need to worry about logging in to the app.
I've read a little about CDO and tried to modify my macro but got errors (1) type mismatch when trying to attach a couple of files to the email and (2) The SendUsing configuration value is invalid.
I haven't used CDO before so I don't know what I'm doing with it.
Here is the code I tried to use:
Set OutApp = CreateObject("CDO.Message")
Set iconf = CreateObject("CDO.Configuration")
With OutApp
Set .Configuration = iconf
.To = Var4
.CC = ""
.BCC = ""
.Subject = "Final Estate Report"
.HTMLBody = StrBody & "<br>"
A = 1
OutAttach = Dir(StrDir)
Do While Len(OutAttach) > 0
DoEvents
.Attachments.Add StrDir & OutAttach
OutAttach = Dir
A = A + 1
Loop
.Send
Application.ScreenUpdating = True
End With
Any suggestions or examples of how to make this work would be greatly appreciated
Thanks for taking the time to look at this issue....
Have you looked into using Microsoft Graph. Your first task will be to call the API in VBA and you can start here How to call Microsoft Graph API using VBA
. Developer documentation here
I am trying to save attachments from a sub-folder in Outlook to a folder on my C drive using Excel VBA.
For example, in my inbox folder I have a sub-folder called 'data' and in this folder there are emails with different excel attachments of different data but with the same formatting and the same attachment name but with an updated date (Eg: "Attachment name + 28 March").
These emails are sent daily. I want all attachments, not already saved, saved to a folder on my C drive and then open each attachment to extract the relevant data to Excel.
I am able to extract the relevant data once the files are in my C drive but I am unable to set up a path from my Excel to Outlook without Outlook VBA (which I don't want to do).
This is what I have so far: (the comments are for my benefit because I am new to this)
Sub attachmentsave()
Dim olook As Outlook.Application
Dim omailitem As Outlook.mailitem
'whenever dealing with folders we need to define outlook.namespace This is a class that opens the gate for me to access all outlook folders
Dim onamespace As Outlook.Namespace
Dim fol As Outlook.Folder 'we need to tell vba where we have out emails with attachments stored
Dim atmt As Outlook.Attachment '.attachment is a class that will help us deal with emails that have attachments
Set olook = New Outlook.Application
Set omailitem = olook.CreateItem(olmailitem)
'messaging application protocol interface
Set onamespace = olook.GetNameSpace("MAPI")
Set fol = onamespace.GetDefaultFolder(olFolderInbox)
For Each omailitem In fol.items
For Each atmt In omailitem.attachments
atmt.SaveAsFile "C:/" & atmt.FileName
'all attachments in inbox should be save in C drive
Next
Next
End Sub
You need a macro-enabled Excel workbook with a reference to "Microsoft Output nn.n Object Library" where “nn.n” depends on the version of Office you are running. Please do not mix versions; I have never tried but I understand it causes problems.
I am assuming you are familiar with Excel VBA and know how to create a macro-enabled workbook. From your comments, I assume you do not know about references.
Much of the power of VBA is not native but comes from libraries which you can reference if you need their functionality. Open the VBA Editor and click Tools and then References. You will get a long list of available references. Those at the top will be ticked. For example, "Microsoft Excel nn.n Object Library" will be ticked. Without this reference, the compiler would not know what a range or a worksheet was. Note: "nn.n" depends on the version of Office you are using. For me, the value is "16.0" because I am using Office 365.
Unticked references are in alphabetic sequence. Scroll down the list until you find "Microsoft Outlook nn.n Object Library". Click the box to the left to tick this reference. Click "OK". If you click Tools then References again you will see "Microsoft Outlook nn.n Object Library" ticked and near the top. The compiler now has access to the definitions of MailItem, Folder and the rest of the Outlook Object Model.
Copy the code below to a new module:
Option Explicit
Sub ListStores()
' Needs reference to "Microsoft Output nn.n Object Library"
' where "nn.n" depends on the version of Outlook you are using.
Dim AppOut As New Outlook.Application
Dim InxStoreCrnt As Long
Dim FldrInbox As Outlook.Folder
With AppOut
With .Session
Debug.Print "List of stores:"
For InxStoreCrnt = 1 To .Folders.Count
Debug.Print " " & .Folders(InxStoreCrnt).Name
Next
Set FldrInbox = .GetDefaultFolder(olFolderInbox)
Debug.Print "Store for default Inbox: " & FldrInbox.Parent.Name
End With
End With
AppOut.Quit
Set AppOut = Nothing
End Sub
VBA usually has more than one method of achieving a desired effect. You have used “NameSpace” in your code whilst I have used “Session”. The documentation says these two methods are equivalent. If you write your own code, you can pick whichever method you prefer. But if you go looking for useful snippets, you must be ready for other people having different preferences.
Dim AppOut As New Outlook.Application creates an instance of Outlook that will access Outlook’s files on behalf of the macro.
With AppOut
With .Session
: : : :
End With
End With
I can replace : : : : with any Outlook VBA. If an Excel macro tries to access an email, the user will be warned and asked to give permission for the macro to run.
Outlook keeps emails, appointments, tasks and so on in files it calls Stores. You may see these called PST files because most have an extension of PST but an OST file is also a store. You may see them called Accounts because, by default, Outlook creates one store per email account. However, you can create as many extra stores as you want, none of which will be Accounts.
This code will create a list of the stores you can access:
Debug.Print "List of stores:"
For InxStoreCrnt = 1 To .Folders.Count
Debug.Print " " & .Folders(InxStoreCrnt).Name
Next
The output might look something like:
List of stores:
Outlook Data File
Smith John#ISPOne.com
Archive Folders
Backup
John Smith#ISPTwo.com
OutlookOutlook
The above is based on my home installation. A work installation is likely to be somewhat different. The differences will depend on the options chosen during installation. A work installation is also likely to included shared folders which I do not have on my system.
If you look at your folder pane, you will have names with other names indented underneath. The names be will the stores and will match the stores listed by the macro although the sequence will probably be different. The other names in the folder pane will be the folders within each store.
The last bit of my macro is:
Set FldrInbox = .GetDefaultFolder(olFolderInbox)
Debug.Print "Store for default Inbox: " & FldrInbox.Parent.Name
You have similar code to access an Inbox but this may not be the Inbox you want. On my system, this code outputs:
Store for default Inbox: Outlook Data File
“Outlook Data File” is Outlook’s default store. On my system, the calendar and my tasks are held in this store but my emails are not. I have two email accounts and each has their own store.
Try this above macro. Does GetDefaultFolderfind the Inbox you need to access?
Now add this macro:
Sub ListStoresAndFirstEmails()
' Needs reference to "Microsoft Output nn.n Object Library"
' where "nn.n" depends on the version of Outlook you are using.
Dim AppOut As New Outlook.Application
Dim InxFldrCrnt As Long
Dim InxStoreCrnt As Long
Dim FldrInbox As Outlook.Folder
With AppOut
With .Session
Debug.Print "List of stores and first emails:"
For InxStoreCrnt = 1 To .Folders.Count
Debug.Print " " & .Folders(InxStoreCrnt).Name
For InxFldrCrnt = 1 To .Folders(InxStoreCrnt).Folders.Count
If .Folders(InxStoreCrnt).Folders(InxFldrCrnt).Name = "Inbox" Then
Set FldrInbox = .Folders(InxStoreCrnt).Folders(InxFldrCrnt)
If FldrInbox.Items.Count > 0 Then
With FldrInbox.Items(1)
Debug.Print " Subject: " & .Subject
Debug.Print " Received: " & .ReceivedTime
Debug.Print " From: " & .SenderEmailAddress
End With
End If
Exit For
End If
Next
Next
End With
End With
AppOut.Quit
Set AppOut = Nothing
End Sub
This macro is also about investigating your stores. The macro scans down your stores. For each store, it scans down the list of level 1 folders looking for "Inbox". If it finds "Inbox", it assumes the oldest item in it is a MailItem and outputs its subject, received time and sender. If the oldest item is not a MailItem, you will get an error. I almost hope you do get an error to demonstrate the importance of not making assumptions.
Finally add:
Sub ListAttachments()
Dim AppOut As New Outlook.Application
Dim InxAttachCrnt As Long
Dim InxItemCrnt As Long
Dim InxStoreCrnt As Long
Dim FldrData As Outlook.Folder
With AppOut
With .Session
Set FldrData = .Folders("Outlook Data File").Folders("Inbox").Folders("Data")
End With
End With
Debug.Print "List emails with attachments within: ";
Debug.Print " " & FldrData.Name & " of " & FldrData.Parent.Name & _
" of " & FldrData.Parent.Parent.Name
With FldrData
For InxItemCrnt = 1 To FldrData.Items.Count
If .Items(InxItemCrnt).Class = olMail Then
With .Items(InxItemCrnt)
If .Attachments.Count > 0 Then
Debug.Print " Subject: " & .Subject
Debug.Print " Received: " & .ReceivedTime
Debug.Print " From: " & .SenderEmailAddress
For InxAttachCrnt = 1 To .Attachments.Count
Debug.Print " " & InxAttachCrnt & " " & .Attachments(InxAttachCrnt).DisplayName
Next
End If
End With
End If
Next
End With
AppOut.Quit
Set AppOut = Nothing
End Sub
I always keep some junk emails in store "Outlook Data File" for testing purposes.
In Set FldrData = .Folders("Outlook Data File").Folders("Inbox").Folders("Data") you need to replace "Outlook Data File" with the name of the store containing the emails of interest. If I understand correctly, the emails are in folder "Data" under folder "Inbox". If I have misunderstood, notice how I have used a chain of "Folders(xxxx)" to reach the required folder. In earlier emails I have used indices to reach stores and folders. Here I have specified a specific folder.
Within that folder I look for MailItems (showing how to avoid other items) and if they have attachments, list some properties of the email and the names of its attachments.
This is as far as I can go because I do not fully understand your explanation of how attachments are named or where you want attachments saved.
I have some macros and Task Scheduler to launch Excel at a specified time, update some tables, create PDF documents from those tables and then email those PDF documents to select individuals.
Sometimes the email gets stuck in the Outbox and does not send until I open up Outlook.
Here is the code for sending the email:
Option Explicit
Public strFileName As String
Sub EmailPDFAsAttachment()
'This macro grabs the file path and stores as a concatenation/variable. Then it emails the file to whomever you specify.
' Works in Excel 2000, Excel 2002, Excel 2003, Excel 2007, Excel 2010, Outlook 2000, Outlook 2002, Outlook 2003, Outlook 2007, Outlook 2010.
' This example sends the last saved version of the Activeworkbook object .
Dim OutApp As Object
Dim OutMail As Object
Dim FilePath As String
'This part is setting the strings and objects to be files to grab with their associated filepath. (e.g. FilePath is setting itself equal to the text where we plan to set up each report)
FilePath = "\\"ServerNameHere"\UserFolders\_AutoRep\DA\PDFs\SealantsVS1SurfaceRestore\" _
& strFileName & ".pdf"
With Application
.EnableEvents = True
.ScreenUpdating = True
' End With
'Below is where it creats the actual email and opens up outlook.
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
' ******Make sure to set the .To to only recipients that are required to view it. Separate email addresses with a semicolon (;).
' Current distribution list:
'
With OutMail
.To = "example#Example.com"
.CC = ""
.BCC = ""
.Subject = strFileName
.HTMLBody = "Hello all!" & "<br>" & _
"Here is this month's report for the Sealants vs Surface Restore. It goes as granular as to by show results by provider." & "<br>" & _
"Let me know what you think or any comments or questions you have!" & "<br>" & _
vbNewLine & .HTMLBody
'Here it attached the file, saves the email as a draft, and then sends the file if everything checks out.
.Attachments.Add FilePath
.Send
End With
On Error GoTo 0
' With Application
' .EnableEvents = True
' .ScreenUpdating = True
End With
'This closes out the Outlook application.
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
After this completes, the Private sub jumps back to the macros in this workbook and quits MS Excel with the CloseWorkbook Application.
My tools reference library in Outlook's VBA settings:
My Trust Settings:
Macro Settings:
"Enable all macros" selected
"Apply macro security settings to installed add-ins" selected
The idea is to have this program run in the early morning and have these emails in the inbox of select individuals by the time they come in to work.
If anyone is still looking for an answer; this allows to actually send an email without opening outlook app.
Dim mySyncObjects As Outlook.SyncObjects
Dim syc As Outlook.SyncObject
Set mySyncObjects = Outlook.Application.GetNamespace("MAPI").SyncObjects
Set syc = mySyncObjects(1)
syc.start
Outlook, just like any other Office app, cannot run in a service(such as the Scheduler).
That being said, you need to force Outlook to perform SendReceive and wait for it to complete. Call Namespace.SendAndReceive or retrieve the first SyncObject object from the Namespace.SyncObjects collection, call SyncObject.Start and wait fro the SyncObject.SyncEnd event to fire.