How to refer to non-default account? - excel

I am trying to send with another account however the VBA defaults to the main email.
I want to use no_reply mailbox however it uses firstname.lastname#company.com.
I even changed the no_reply to my default email by going into account settings in Outlook.
I checked while running the code if it is referring to the no_reply when it creates a new mail window, and it does at line Set OutAccount = myMail.Session.Accounts.Item(1) which shows as no_reply. However the email message shows first.last#company.com.
Sub Send_EmailV21()
Dim outlookApp As Outlook.Application
Dim myMail As Outlook.MailItem
Dim lastrow As Long
Dim i As Integer
Dim Sheet As Worksheet
Dim OutAccount As Outlook.Account
Application.ScreenUpdating = False
On Error Resume Next
lastrow = ThisWorkbook.Worksheets("Sheet1").Range("A1").End(xlDown).Row
For i = 2 To lastrow
'If ThisWorkbook.Worksheets("Sheet2").Range("T" & i) = "No" Then
Set outlookApp = New Outlook.Application
Set myMail = outlookApp.CreateItem(olMailItem)
'Set OutAccount = myMail.Session.Accounts.Item(1)
source_file = ThisWorkbook.Worksheets("Sheet1").Range("E" & i).Value
source_file2 = ThisWorkbook.Worksheets("Sheet1").Range("F" & i).Value
Set Sheet = ThisWorkbook.Worksheets("Sheet1")
myMail.Attachments.Add source_file
myMail.Attachments.Add source_file2
'Set myMail.SendUsingAccount = myMail.Session.Accounts.Item(1)
myMail.To = ThisWorkbook.Worksheets("Sheet1").Range("D" & i).Value
myMail.Subject = "Subject Line"
myMail.HTMLBody = "whatever i want to write in the email"
myMail.Display
myMail.Send
ThisWorkbook.Worksheets("Sheet1").Range("G" & i) = "Yes"
'Else
'End If
Application.ScreenUpdating = True
Next i
End Sub
Adding the following line worked.
myMail.SentOnBehalfOfName = "blah#company.com"

I'd suggest iterating over all accounts configured in the profile and choose the required one. By using indexes you may choose a wrong account mistakenly.
' Loop over the Accounts collection of the current Outlook session.
Dim accounts As Outlook.Accounts = application.Session.Accounts
Dim account As Outlook.Account
For Each account In accounts
' When the email address matches, return the account.
If account.SmtpAddress = smtpAddress Then
Return account
End If
Next
See Send an email given the SMTP address of an account for more information.

Related

Add current date to Filtered Date Column

