multiple recipients email mismatch in VBA - vba

I am trying to add multiple recipients' emails that are on a range of cells.
I am able to select the range of emails on the sheet.
However, I kept getting this mismatch error and I have no idea how to solve it.
I have been looking around for solutions and did the same steps.
Please pardon me, i am new to VBA.
I would very much appreciate your help.
My code is below,
Private Sub CommandButton1_Click()
Dim olapp As Object
Dim olmail As Object
Dim recip As String
lastr = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
'this is for the range of data to be copied on the body but have yet to do it
lastr2 = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, 7).End(xlUp).Row
recip = ThisWorkbook.Sheets("Sheet1").Range("G3:G" & lastr2).Value
'mismatch after this step
Set olapp = CreateObject("Outlook.Application")
Set olmail = olapp.CreateItem(0)
With MItem
.to = recip
.Subject = "hello"
.Body = "whats up"
.display
End With
Any idea why is this happening?

You're trying to assign an array (a range of multiple cells is an Array) to a string variable. WIthout testing, I know you can resolve this with a For Each loop, as Jaycal's comment suggested:
Dim cl as Range
For each cl in ThisWorkbook.Sheets("Sheet1").Range("G3:G" & lastr2).Cells
recip = recip & ";" & cl.Value
Next
But you could simplify by using the string Join function. The Join function effectively performs this loop on an array of strings, so it saves you an unnecessary loop. I modify to use a range variable for legibility:
Dim sendRange as Range
Set sendRange = ThisWorkbook.Sheets("Sheet1").Range("G3:G" & lastr2)
recip = Join(Application.Transpose(sendRange.Value), ";")
Whichever method you use, you will be able to use the same With block.
With MItem
.to = recip
.Subject = "hello"
.Body = "whats up"
.display
End With

Related

Cannot run my codes for sending email in other machine

I am helping my friend to develop her codes using VBA. I have successfully run these codes in my laptop yet she is encountering errors when we copy the codes to her machine.
Here's my code:
Sub Test()
Call sendingEmailWithChecklist("Book1.xlsm")
End Sub
Sub sendingEmailWithChecklist(workbookName As String)
Dim recipient As String
Dim cc As String
Dim subject As String
Dim body As Range
Dim greetings As String
Dim message As String
Dim signature As String
Dim ebody As String
Dim olApp As Outlook.Application
Dim olInsp As Outlook.Inspector
Dim wdDoc As Word.Document
Dim olEmail As Outlook.MailItem
Dim worksheetName As String
Dim content As Range
Set olApp = New Outlook.Application
Set olEmail = olApp.CreateItem(olMailItem)
Sheet2.Activate
recipient = Range("B3").Value
cc = Range("B4").Value
subject = Range("B5").Value
greetings = Range("B6").Value
message = Range("B7").Value
ebody = greetings & vbNewLine & vbNewLine & message & vbNewLine
signature = Range("B8").Value
'Workbooks(workbookName).Activate
worksheetName = "Sheet1"
With olEmail
.Display
.To = recipient
.cc = cc
.subject = subject
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
Workbooks(workbookName).Worksheets(worksheetName).Activate
Workbooks(workbookName).Worksheets(worksheetName).Cells.Copy
'Range("A1:F17").Select
'Selection.Copy
End With
With olEmail
.Display
wdDoc.Range(1, 1).Paste
wdDoc.Range.InsertBefore ebody
'.Send
End With
End Sub
wdDoc.Range(1,1).Paste was her error. We have both declared same references from tools yet the error is still on this line. What could be the possible error why it doesn't run on her machine?
PS. She doesn't want to use HTMLbody.
Instead of
wdDoc.Range(1, 1).Paste
Try
wdDoc.Range.Paste
If you want to further control the way you paste your data in the body of mail you may want to use the Word Selection object (expression) instead of Range. Something like:
wdDoc.Application.Selection.PasteAndFormat wdFormatOriginalFormatting
Above paste the copied item with its original formatting. You may select other PasteAndFormat options depending on your expected outcome.

Sending multiple and and different attachments through VBA and Outlook

