从 VB 代码通过电子邮件将多个范围作为附件发送
Posted
技术标签:
【中文标题】从 VB 代码通过电子邮件将多个范围作为附件发送【英文标题】:Emailing multiple ranges as attachments from VB code 【发布时间】:2022-01-02 06:26:58 【问题描述】:我使用来自 Internet 的一些标准代码来使用一个按钮在 Outlook 中创建一封电子邮件,其附件是工作表中按下该按钮的区域。代码运行良好。 如何扩展代码以附加两个或更多范围?在下面的代码中,我已经开始初始化第二个 Source 和 Dest,但随后对如何处理失去信心应用。
Private Sub CommandButton2_Click()
Dim Source As Range
Dim Source2 As Range
Dim Dest As Workbook
Dim Dest2 As Workbook
Dim wb As Workbook
Dim TempFilePath As String
Dim TempFileName As String
Dim FileExtStr As String
Dim AutoPrint As String
Dim FileFormatNum As Long
Dim OutApp As Object
Dim OutMail As Object
Set Source = Nothing
Set Source2 = Nothing
On Error Resume Next
Set Source = Range("A1:M47").SpecialCells(xlCellTypeVisible)
Set Source2 = Range("AB1:AN47").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Source Is Nothing Then
MsgBox "The source is not a range or the sheet is protected, please correct and try again.", vbOKOnly
Exit Sub
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb = ActiveWorkbook
Set Dest = Workbooks.Add(xlWBATWorksheet)
Set Dest2 = Workbooks.Add(xlWBATWorksheet)
Source.Copy
With Dest.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial Paste:=xlPasteValues
.Cells(1).PasteSpecial Paste:=xlPasteFormats
.Cells(1).Select
Application.CutCopyMode = False
End With
If Range("AC6") <> "" Then
Source2.Copy
With Dest2.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial Paste:=xlPasteValues
.Cells(1).PasteSpecial Paste:=xlPasteFormats
.Cells(1).Select
Application.CutCopyMode = False
End With
End If
TempFilePath = Environ$("temp") & "\"
TempFileName = "Selection of " & wb.Name & " " & Format(Now, "dd-mmm-yy h-mm-ss")
If Val(Application.Version) < 12 Then
'You use Excel 97-2003
FileExtStr = ".xls": FileFormatNum = -4143
Else
'You use Excel 2007-2016
FileExtStr = ".xlsx": FileFormatNum = 51
End If
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
AutoPrint = Range("Y6").Value
With Dest
.SaveAs TempFilePath & TempFileName & FileExtStr, FileFormat:=FileFormatNum
On Error Resume Next
With OutMail
.to = Range("S6").Value
.CC = Range("S3").Value
If Range("T3").Value = "Enter bcc addresses manually here" Then
.bcc = ""
Else
.bcc = Range("T3").Value
End If
.Subject = Range("V6").Value
.Body = Range("U6").Value
.Attachments.Add Dest.FullName
'You can add other files also like this
'.Attachments.Add ("C:\test.txt")
If AutoPrint = "Yes" Then
.Send 'or use .Display
Else
.Display
End If
End With
On Error GoTo 0
.Close savechanges:=False
End With
Kill TempFilePath & TempFileName & FileExtStr
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
【问题讨论】:
这里的“最佳”方法是将创建新文件的代码从提供的范围提取到一个单独的方法中,因此如果需要,您可以多次调用它。如果将该方法设为函数,它可以返回临时文件的完整路径。 【参考方案1】:根据我上面的评论:
Private Sub CommandButton2_Click()
Dim OutApp As Object, AutoPrint
Dim colAttachments As New Collection, fPath As String, ws As Worksheet, tm, p
Set ws = ActiveSheet
tm = Format(Now, "dd-mmm-yy h-mm-ss")
'first attachment
fPath = CreateAttachment(ws.Range("A1:M47"), _
"Selection1 of " & ws.Parent.Name & " " & tm)
If Len(fPath) = 0 Then Exit Sub 'exit if there was a problem
colAttachments.Add fPath
If ws.Range("AC6") <> "" Then 'second attachment? Note the filename needs to be distinct...
fPath = CreateAttachment(ws.Range("AB1:AN47"), _
"Selection2 of " & ws.Parent.Name & " " & tm)
If Len(fPath) = 0 Then Exit Sub 'exit if there was a problem
colAttachments.Add fPath
End If
Set OutApp = CreateObject("Outlook.Application")
AutoPrint = ws.Range("Y6").Value
With OutApp.CreateItem(0)
.to = ws.Range("S6").Value
.CC = ws.Range("S3").Value
If ws.Range("T3").Value = "Enter bcc addresses manually here" Then
.bcc = ""
Else
.bcc = ws.Range("T3").Value
End If
.Subject = ws.Range("V6").Value
.Body = ws.Range("U6").Value
For Each p In colAttachments 'add each attachment from the collection
.Attachments.Add p
Kill p
Next p
If AutoPrint = "Yes" Then
.Send
Else
.Display
End If
End With
End Sub
'create a file from the visible cells in `rng`
' and return the path to the file
Function CreateAttachment(rng As Range, fName As String) As String
Dim rngVis As Range, ws As Worksheet, ext, fPath As String
'try to get a range with only visible cells
On Error Resume Next
Set rngVis = rng.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If rngVis Is Nothing Then
MsgBox "The source is not a range or the sheet is protected. " & _
"Please correct and try again.", vbExclamation + vbOKOnly
Else
Application.ScreenUpdating = False
Set ws = Workbooks.Add(xlWBATWorksheet).Sheets(1)
rngVis.Copy
With ws.Cells(1)
.PasteSpecial Paste:=xlPasteColumnWidths '8
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
.Select
End With
Application.CutCopyMode = False
ext = IIf(Val(Application.Version) < 12, ".xls", ".xlsx")
fPath = Environ$("temp") & "\" & fName & ext
ws.Parent.SaveAs fPath
ws.Parent.Close False
CreateAttachment = fPath
End If
End Function
【讨论】:
非常感谢您在回答中提供如此详细的信息。真正基本的问题:我试图将此代码附加到 ActiveX 按钮,并且代码似乎在函数开始时翻倒了。我是否认为该按钮仅识别 Private Sub/End Sub 代码,并且我需要以某种方式将 Function 组合到其中?在这一点上,我无法判断代码是否工作...... 函数是从CommandButton2_Click
调用的,所以你的按钮只需要调用那个Sub
仅供参考,“跌倒”不是很具有描述性 - 如果您遇到代码问题,它总是有助于准确描述正在发生的事情。如果出现错误,错误消息是什么?如果单击“调试”,则会突出显示哪一行?
如果我运行调试,临时文件名会创建得很好,然后我会收到运行时错误“-2147417856 (80010100)”:自动化错误系统调用失败。当我收到此错误时,我没有看到突出显示的行。这在某种程度上与定义了三个单独的命令按钮这一事实有关吗?
我只创建一个附件的原始代码位于 CommandButton2 上,我将您的代码(进行了一些非常简单的更改)放在了 CommandButton3 上。以上是关于从 VB 代码通过电子邮件将多个范围作为附件发送的主要内容,如果未能解决你的问题,请参考以下文章
我可以通过自动电子邮件从 Google 表单/Google 表格发送多个上传的附件吗?
vbscript [.net] [vb]从内存流发送包含附件的电子邮件