I have a table that houses all the info about projects I have bid. I frequently have to send emails to General Contractors checking up on projects. Each person I am email typically has more than multiple project I am checking up on. Currently I am running a macro, that filters the data based on the Contacts name, and if the project status is "open", generates an email with the data and then clears the filters. I would like to add todays date to a column I have on the table called "Follow up Date" for each project I emailed about. I image this portion would need to happen while the table is still filter.
Sub EmailGCsBulk()
'Declare Outlook Variables
Dim oLookApp As Outlook.Application
Dim oLookItm As Outlook.MailItem
Dim oLookIns As Outlook.Inspector
'Declare Word Variables
Dim oWrdDoc As Word.Document
Dim oWrdRng As Word.Range
Dim oWrdTble As Word.Table
'Declare Excel Variables
Dim ExcTbl As ListObject
On Error Resume Next
'Get The Active instance of Outlook, if there is one.
Set oLookApp = GetObject(, "Outlook. Application")
'If ther is no active instance create one
If Err.Number = 429 Then
'Create a new instance
Set oLookApp = New Outlook.Application
End If
'Create a new Email
Set oLookItm = oLookApp.CreateItem(olMailItem)
'Create a refernce to the table
Set Exltbl = ActiveSheet.ListOjects(1)
With oLookItm
'Basic Info
.To = Range("F1").Value
.Subject = "Various Project Statuses"
'Display Email
.Display
'Get The Inspector
Set oLookIns = .GetInspector
'Get the Word Editor
Set oWrdDoc = oLookIns.WordEditor
'Filter Table to Distro
ActiveSheet.Range("Table1").AutoFilter Field:=5, Criteria1:=Cells(1, 5).Value
ActiveSheet.Range("Table1").AutoFilter Field:=10, Criteria1:="Open"
'Add Follow up date
'Hide Columns
Range("H:R").EntireColumn.Hidden = True
Range("A:A").EntireColumn.Hidden = True
'Copy Items
Worksheets(1).ListObjects("Table1").Range.Copy
oWrdDoc.Range(1, 2).Paste
'Greeting Text
MsgText = Split(Range("E1").Value, " ")(0) & "," & vbNewLine & "Can you please let me know the statuses of the projects below." & vbNewLine
oWrdDoc.Range.InsertBefore Text:=MsgText
'Clearing out filter and selection
ActiveSheet.ListObjects("Table1").AutoFilter.ShowAllData
Application.CutCopyMode = False
Range("G:R").EntireColumn.Hidden = False
Range("A:A").EntireColumn.Hidden = False
ActiveSheet.Range("Table1").AutoFilter Field:=3, Criteria1:=">=1/31/2021"
End With
Set oLookItm = Nothing
Set oLookApp = Nothing
Application.ScreenUpdating = True
End Sub
So after hours of searching I think I may have found the answer but I am nervous to implement because I don't exactly know what is going on with the Resize function but it seems to work. Can someone please review and let me know if this is a good option.
Sub EmailGCsBulk()
'******Declare Outlook Variables******
Dim oLookApp As Outlook.Application
Dim oLookItm As Outlook.MailItem
Dim oLookIns As Outlook.Inspector
'******Declare Word Variables******
Dim oWrdDoc As Word.Document
Dim oWrdRng As Word.Range
Dim oWrdTble As Word.Table
'******Declare Excel Variables******
Dim ExcTbl As ListObject
Dim FUDate As Range, cell As Range
Set FUDate = ActiveSheet.AutoFilter.Range
Set FUDate = FUDate.Offset(1, 0).Resize(FUDate.Rows.Count - 1, 1)
On Error Resume Next
'******Get The Active instance of Outlook, if there is one.******
Set oLookApp = GetObject(, "Outlook. Application")
'******If ther is no active instance create one******
If Err.Number = 429 Then
'******Create a new instance******
Set oLookApp = New Outlook.Application
End If
'******Create a new Email******
Set oLookItm = oLookApp.CreateItem(olMailItem)
'******Create a refernce to the table******
With oLookItm
'******Basic Info******
.To = Range("F1").Value
.Subject = "Various Project Statuses"
'******Display Email******
.Display
'******Get The Inspector******
Set oLookIns = .GetInspector
'******Get the Word Editor******
Set oWrdDoc = oLookIns.WordEditor
'******Filter Table to Distro******
ActiveSheet.Range("Table1").AutoFilter Field:=5, Criteria1:=Cells(1, 5).Value
ActiveSheet.Range("Table1").AutoFilter Field:=10, Criteria1:="Open"
'******Add Follow up date******
For Each cell In FUDate.Columns(13).Cells.SpecialCells(xlCellTypeVisible)
cell.Value = Date
Next cell
'******Add Follow up By******
For Each cell In FUDate.Columns(14).Cells.SpecialCells(xlCellTypeVisible)
cell.Value = "DV"
Next cell
'******Add Plus Count******
For Each cell In FUDate.Columns(15).Cells.SpecialCells(xlCellTypeVisible)
cell.Value = cell.Value + 1
Next cell
'******Hide Columns******
Range("H:R").EntireColumn.Hidden = True
Range("A:A").EntireColumn.Hidden = True
'******Copy Items******
Worksheets(1).ListObjects("Table1").Range.Copy
oWrdDoc.Range(1, 2).Paste
'******Greeting Text******
MsgText = Split(Range("E1").Value, " ")(0) & "," & vbNewLine & "Can you please let me know the statuses of the projects below." & vbNewLine
oWrdDoc.Range.InsertBefore Text:=MsgText
'******Clearing out filter and selection******
ActiveSheet.ListObjects("Table1").AutoFilter.ShowAllData
Application.CutCopyMode = False
Range("G:R").EntireColumn.Hidden = False
Range("A:A").EntireColumn.Hidden = False
ActiveSheet.Range("Table1").AutoFilter Field:=3, Criteria1:=">=1/31/2021"
End With
Set oLookItm = Nothing
Set oLookApp = Nothing
Application.ScreenUpdating = True
End Sub

