Using a macro to select a row of text and email it...

pontybiker

Board Regular
Joined
Oct 27, 2015
Messages
73
Hi,

If possible, I would like the ability to select text from an excel workbook and email it to an email address. The email address would be dependent on what text is in a certain cell.

This is an example of the workbook containing the data (workbook A):
Sport£1£2AAAA
Education£2£2BBBB
Managment£6£1CCCC
Art£4£3DDDD

<tbody>
</tbody>

This is an example of the email workbook (workbook B);
Sportj@j.com
Educationb@j.com
Managementg@j.com
Artk@j.com

<tbody>
</tbody>

So the code would need to email the row of text in workbook A to the email address in workbook B by matching the text in column A in workbook A to the correct email address in column B in workbook B.

I hope this makes sense. I realise this may be asking a lot. As always, I honestly do appreciate anyone's help with these questions.

Kind regards,

J.
 
Sorry mate, been out on my lunch break so have only just seen your replies. Leave it with me and I will see if I can tweak it accordingly to work with 2 separate workbooks.

With regards to the second part of your query, do you mean you want it to go through each cell in workbook1 column A and if there is a corresponding email address then send a mail to it? That means you dont need to select a row first it will work its way through all of them?

Please don't say sorry, I honestly can't believe you are helping me so much. I can't tell you how much I appreciate this.

Basically yes, but the text in column A in workbook A is the Department which is the same in workbook B column A. When this matches it needs to use the email address in column B in worksheet B to send the corresponding row in workbook A. So if the code finds the Art department in both spreadsheets i needs to email the text in the row in workbook A to the email address of the Art department in workbook B.

Does that make sense?

J.
 
Upvote 0

Excel Facts

Quick Sum
Select a range of cells. The total appears in bottom right of Excel screen. Right-click total to add Max, Min, Count, Average.
Please don't say sorry, I honestly can't believe you are helping me so much. I can't tell you how much I appreciate this.

Basically yes, but the text in column A in workbook A is the Department which is the same in workbook B column A. When this matches it needs to use the email address in column B in worksheet B to send the corresponding row in workbook A. So if the code finds the Art department in both spreadsheets i needs to email the text in the row in workbook A to the email address of the Art department in workbook B.

Does that make sense?

J.
Yup, that much is understood. I am just querying if you want to loop through all rows in workbook A and mail to them if a corresponding email address is found. This will all happen automatically on a single run of the macro, so if you have 10 departments in column A of workbook A it will run 10 checks (one for each department) and will mail the corresponding row data so long as it finds a matching row in workbook B.

That's what you're wanting, right?
 
Upvote 0
Yup, that much is understood. I am just querying if you want to loop through all rows in workbook A and mail to them if a corresponding email address is found. This will all happen automatically on a single run of the macro, so if you have 10 departments in column A of workbook A it will run 10 checks (one for each department) and will mail the corresponding row data so long as it finds a matching row in workbook B.

That's what you're wanting, right?

Yeah, that's spot on! I think there will be over 170 rows if that's of any use?
 
Upvote 0
Yeah, that's spot on! I think there will be over 170 rows if that's of any use?
OK, so I may be making this over complicated, but I think this will work for you nicely. It will:

