【问题标题】:Emailing Multiple Attachments based on Named Range基于命名范围通过电子邮件发送多个附件
【发布时间】:2018-02-13 05:32:09
【问题描述】:

调试以下代码时遇到问题。

我正在尝试自动化宏以根据命名范围发送多个附件。

Sub Test()

 Dim objol As New Outlook.Application, objMail As MailItem
 Dim MyArr As Variant, i As Long

 Set objol = New Outlook.Application
 Set objMail = objol.CreateItem(olMailItem)

 With objMail
 MyArr = Sheets("Sheet1").Range("A2:A9").Value
 .To = ("test@test.com")
 .Subject = "Test"
 .Body = ""
 .NoAging = True
 For i = LBound(MyArr) To UBound(MyArr)
 If Dir(MyArr(i, 1), vbNormal) <> "" Then .Attachments.Add MyArr(i, 1)
 Next i
 .Display
 End With

 End Sub

在我正在测试的示例中,我在范围内只有两个输入(分别在单元格 A2 和 A3 中的“Sheet2”和“Sheet3”)。似乎代码在i=3 处起作用,该行为空白。但我需要这样才能好。由于它所指的列已设置 (A2:A9),因此用户输入他们想要通过电子邮件在工作簿中找到的工作表的名称。有时用户可以输入 2 个名称或 3 个名称 - 最多为 A9。如果范围中有空白,我只需要代码来结束循环,并发送范围中已经定义的附件。

到目前为止,它一直给我一个类型不匹配的错误? (类型不匹配发生在If Dir(MyArr(i, 1), vbNormal) &lt;&gt; "" Then .Attachments.Add MyArr(i, 1)

编辑 - 由于Dir 也可能是一个问题 - 范围内的值是工作表名称,因此 Sheet1、Sheet2

【问题讨论】:

  • 这里发生了两件事:1) 如果A2:A9 中的值实际上是only 工作表名称Dir 将不起作用,.Attachments.Add 也不会,因为它们都需要一个有效的文件路径名。 2) 例如,要在单元格为空白时退出循环,您可以写If myArr(i,1) = vbNullString。还有其他方法可以做到这一点,包括循环遍历范围本身。数据集太小了,在这种情况下没有真正的区别。
  • 感谢@ScottHoltzman 的回复 - 为什么Attachments.Add 不接受工作表名称?可以这样工作吗:Set rRange = Sheets("Sheet1").Range("A2:A9") For Each rcell In rRange If rcell.Value &lt;&gt; "" Then Sheets(rcell.Value).Copy End If Debug.Print rcell.Value
  • 如果您设置了一个对象,您必须在完成后再次将其设置为 Nothing。

标签: vba excel


【解决方案1】:

这就是你想要的

Sub Mail_ActiveSheet()
    Dim OutApp As Object
    Dim OutMail As Object

    With Application
        .ScreenUpdating = False
        .EnableEvents = False
    End With

    Dim Sourcewb As Workbook
    Set Sourcewb = ActiveWorkbook

    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)

    With OutMail
        .To = "test@test.com"
        .CC = ""
        .BCC = ""
        .Subject = "Test"
        .Body = "Body"

        AddAttachments ActiveWorkbook, OutMail

        .Display
    End With


    Set OutMail = Nothing
    Set OutApp = Nothing

    With Application
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End Sub

下面的子程序将从 A2 循环到 A9,然后将调用 SheetExists() 以查看单元格值是否与现有工作表名称匹配。如果是这样,它会将工作表复制到新工作簿中,将其另存为临时文件夹中的文件,将其附加到电子邮件中,然后删除该文件。