I'm by no means an expert and I want to send the multiple and different attachments (e.g. Person1 receives BOTH attch.1 and attach.2; Person2 receives attch.3 and attch. 5 etc).
My code:
Sub SendEmail(what_address As String, subject_line As String, mail_body As String)
Dim dlApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
Set olMail = olApp.CreateItem(olMailItem)
olMail.To = what_address
olMail.Subject = subject_line
olMail.Body = mail_body
olMail.Send
End Sub
Sub SendMassEmail()
Dim mail_body_message As String
Dim title As String
row_number = 1
Do
DoEvents
row_number = row_number + 1
mail_body_message = Sheet1.Range("D2")
title = Sheet1.Range("B" & row_number)
mail_body_message = Replace(mail_body_message, "replace_name_here", title)
Call SendEmail(Sheet1.Range("A" & row_number), "This is a test", mail_body_message)
Loop Until row_number = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
End Sub
I think your code requires some work but the snippet below should help with adding multiple attachments. I have tried to add annotations that might be helpful.
Please note that the full path for each attachment must be known.
For example:
C:\TestFolder\TestSubfolder\TestFile.txt
You should be able to use the same looping concept to traverse across columns to handle multiple emails. It would be difficult to suggest the exact looping to be used without knowing the structure of your spreadsheet.
Sub GenerateEmails()
Dim OutApp As Object
Dim OutMail As Object
Dim myRange As Range
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = Outlook.Application.CreateItem(olMailItem)
'This will only generate a single email with multiple attachments.
'You will need another loop or something similar to process multiple emails the loop could
'be similar to the loop below that use offset to go down rows but instead
'you will offest across columns
With OutMail
'I have used hard coded cell ranges to define the values but you can use other
'methods.
.Subject = Range("A1").Value
.To = Range("A2").Value
.CC = Range("A3").Value
.Body = Range("A4").Value
'This is where you list of attachments will start
Set myRange = Range("A5")
'Keep going down one cell until no more attachment values are provided
Do Until myRange.Value = ""
'The value here needs to be the full attachment path including file name and extension
.Attachments.Add (myRange.Value)
'Set the range to be the next cell down
Set myRange = myRange.Offset(1, 0)
Loop
'This displays the email without sending.
.Display
'Once the code is correct you can use the .Send instead to actually send the emails.
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Excel VBA to Outlook: error Type Mismatch

I am trying to write a VBA code in Excel that will create an Outlook message which contains:
text in the body
a table
a signature at the bottom.
Below is a code that I wrote. It was working until I added the Excel Table object to the body of the message. It's coming up with an error message that says:
Run-time error: error type 13, Type Mismatch".
Can someone help with my code below?
Sub send()
Dim OApp As Object, OMail As Object, signature As String
Dim TOEMAIL As Range
Dim CCMEMAIL As Range
Dim SUBJECT As Range
Dim Workbook As Range
Dim Table As Range
Set TOEMAIL = Sheets("Macro").Range("D6")
Set CCEMAIL = Sheets("Macro").Range("D7")
Set SUBJECT = Sheets("Macro").Range("D8")
Set Workbook = Sheets("Macro").Range("D5")
Set Table = Sheets("Sheet1").Range("B7:B17")
Set OApp = CreateObject("Outlook.Application")
Set OMail = OApp.CreateItem(0)
With OMail
.Display
End With
signature = OMail.body
With OMail
.To = TOEMAIL
.CC = CCEMAIL
.SUBJECT = SUBJECT
.Attachments.Add (Workbook)
.body = "Hello, this is a test." & vbNewLine & Table & vbNewLine & signature & vbNewLine
End With
Set OMail = Nothing
Set OApp = Nothing
End Sub
MailItem.Body property expects a string. You are trying to concatenate a few strings and a Range object. It is your responsibility to extract the relevant data from that table and represent it as a string.
You would probably be better off creating an HTML table and setting the MailItem.HTMLBody property instead.

Refer 'To' field in Outlook to cell