- Check if workbook B is open or not and will open it if required (there is some additional code that needs to be added to your workbook, I'll get to that in a minute)
- Work out how many departments are in Sheet1 column A of workbook A (assumes there are no headers)
- Work out how many email addresses are in Sheet1 column A of workbook B (assumes there are no headers)
- Systematically work through each department in workbook A and send the corresponding email if possible
- Display an optional message for any departments where it doesn't find a match
- Display a message at the end to confirm it has checked all entries from workbook A

You will need to amend any parts in bold red to correctly reflect the actual filepath for workbook B.
You may also want to delete the whole bold blue section if you don't want to see messages relating to departments that cannot be found in workbook B.
If the sheets we are looking at in each workbook are not actually the first sheet then you will need to change the bold green Sheet(1) parts to correctly reflect what number tab we are dealing with, e.g. Sheets(3) would be whatever is the 3rd tab.
If workbook A has headers then you will need to change Set cRange = wb1.Sheets(1).Range("A1:A" & LastRow1) to Set cRange = wb1.Sheets(1).Range("A2:A" & LastRow1)
If workbook B has headers then you will need to change Set lRange = wb2.Sheets(1).Range("A1:A" & LastRow1) to Set lRange = wb2.Sheets(1).Range("A2:A" & LastRow1)

The first thing you will want to do is put the following code in a standard module in your workbook (the same as your main macro is fine). This code contains a function for checking if a workbook is already open or not. I have referenced this in my tweaked macro for you so it is essential you add it in:

Rich (BB code):
Function IsFileOpen(filename As String)
' Defines variables
    Dim filenum As Integer, errnum As Integer


    On Error Resume Next   ' Turn error checking off.
    filenum = FreeFile()   ' Get a free file number.
' Attempt to open the file and lock it.
    Open filename For Input Lock Read As #filenum
    Close filenum          ' Close the file.
    errnum = Err           ' Save the error number that occurred.
    On Error GoTo 0        ' Turn error checking back on.


' Check to see which error occurred.
    Select Case errnum


' No error occurred.
' File is NOT already open by another user.
        Case 0
            IsFileOpen = False


' Error number for "Permission Denied."
' File is already opened by another user.
        Case 70
            IsFileOpen = True


' Another error occurred.
        Case Else
            Error errnum
    End Select
End Function

Once you have that in place, replace your original macro with the following. This has the highlighted parts I mentioned above which may need changing:

Rich (BB code):
Sub MailWithLookupLoop()
' Defines variables
Dim wb1 As Workbook, wb2 As Workbook, FindString As String, EmailAdd As String, Cell As Range, cRange As Range, lRange As Range
' Disable screen updating to reduce flicker
Application.ScreenUpdating = False


'''SETUP WORKBOOK 1'''
' Sets wb1 as the main workbook
Set wb1 = ThisWorkbook
' Defines LastRow1 as the last row of data on wb1 sheet1 based on column A
LastRow1 = wb1.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets the check range as A1 to the last row of A on wb1 sheet1
Set cRange = wb1.Sheets(1).Range("A1:A" & LastRow1)


'''SETUP WORKBOOK 2'''
' If EmailList is not already open (amend file path as required) then...
If Not IsFileOpen("C:\TestFolder\PontyBiker\emaillist.xlsx") Then
    ' Open and Sets wb2 as emaillist.xlsx (amend file path as required)
    Set wb2 = Workbooks.Open("C:\TestFolder\PontyBiker\emaillist.xlsx")
    ' Re-activate wb1
    wb1.Activate
' Else if EmailList is already open then...
Else
    ' Sets wb2 as emaillist.xlsx
    Set wb2 = Workbooks("emaillist.xlsx")
End If
' Defines LastRow2 as the last row of data of wb2 sheet1 based on column A
LastRow2 = wb2.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets lookup range as A1 to the last row of B on wb2 sheet1
Set lRange = wb2.Sheets(1).Range("A1:B" & LastRow2)


'''START LOOP'''
' For each cell in the check range
For Each Cell In cRange
    ' Sets variable FindString as the contents of the current cell on wb1 sheet1
    FindString = Cell.Value
    ' On error continue
    On Error Resume Next
    ' Sets variable EmailAdd as the corresponding email address based on the FindString on wb2 sheet1
    EmailAdd = Application.WorksheetFunction.VLookup(FindString, lRange, 2, False)
       
'''
'''OPTIONAL MESSAGE IF DEPARTMENT IS NOT FOUND - DELETE THE BELOW SECTION FOR SEAMLESS PROCESSING'''
' If an error is encountered then...
    If Err.Number <> 0 Then
        ' Display message that the department was not found and move on
        MsgBox FindString & " department not found.  Moving on."
    End If
'''END OF OPTIONAL MESSAGE PART - DELETE THE ABOVE SECTION FOR SEAMLESS PROCESSING'''
'''
    
    ' If EmailAdd is not blank then
    If EmailAdd <> "" Then
        ' Select the range of cells on the ws1 as this is what will be emailed
        wb1.Sheets(1).Range("A" & Cell.Row, "D" & Cell.Row).Select
        ' Show the envelope on the ActiveWorkbook
        ActiveWorkbook.EnvelopeVisible = True
        With ActiveSheet.MailEnvelope
            ' Sets the optional introduction fields thats adds
           .Introduction = "This is what will be in the opening of your email"
           ' Send to the email address in EmailAdd
           .Item.To = EmailAdd
           ' Define your desired subject line
           .Item.Subject = "Your chosen email subject"
           ' Send the email
           .Item.Send
        End With
    End If
' Check next cell in check range
Next Cell
'''END LOOP'''


' Re-enable screen updating
Application.ScreenUpdating = True
' Display message box to confirm the process has completed
MsgBox "All mails sent."


End Sub
 
Last edited:
Upvote 0
Man, I am totally blown away by your generosity.

I have to go to the hospital this afternoon so I wont have chance to test it. I will be back in work in the morning. As soon as I have finished testing I will let you know the outcome.

I truly can't thank you enough for this.

Kind regards,

Jamie.
 
Upvote 0
Man, I am totally blown away by your generosity.

I have to go to the hospital this afternoon so I wont have chance to test it. I will be back in work in the morning. As soon as I have finished testing I will let you know the outcome.

I truly can't thank you enough for this.

Kind regards,

Jamie.
You're most welcome mate. I hope everything goes well at the hospital, and that the code does as you need when you test it tomorrow. If you have any problems feel free to come back here and give me a shout.

Also I just noticed another typo in my description here:

If workbook B has headers then you will need to change Set lRange = wb2.Sheets(1).Range("A1:A" & LastRow1) to Set lRange = wb2.Sheets(1).Range("A2:A" & LastRow2)

The bold red is corrected text.
 
Upvote 0
Hi Fishboy,

I tested your code this morning. It runs through opening the emailist.xlsx and then a message pops up saying "all mails sent" but not emails actually get sent.

Also, I know there are departments in workbook A that don't exist in workbook B so I was expecting a message to pop up say "xxx doesn't exis, moving on"?

Sorry to come back to you with this problem.

J.
 
Upvote 0
Hold on a second, I think I may know what is the issue. in the code
Code:
[COLOR=#574123]Set wb1 = ThisWorkbook[/COLOR]
. I've placed the code in personal macros which I think is the issue. I have set the wb1 = the location of the workbook A. I'll run it again and let you know the outcome.
 
Upvote 0
OK, I think we are getting somewhere. The good news I'm now receiving file via email, the bad news is I don't think it is running any checks. I'm receiving an email for every line in workbook A even if it doesn't have a corresponding email address in workbook B?

I thought I would upload the code just in case I've messed something up:

Code:
Sub MailWithLookupLoop()
' Defines variables
Dim wb1 As Workbook, wb2 As Workbook, FindString As String, EmailAdd As String, Cell As Range, cRange As Range, lRange As Range
' Disable screen updating to reduce flicker
Application.ScreenUpdating = False




'''SETUP WORKBOOK 1'''
' Sets wb1 as the main workbook
Set wb1 = Workbooks.Open("C:\Users\sm18441\Documents\Call Logger\Telephone-Charges.xlsx")


' Defines LastRow1 as the last row of data on wb1 sheet1 based on column A
LastRow1 = wb1.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets the check range as A1 to the last row of A on wb1 sheet1
Set cRange = wb1.Sheets(1).Range("A1:A" & LastRow1)




'''SETUP WORKBOOK 2'''
' If EmailList is not already open (amend file path as required) then...
If Not IsFileOpen("C:\Users\sm18441\Documents\Call Logger\emaillist.xlsx") Then
    ' Open and Sets wb2 as emaillist.xlsx (amend file path as required)
    Set wb2 = Workbooks.Open("C:\Users\sm18441\Documents\Call Logger\emaillist.xlsx")
    ' Re-activate wb1
    wb1.Activate
' Else if EmailList is already open then...
Else
    ' Sets wb2 as emaillist.xlsx
    Set wb2 = Workbooks("emaillist.xlsx")
End If
' Defines LastRow2 as the last row of data of wb2 sheet1 based on column A
LastRow2 = wb2.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets lookup range as A1 to the last row of B on wb2 sheet1
Set lRange = wb2.Sheets(1).Range("A1:B" & LastRow2)




'''START LOOP'''
' For each cell in the check range
For Each Cell In cRange
    ' Sets variable FindString as the contents of the current cell on wb1 sheet1
    FindString = Cell.Value
    ' On error continue
    On Error Resume Next
    ' Sets variable EmailAdd as the corresponding email address based on the FindString on wb2 sheet1
    EmailAdd = Application.WorksheetFunction.VLookup(FindString, lRange, 2, False)
       
'''
'''OPTIONAL MESSAGE IF DEPARTMENT IS NOT FOUND - DELETE THE BELOW SECTION FOR SEAMLESS PROCESSING'''
' If an error is encountered then...
    If Err.Number <> 0 Then
        ' Display message that the department was not found and move on
        MsgBox FindString & " department not found.  Moving on."
    End If
'''END OF OPTIONAL MESSAGE PART - DELETE THE ABOVE SECTION FOR SEAMLESS PROCESSING'''
'''
    
    ' If EmailAdd is not blank then
    If EmailAdd <> "" Then
        ' Select the range of cells on the ws1 as this is what will be emailed
        wb1.Sheets(1).Range("A" & Cell.Row, "D" & Cell.Row).Select
        ' Show the envelope on the ActiveWorkbook
        ActiveWorkbook.EnvelopeVisible = True
        With ActiveSheet.MailEnvelope
            ' Sets the optional introduction fields thats adds
           .Introduction = "This is what will be in the opening of your email"
           ' Send to the email address in EmailAdd
           .Item.To = EmailAdd
           ' Define your desired subject line
           .Item.Subject = "Your chosen email subject"
           ' Send the email
           .Item.Send
        End With
    End If
' Check next cell in check range
Next Cell
'''END LOOP'''




' Re-enable screen updating
Application.ScreenUpdating = True
' Display message box to confirm the process has completed
MsgBox "All mails sent."




End Sub

J.
 
Upvote 0
OK, I think we are getting somewhere. The good news I'm now receiving file via email, the bad news is I don't think it is running any checks. I'm receiving an email for every line in workbook A even if it doesn't have a corresponding email address in workbook B?

I thought I would upload the code just in case I've messed something up:

Code:
Sub MailWithLookupLoop()
' Defines variables
Dim wb1 As Workbook, wb2 As Workbook, FindString As String, EmailAdd As String, Cell As Range, cRange As Range, lRange As Range
' Disable screen updating to reduce flicker
Application.ScreenUpdating = False




'''SETUP WORKBOOK 1'''
' Sets wb1 as the main workbook
Set wb1 = Workbooks.Open("C:\Users\sm18441\Documents\Call Logger\Telephone-Charges.xlsx")


' Defines LastRow1 as the last row of data on wb1 sheet1 based on column A
LastRow1 = wb1.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets the check range as A1 to the last row of A on wb1 sheet1
Set cRange = wb1.Sheets(1).Range("A1:A" & LastRow1)




'''SETUP WORKBOOK 2'''
' If EmailList is not already open (amend file path as required) then...
If Not IsFileOpen("C:\Users\sm18441\Documents\Call Logger\emaillist.xlsx") Then
    ' Open and Sets wb2 as emaillist.xlsx (amend file path as required)
    Set wb2 = Workbooks.Open("C:\Users\sm18441\Documents\Call Logger\emaillist.xlsx")
    ' Re-activate wb1
    wb1.Activate
' Else if EmailList is already open then...
Else
    ' Sets wb2 as emaillist.xlsx
    Set wb2 = Workbooks("emaillist.xlsx")
End If
' Defines LastRow2 as the last row of data of wb2 sheet1 based on column A
LastRow2 = wb2.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
' Sets lookup range as A1 to the last row of B on wb2 sheet1
Set lRange = wb2.Sheets(1).Range("A1:B" & LastRow2)




'''START LOOP'''
' For each cell in the check range
For Each Cell In cRange
    ' Sets variable FindString as the contents of the current cell on wb1 sheet1
    FindString = Cell.Value
    ' On error continue
    On Error Resume Next
    ' Sets variable EmailAdd as the corresponding email address based on the FindString on wb2 sheet1
    EmailAdd = Application.WorksheetFunction.VLookup(FindString, lRange, 2, False)
       
'''
'''OPTIONAL MESSAGE IF DEPARTMENT IS NOT FOUND - DELETE THE BELOW SECTION FOR SEAMLESS PROCESSING'''
' If an error is encountered then...
    If Err.Number <> 0 Then
        ' Display message that the department was not found and move on
        MsgBox FindString & " department not found.  Moving on."
    End If
'''END OF OPTIONAL MESSAGE PART - DELETE THE ABOVE SECTION FOR SEAMLESS PROCESSING'''
'''
    
    ' If EmailAdd is not blank then
    If EmailAdd <> "" Then
        ' Select the range of cells on the ws1 as this is what will be emailed
        wb1.Sheets(1).Range("A" & Cell.Row, "D" & Cell.Row).Select
        ' Show the envelope on the ActiveWorkbook
        ActiveWorkbook.EnvelopeVisible = True
        With ActiveSheet.MailEnvelope
            ' Sets the optional introduction fields thats adds
           .Introduction = "This is what will be in the opening of your email"
           ' Send to the email address in EmailAdd
           .Item.To = EmailAdd
           ' Define your desired subject line
           .Item.Subject = "Your chosen email subject"
           ' Send the email
           .Item.Send
        End With
    End If
' Check next cell in check range
Next Cell
'''END LOOP'''




' Re-enable screen updating
Application.ScreenUpdating = True
' Display message box to confirm the process has completed
MsgBox "All mails sent."




End Sub

J.
Hello mate,

I am sorry to hear you are having issues with the code. I am looking into it for you now.
 
Upvote 0

Forum statistics

Threads
1,215,294
Messages
6,124,100
Members
449,142
Latest member
championbowler

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top