Send mail on condition (Only if user fills specific rows)

I want to code a VBA such that the mail can be sent only if the user fills in details in rows. If not, an alert showing "Cannot send update. Fill the details completely" should pop up on the users screen.
Eg: The user has to fil Columns "A to J" and "M". If not they cannot send mail and pop up should ask them to enter it.
I have the following code as below,
Sub MAIL()
Dim EmailApp As Outlook.Application
Dim Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
EmailItem.To = "abc#gmail.com"
EmailItem.Subject = " "
EmailItem.HTMLBody = ""
Source = ThisWorkbook.FullName
EmailItem.Attachments.Add Source
EmailItem.Send
End Sub
Please help me provide alerts to users. I am completely new to this.
Please, use the next function. It will check if at least a cell is filled in all columns of the range ("A:J, M:M"). In such a case it returns True. Otherwise, it send a relevant message and returns false, stopping the mail sending:
Function checkIfOK() As Boolean
Dim rng As Range, ar As Range, i As Long
Set rng = Range("A:J,M:M")
For Each ar In rng.Areas
For i = 1 To ar.Columns.count
If WorksheetFunction.CountA(ar.Columns(i)) > 1 Then
MsgBox "Column " & Split(ar.Columns(i).cells(1).Address, "$")(1) & " is empty..."
Exit Function
End If
Next i
Next ar
checkIfOK = True
End Function
You have to use it in your code in the next way:
Sub MAIL()
If Not checkIfOK Then Exit Sub 'it stop the code here if the function returns False
Dim EmailApp As Outlook.Application, Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
EmailItem.To = "abc#gmail.com"
EmailItem.Subject = " "
EmailItem.HtmlBody = ""
Source = ThisWorkbook.fullName
EmailItem.Attachments.Add Source
EmailItem.Send
End Sub
The function has been built on the above mentioned assumption. I asked you in my comment "How this to be appreciated?" and you did not answer anything...

How to display emails one at a time in a loop?

I am trying to display all emails created with a loop, one at a time.
In the code below but I want to add an option to either send the emails automatically, or see them displayed and then send them manually.
While it opens the email item and displays it, when it loops it closes the previous one and opens a new one. I would like to open one and then another one as the loop goes.
Sub Test()
Dim i As Integer
Dim wB As Workbook: Set wB = ThisWorkbook
Dim wsD As Worksheet: Set wsD = wB.Worksheets("Data")
Dim wsE As Worksheet: Set wsE = wB.Worksheets("Email Format")
Dim LastRowsData As Integer
Dim LastRowEmail As Integer
Dim OA As Outlook.Application: Set OA = New Outlook.Application
Dim msg As Outlook.MailItem: Set msg = OA.CreateItem(olMailItem)
Dim Recipient As String
Recipient = Worksheets("Email Format").Range("A2")
LastRowsData = Worksheets("Data").Cells(Rows.Count, 1).End(xlUp).Row + 1
LastRowEmail = Worksheets("Email Format").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LastRowsData
If Not IsError(Application.Match(wsD.Range("H" & i).Value, _
wsD.Range("A1:A" & LastRowsData), 0)) Then
LastRowEmail = LastRowEmail + 1
wsE.Range("A" & LastRowEmail).Value = wsD.Range("G" & i).Value
End If
Next i
For i = 2 To LastRowEmail
With msg
.BodyFormat = olFormatHTML
.HTMLBody = wsE.Range("D" & i).Value
.To = wsE.Range("A" & i).Value
.Subject = wsE.Range("C" & i).Value
.Display
End With
Next i
End Sub
Bring Set msg = OA.CreateItem(olMailItem) into your second FOR loop. Then have a msgbox at the end to ask the user if they want to send the msg. If they do, send the msg. If they dont, display a second msg where the user has to click on continue before creating a new item – Zac yesterday