Sub AddAttachments(wb As Workbook, mail As Object)
    'Copy sheets
    For i = 2 To 9
        Dim sheetName As String
        sheetName = wb.Sheets("Sheet1").Range("A" & i).Value

        If SheetExists(sheetName, wb) = True Then
            wb.Sheets(sheetName).Copy

            Dim Destwb As Workbook
            Set Destwb = ActiveWorkbook

            Dim FileExtStr As String
            Dim FileFormatNum As Long

            'Determine the Excel version and file extension/format
            With Destwb
                If Val(Application.Version) < 12 Then
                    'You use Excel 97-2003
                    FileExtStr = ".xls": FileFormatNum = -4143
                Else
                    'You use Excel 2007-2016
                    Select Case wb.FileFormat
                        Case 51: FileExtStr = ".xlsx": FileFormatNum = 51
                        Case 52:
                            If .HasVBProject Then
                                FileExtStr = ".xlsm": FileFormatNum = 52
                            Else
                                FileExtStr = ".xlsx": FileFormatNum = 51
                            End If
                        Case 56: FileExtStr = ".xls": FileFormatNum = 56
                        Case Else: FileExtStr = ".xlsb": FileFormatNum = 50
                    End Select
                End If

                'Save the new workbook/Mail it/Delete it
                Dim TempFilePath As String
                Dim TempFileName As String

                TempFilePath = Environ$("temp") & "\"
                TempFileName = wb.Name & " " & sheetName & " " & Format(Now, "yymmdd h-mm-ss")

                .SaveAs TempFilePath & TempFileName & FileExtStr, FileFormat:=FileFormatNum

                .Close savechanges:=False

                mail.Attachments.Add TempFilePath & TempFileName & FileExtStr

                'Delete the file you have send
                Kill TempFilePath & TempFileName & FileExtStr
            End With
        End If
    Next i
End Sub


 Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
    Dim sht As Worksheet

     If wb Is Nothing Then Set wb = ThisWorkbook
     On Error Resume Next
     Set sht = wb.Sheets(shtName)
     On Error GoTo 0
     SheetExists = Not sht Is Nothing
 End Function

这是一个快速的解决方案。请注意,我没有检查错误,即我没有检查文件是否已创建,或者我没有检查同一张工作表是否被多次列出,这可能会给你带来不希望的结果。

额外的努力取决于你

【讨论】:

  • 似乎我没有在每个循环结束时设置 Destwb = Nothing。为时已晚,我将把这些额外的小修正留给你。
  • 谢谢!欣赏它。我可以进行更正。最后一个问题,请随意指导我 - 如果我有一张将始终与包含用户定义工作表的工作簿一起发送的工作表,例如“Sheet6”。它将始终命名为“Sheet6”并始终在工作簿中,并始终在电子邮件中发送。我可以为此使用 Attachments.Add 吗?或者有什么地方我可以把&amp; "Sheet6" 放在本质上?
  • 要添加像“Sheet6”这样的特定工作表,您需要从AddAttachments() sub 复制一些代码。是的,您需要使用 Attachements.Add,就像 AddAttachements() 对 mail.Attachments.Add TempFilePath &amp; TempFileName &amp; FileExtStr 所做的那样,但首先它将工作表复制到一个新的工作簿中,将其保存在硬盘驱动器(临时文件夹)中的某个位置,然后就可以附加它了带附件。添加。您需要的代码在For 语句中。只需复制代码,确保sheetName = "Sheet6"
  • 我已将代码调整为包含:For i = 2 To 11 Dim sheetName As String sheetName = wb.Sheets("Inputsheets").Range("B" &amp; i).Value sheetName2 = "Sheet6" If SheetExists(sheetName, wb) = True Then wb.Sheets(sheetName).Copy wb.Sheets(sheetName2).Copy 未调整的代码为我提供了两个不同的用户定义工作表名称(sheet1 和 sheet2)的单独附件 - 调整后的代码位于这条评论,如果我点击第二个附件,它将在两个 diff excel 文件中返回 Sheet 6 和 Sheet2。 cnt->
  • 有没有办法在一个工作簿中返回所有 3 个文件,或者让它们保存在 3 个不同的文件中?不知道为什么 sheet6 与第二个附件结合而不是它自己的附件
猜你喜欢
  • 2022-01-02
  • 2021-02-05
  • 2020-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 2015-09-30
相关资源
最近更新 更多