如何从 Excel table 创建电子邮件?
How to create emails from Excel table?
我在 Excel 中有一个 table。它的构建如下:
|Information on food|
|date: April 28th, 2021|
|Person|Email|Apples|Bananas|Bread|
|------|-----|------|-------|-----|
|Person_A|person_A@mailme.com|3|8|9|
|Person_B|person_B@mailme.com|10|59|11|
|Person _C|person_C@maime.com|98|12|20|
table 中还有一个日期字段。对于测试,这可以设置为今天的日期。
根据这些信息,我正在寻找一个 VBA 代码,该代码可以向每个列出的人发送一封电子邮件,并告诉他们他们在特定日期吃了什么。
我需要访问 table 中的几个字段,同时循环遍历电子邮件地址。然后我想 VBA 打开 Outlook 并准备电子邮件。最好不要发送它们,这样我可以在发送邮件之前最后看一下。
通过范围等专门访问某些单元格会很好。我使用的是 Excel/Outlook 2016。
如何在 VBA 中实现?
假设数据是一个命名的 table 并且 title/date 在 table 的角上方,如您的示例所示。 table 的所有行也都有有效数据。电子邮件已准备好并显示但未发送(除非您更改显示的代码)。
Option Explicit
Sub EmailMenu()
Const TBL_NAME = "Table1"
Const CSS = "body{font:12px Verdana};h1{font:14px Verdana Bold};"
Dim emails As Object, k
Set emails = CreateObject("Scripting.Dictionary")
Dim ws As Worksheet, rng As Range
Dim sName As String, sAddress As String
Dim r As Long, c As Integer, s As String, msg As String
Dim sTitle As String, sDate As String
Set ws = ThisWorkbook.Sheets("Sheet1")
Set rng = ws.ListObjects(TBL_NAME).Range
sTitle = rng.Cells(-1, 1)
sDate = rng.Cells(0, 1)
' prepare emails
For r = 2 To rng.Rows.Count
sName = rng.Cells(r, 1)
sAddress = rng.Cells(r, 2)
If InStr(sAddress, "@") = 0 Then
MsgBox "Invalid Email: '" & sAddress & "'", vbCritical, "Error Row " & r
Exit Sub
End If
s = "<style>" & CSS & "</style><h1>" & sDate & "<br>" & sName & "</h1>"
s = s & "<table border=""1"" cellspacing=""0"" cellpadding=""5"">" & _
"<tr bgcolor=""#ddddff""><th>Item</th><th>Qu.</th></tr>"
For c = 3 To rng.Columns.Count
s = s & "<tr><td>" & rng.Cells(1, c) & _
"</td><td>" & rng.Cells(r, c) & _
"</td></tr>" & vbCrLf
Next
s = s & "</table>"
' add to dictonary
emails.Add sAddress, Array(sName, sDate, s)
Next
' confirm
msg = "Do you want to send " & emails.Count & " emails ?"
If MsgBox(msg, vbYesNo) = vbNo Then Exit Sub
' send emails
Dim oApp As Object, oMail As Object, ar
Set oApp = CreateObject("Outlook.Application")
For Each k In emails.keys
ar = emails(k)
Set oMail = oApp.CreateItem(0)
With oMail
.To = CStr(k)
'.CC = "email@test.com"
.Subject = sTitle
.HTMLBody = ar(2)
.display ' or .send
End With
Next
oApp.Quit
End Sub
我在 Excel 中有一个 table。它的构建如下:
|Information on food|
|date: April 28th, 2021|
|Person|Email|Apples|Bananas|Bread|
|------|-----|------|-------|-----|
|Person_A|person_A@mailme.com|3|8|9|
|Person_B|person_B@mailme.com|10|59|11|
|Person _C|person_C@maime.com|98|12|20|
table 中还有一个日期字段。对于测试,这可以设置为今天的日期。
根据这些信息,我正在寻找一个 VBA 代码,该代码可以向每个列出的人发送一封电子邮件,并告诉他们他们在特定日期吃了什么。
我需要访问 table 中的几个字段,同时循环遍历电子邮件地址。然后我想 VBA 打开 Outlook 并准备电子邮件。最好不要发送它们,这样我可以在发送邮件之前最后看一下。
通过范围等专门访问某些单元格会很好。我使用的是 Excel/Outlook 2016。
如何在 VBA 中实现?
假设数据是一个命名的 table 并且 title/date 在 table 的角上方,如您的示例所示。 table 的所有行也都有有效数据。电子邮件已准备好并显示但未发送(除非您更改显示的代码)。
Option Explicit
Sub EmailMenu()
Const TBL_NAME = "Table1"
Const CSS = "body{font:12px Verdana};h1{font:14px Verdana Bold};"
Dim emails As Object, k
Set emails = CreateObject("Scripting.Dictionary")
Dim ws As Worksheet, rng As Range
Dim sName As String, sAddress As String
Dim r As Long, c As Integer, s As String, msg As String
Dim sTitle As String, sDate As String
Set ws = ThisWorkbook.Sheets("Sheet1")
Set rng = ws.ListObjects(TBL_NAME).Range
sTitle = rng.Cells(-1, 1)
sDate = rng.Cells(0, 1)
' prepare emails
For r = 2 To rng.Rows.Count
sName = rng.Cells(r, 1)
sAddress = rng.Cells(r, 2)
If InStr(sAddress, "@") = 0 Then
MsgBox "Invalid Email: '" & sAddress & "'", vbCritical, "Error Row " & r
Exit Sub
End If
s = "<style>" & CSS & "</style><h1>" & sDate & "<br>" & sName & "</h1>"
s = s & "<table border=""1"" cellspacing=""0"" cellpadding=""5"">" & _
"<tr bgcolor=""#ddddff""><th>Item</th><th>Qu.</th></tr>"
For c = 3 To rng.Columns.Count
s = s & "<tr><td>" & rng.Cells(1, c) & _
"</td><td>" & rng.Cells(r, c) & _
"</td></tr>" & vbCrLf
Next
s = s & "</table>"
' add to dictonary
emails.Add sAddress, Array(sName, sDate, s)
Next
' confirm
msg = "Do you want to send " & emails.Count & " emails ?"
If MsgBox(msg, vbYesNo) = vbNo Then Exit Sub
' send emails
Dim oApp As Object, oMail As Object, ar
Set oApp = CreateObject("Outlook.Application")
For Each k In emails.keys
ar = emails(k)
Set oMail = oApp.CreateItem(0)
With oMail
.To = CStr(k)
'.CC = "email@test.com"
.Subject = sTitle
.HTMLBody = ar(2)
.display ' or .send
End With
Next
oApp.Quit
End Sub