Remove the signature when opening an Outlook template in Excel

I'm trying to open an Outlook template (.oft) file from Excel but without appending the user's signature. I can't get this to work.
I know I need to delete the hidden bookmark "_MailAutoSig" but I can't figure out how. I've tried to follow this guide but it's out of date and doesn't work with Outlook / Excel 2016: https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/dd492012(v=office.12)#176-working-with-outlook-signatures
Here is my code
Option Explicit
Sub openEmail()
Dim cfgFromEmail As String
Dim cfgNotice As String
Dim cfgTemplate As String
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim rownum As Integer
Dim colnum As Integer
rownum = 6
cfgFromEmail = Sheets("Email").Range("O5").Value
cfgNotice = Sheets("Email").Cells(rownum, 10) '10 = column J
cfgTemplate = Sheets("Email").Cells(rownum, 11) '11 = column K
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = appOutlook.CreateItemFromTemplate("\\location\to\template\" & cfgTemplate & ".oft")
'Set template = mailApp.CreateItem(olMailItem) 'Creates a blank email
If cfgNotice <> "null" Then 'If is not blank
MsgBox cfgNotice, vbInformation, "Before you send the email"
End If
With newEmail
.SentOnBehalfOfName = cfgFromEmail
.Display 'Show the email
End With
Set newEmail = Nothing
Set appOutlook = Nothing
End Sub
Any help is greatly appreciated. I have spent several hours searching Google and Stack Overflow to no luck.
If the email template is not too complicated, you may be able to just create a new email and create the template without signature using HTML:
Sub emailgenerator
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim emailBody As String
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = olApp.CreateItem(olMailItem)
emailBody = "<p>Header</p><br><p>body area or something</p>"
emailBody = emailBody & "<table></table>" ' maybe add tables and whatever is needed
With newEmail
.To = "abc#abc.com"
.CC = "def#def.com"
.Subject = "Test"
.SentOnBehalfOfName = "youremail#youremail.com" ' could disregard this
.HTMLBody = emailBody
.Save
.Close olPromptForSave
End With
End Sub
This will take some looking into HTML but you can probably recreate the template with enough effort.
I believe when I tried this method for another project my signature wasn't getting appended automatically as it would with a template but not sure... best of luck
I have found a solution thanks to this stack overflow post
We need to save our template as HTML, then manually create a new email using the HTML code.
I'm yet to add images to the code but I think this will be easy using a find and replace method.
Final code without images:
Option Explicit
Sub openEmail(rownum As Integer)
Dim cfgFromEmail As String
Dim cfgNotice As String
Dim cfgTemplate As String
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim htmlPath As String
'Dim rownum As Integer
'Dim colnum As Integer
'rownum = 6
cfgFromEmail = Sheets("Email").Range("O5").Value
cfgNotice = Sheets("Email").Cells(rownum, 10) '10 = column J
cfgTemplate = Sheets("Email").Cells(rownum, 11) '11 = column K
htmlPath = "\\shared\drive\path\to\template\goes\here\" & cfgTemplate & ".htm"
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = appOutlook.CreateItem(olMailItem) 'Creates a blank email
If cfgNotice <> "null" Then 'If is not blank
MsgBox cfgNotice, vbInformation, "Before you send the email"
End If
With newEmail
.SentOnBehalfOfName = cfgFromEmail
.HTMLBody = HTMLtoString(htmlPath)
'Refer to and fill in variable items in template
'.Body = Replace(.Body, "<< clientname >>", Worksheets("Clients").Range(1, 2))
'.HTMLBody = Replace(.HTMLBody, "<< clientname >>", Worksheets("Clients").Range(1, 2))
.Display 'Show the email
End With
Set newEmail = Nothing
Set appOutlook = Nothing
End Sub
Function HTMLtoString(htmlPath As String)
'Returns a string after reading the contents of a given file
HTMLtoString = CreateObject("Scripting.FileSystemObject").OpenTextFile(htmlPath).ReadAll()
End Function
In case anyone's looking for solutions not involving parsing HTML tags, here's a relatively simple one. Make sure to have the Microsoft Word library referenced.
Dim myItem As Outlook.MailItem
Dim myInspector As Outlook.Inspector
Dim myDoc As Word.Document
Set myItem = _
Outlook.Application.CreateItemFromTemplate(TemplateName & ".oft")
.Display
Set myInspector = Application.ActiveInspector
Set myDoc = myInspector.WordEditor
myDoc.Bookmarks("_MailAutoSig").Range.Delete

Opening Outlook address book from Excel

I'm using VBA in Excel 2010, with Outlook 2010 (already open).
How could I write a sub such that:
1 Outlook address book opens;
2 The user selects a contact and clicks ok;
3 The contact's first name, last name and email address are stored in cells of the active worksheet?
I tried with this method without success: SelectNamesDialog Object
Also I'm not sure if I need to use: Application.GetNamespace("MAPI")
You are on the right avenue, the SelectNamesDialog is exactly what you are looking for. The GetNamepsace method equals to the Session property used in the sample code:
Sub ShowContactsInDialog()
Dim oDialog As SelectNamesDialog
Dim oAL As AddressList
Dim oContacts As Folder
Set oDialog = Application.Session.GetSelectNamesDialog
Set oContacts = _
Application.Session.GetDefaultFolder(olFolderContacts)
'Look for the address list that corresponds with the Contacts folder
For Each oAL In Application.Session.AddressLists
If oAL.GetContactsFolder = oContacts Then
Exit For
End If
Next
With oDialog
'Initialize the dialog box with the address list representing the Contacts folder
.InitialAddressList = oAL
.ShowOnlyInitialAddressList = True
If .Display Then
'Recipients Resolved
'Access Recipients using oDialog.Recipients
End If
End With
End Sub
You may find the following articles helpful:
How to automate Outlook from another program
Automating Outlook from a Visual Basic Application
Here is how to get all the details from a selected contact in the GAL:
You need to open the Global Address List and not the contacts from the contact folder, and use an Outlook.ExchangeUser object as explained on this page: see last answer from David Zemens.
Private Sub cmdSetProjectMember1_Click()
Dim olApp As Outlook.Application
Dim oDialog As SelectNamesDialog
Dim oGAL As AddressList
Dim myAddrEntry As AddressEntry
Dim exchUser As Outlook.ExchangeUser
Dim AliasName As String
Dim FirstName As String
Dim LastName As String
Dim EmailAddress As String
Set olApp = GetObject(, "Outlook.Application")
Set oDialog = olApp.Session.GetSelectNamesDialog
Set oGAL = olApp.GetNamespace("MAPI").AddressLists("Global Address List")
With oDialog
.AllowMultipleSelection = False
.InitialAddressList = oGAL
.ShowOnlyInitialAddressList = True
If .Display Then
AliasName = oDialog.Recipients.Item(1).Name
Set myAddrEntry = oGAL.AddressEntries(AliasName)
Set exchUser = myAddrEntry.GetExchangeUser
If Not exchUser Is Nothing Then
FirstName = exchUser.FirstName
LastName = exchUser.LastName
EmailAddress = exchUser.PrimarySmtpAddress
'...
MsgBox "You selected contact: " & vbNewLine & _
"FirstName: " & FirstName & vbNewLine & _
"LastName:" & LastName & vbNewLine & _
"EmailAddress: " & EmailAddress
End If
End If
End With
Set olApp = Nothing
Set oDialog = Nothing
Set oGAL = Nothing
Set myAddrEntry = Nothing
Set exchUser = Nothing
End Sub

Resources