I'm trying to create a macro on Excel VBA that will create an email and will populate the To field from the Excel cell K6.
When this code runs, I get the error message Run-time error'5': Invalid procedure call or argument.
Dim OutApp As Object
Dim MItem As Object
Dim cell As Range
Dim rng As Range
Dim Subj As String
Dim EmailAddr As String
Dim myRecipient As Object
Dim myRecipients As Object
Dim Recipient As String
Dim Msg As String
Dim ws1 As Worksheet
Dim DateNow As Date
Set ws1 = Sheets("Email")
'Create Outlook object
Set rng = ws1.Range("B6:F26").SpecialCells(xlCellTypeVisible)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set MItem = OutApp.CreateItem(0)
Set myRecipients = MItem.Recipients
myRecipients = ws1.Cells.Range("K6")
If Not myRecipients.ResolveAll Then
For Each myRecipient In myRecipients
If Not myRecipient.Resolved Then
MsgBox myRecipient.Name
End If
Next
End If
DateNow = Format(Now, "dd/MM/yyyy")
DateNow2 = Format(Now, "h:mm")
Msg = "This report was generated on " & DateNow & " at " & DateNow2 & "."
With MItem
.CC = EmailAddr2
.Subject = Subj
.HTMLBody = RangetoHTML(rng) & Msg
.Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = False
End With
Set MItem = Nothing
Set OutApp = Nothing
End Sub
If I use Set myRecipients = ws1.Cells.Range("K6") I get the error message Run-time error '438': Object doesn't support this property or method.
If I set the myRecipients As String, it says Object required.
I'm having lots of problems to understand late-binding Outlook in Excel VBA and I've read lots of things, but haven't found many sources on it that could explain this in a more didactic way.
Besides that, I'm also trying to, after adding the content of the cell, to Resolve (the effect of using ctrl + K on Outlook to resolve the email to the display name) the emails added to the To field, but I can't test it without making the first part work.
Thanks for the attention,
Edit: after Bruce Wayne's suggestion, I put them as Range, but now I'm getting a different error: Run-time error '-2147352567 (800200009)': Property is read-only.
Dim myRecipient As Range
Dim myRecipients As Range
In the middle of the code:
Set OutApp = CreateObject("Outlook.Application")
Set MItem = OutApp.CreateItem(0)
Set myRecipients = ws1.Cells.Range("K6")
Set MItem.Recipients = myRecipients
After Dmitry's suggestion:
Set OutApp = CreateObject("Outlook.Application")
Set MItem = OutApp.CreateItem(0)
Set myRecipients = ws1.Cells.Range("K6")
Set myRecipient = MItem.Recipients.Add(myRecipients)
If Not myRecipients.ResolveAll Then
For Each myRecipient In myRecipients
If Not myRecipient.Resolved Then
MsgBox myRecipient.Name
End If
Next
End If
But I get the error message: Run-time error '438': Object doesn't support this property or method marked on the If Not myRecipients.ResolveAll Then. If I delete all the If part, the code runs fine. But it's very important to me that I'm able to resolve the names and emails in the To/CC fields.
Recipients property is indeed read-only. You need to either call MailItem.Recipients.Add for each recipient or set the To / CC/ BCC properties to a ";" separated list of names or addresses.
UPDATE:
Set OutApp = CreateObject("Outlook.Application")
Set MItem = OutApp.CreateItem(0)
Set recipName = ws1.Cells.Range("K6").Value
Set myRecipient = MItem.Recipients.Add(recipName)
If Not myRecipient.Resolve Then
MsgBox myRecipient.Name
End If
I think it's due to the fact that you're setting myRecipients and myRecipient as an Object but want to set it with what is essentially a Range type. Try:
Dim myRecipients as Range, myRecipient as Range
Dim objMyRecipients as Object, objMyRecipient as Object 'create a variable that holds the object
Then, when you need to use them as an object, you have a separate variable to do so.

Issue with reading data from specific cells in Excel VBA

I'm attempting to send an email containing an Excel workbook from within the document using the built in VB macros. There is data in one of the sheets, which are relevant to sending the email (Subject, recipient etc). I am trying to access these using the Sheets object like so
Sub Button1_Click()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Dim cell As Object
Dim count As Integer
count = 0
For Each cell In Selection
count = count + 1
Next cell
If count <> 1 Then
MsgBox ("You must select exactly one cell, which shall be the e-mail address of the recipient")
Wscript.Quit
Else
recipient = ActiveCell.Value
End If
On Error Resume Next
With OutMail
.To = recipient
.CC = ""
.BCC = ""
.SentOnBehalfOfName = This.Sheets("MailContent").Range("A2").Value
.Subject = This.Sheets("MailContent").Range("A4").Value
.Body = This.Sheets("MailContent").Range("A6").Value & vbNewLine & This.Sheets("MailContent").Range("A7") & vbNewLine & vbNewLine & "Næste gang senest den " + This.Sheets("MailContent").Range("A10") & vbNewLine & vbNewLine & This.Sheets("MailContent").Range("A8")
.Attachments.Add ActiveWorkbook.Name
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I've also been able to replicate the same error with this small snippet
Sub Button1_Click()
Dim subjectCell As Range
subjectCell = This.Sheets("MailContent").Range("A2")
MsgBox (subjectCell.Value)
End Sub
I've tried using WorkSheets, Sheets, ActiveWorkbook to access the cells, but I'm sure it's just a problem of how I assign the data, since I'm not used to languages with syntax like VB. Any help is much appreciated, and if you need more info leave me a comment.
You need to use the 'Set' keyword to assign to a range.
Set subjectCell = ThisWorkbook.Sheets("MailContent").Range("A2")
This still catches me out on an irritatingly regular basis.