Excel VBA将多个PDF附加到电子邮件-我的do循环跳过第一个PDF,生成第二个和后续电子邮件?

y4ekin9u  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(171)

我曾尝试编写一个宏来扫描一个文件夹,以挑选属于某个人(如AAA)的相关PDF文件,并将它们附加到一封电子邮件中发送给AAA,然后继续挑选属于BBB的PDF文件,并将它们附加到一封电子邮件中发送给BBB,依此类推。我的包含PDF文件的文件夹如下所示:

  • AAA_111111.pdf
  • AAA_222222.pdf
  • AAA_333333.pdf
  • BBB_111111.pdf
  • BBB_222222.pdf
  • BBB_333333.pdf
  • CCC_777777.pdf
  • CCC_888888.pdf
  • CCC_999999.pdf
  • CCC_444444.pdf

该人员由下划线(姓名首字母缩写)前的字母标识,另一个Excel选项卡上有一个列表,可对照该列表查找姓名首字母缩写以返回其电子邮件地址。
我已经写了下面的代码,它的工作相当不错,除了它有一个恼人的缺陷,我不能解决。它将成功地生成个人AAA的电子邮件,并附上上面列出的所有三个文件。在下一次通过主(外部)“do while”循环将其转到person BBB,但内部“do while mfe=”循环将附加为其列出的第二个和第三个文件(BBB_222222.pdf和BBB_333333.pdf),并完全忽略BBB_111111.pdf(不附加它),尽管它似乎可以看到它。第三个循环也是如此,“do while mfe=”循环将CCC的后三个文件附加到电子邮件中,但不会附加CCC_77777.pdf?!

Sub emailreports()
Dim OutApp As Object
Dim OutMail As Object
Dim OMail As Object, signature, mfe, sto As String
Dim emaillastrow, x, a As Long
Dim fso As Scripting.FileSystemObject
Set fso = New FileSystemObject
Dim folder, strfile As String
Dim rundate As Date

Application.ScreenUpdating = False
Application.Calculation = xlManual
Application.AutoRecover.Enabled = False

folder = Worksheets("START").Range("A14")
strfile = Dir(folder)
rundate = Worksheets("TEMPLATE").Range("E7")
b = Worksheets("START").Range("H25")

Sheets("EMAIL").Select
emaillastrow = Worksheets("EMAIL").Range("A1000000").End(xlUp).Row

If Dir(folder, vbDirectory) = "" Then
MsgBox "PDF destination file path doesn't exist.", vbcritial, "Path error"
Exit Sub
End If

Do While Len(strfile) > 0
        Filename = fso.GetBaseName(folder & strfile)
        mfe = Left(Filename, InStr(Filename, "_") - 1)
        
        For x = 2 To emaillastrow
        If mfe = Worksheets("EMAIL").Range("A" & x) Then
        sto = sto & ";" & Worksheets("EMAIL").Range("B" & x)
        End If
        Next
        
        Set OutApp = CreateObject("Outlook.Application")
        Set OutMail = OutApp.CreateItem(0)
        
        On Error Resume Next
        With OutMail
        .Display
         End With
         With OutMail
        .To = LCase(sto)
        .CC = ""
        .BCC = ""
        .Subject = "Test subject text"
        Do While mfe = Left(Filename, InStr(Filename, "_") - 1)
                .Attachments.Add (folder & Filename)
                Filename = Dir
                If Filename = "" Then
                Exit Do
                End If
        Loop
        .signature.Delete
        .HTMLBody = "<font face=""arial"" style=""font-size:10pt;"">" & "Test email body text" & .HTMLBody
        .Display
        
        End With
        On Error GoTo 0
        
        With Application
        .EnableEvents = True
        .ScreenUpdating = True
        End With
        
        Set OutMail = Nothing
        Set OutApp = Nothing
        Set OutAccount = Nothing
        
Skip:
sto = ""
strfile = Filename

Loop

Application.StatusBar = False
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.AutoRecover.Enabled = True
End Sub

我想尝试在邮件生成的最后退一步,但作为一个循环,这是不可能的。我的代码似乎忽略了PDF,它停止在作为前一个电子邮件生成的一部分,当生成下一个电子邮件开始从该PDF文件,但只拿起并附加后续PDF。任何帮助将感激地接收,因为我已经尝试了各种各样的事情,但不能'这是我在Stackoverflow上的第一篇文章,如果我的问题和/或格式不正确或不合适,请道歉。

ztigrdn8

ztigrdn81#

你可以使用一个dictionary对象,通过目录的一次遍历,按前缀将文件名组合在一起,然后迭代字典键,创建带有相应附件的电子邮件。

Option Explicit

Sub emailreports()
   
    Dim dict As Scripting.Dictionary, key
    Set dict = New Scripting.Dictionary
    
    Dim folder As String, strfile As String, mfe As String
    Dim sTo As String, arPDF, arAddr, f
    Dim ws As Worksheet, r As Long, emaillastrow As Long
    
    folder = Worksheets("START").Range("A14")
    strfile = Dir(folder & "*.pdf")
    If strfile = "" Then
        MsgBox "PDF destination file path doesn't exist.", vbCritical, "Path error " & folder
        Exit Sub
    Else
        ' group files by prefix
        Do While strfile <> ""
            mfe = Left(strfile, InStr(strfile, "_") - 1)
            If dict.Exists(mfe) Then
                dict(mfe) = dict(mfe) & vbTab & strfile
            Else
                dict.Add mfe, strfile
            End If
            strfile = Dir ' get next pdf
        Loop
    End If
    
    Set ws = Worksheets("EMAIL")
    emaillastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row
    
    ' read email address lookup into array
    arAddr = ws.Range("A2:B" & emaillastrow)
    
    ' prepare one email per key
    Dim OutApp As Object, OutMail As Object, OMail As Object
    'Set OutApp = CreateObject("Outlook.Application")
    For Each key In dict.Keys
                
        ' build array of file names for one key
        mfe = Trim(key)
        arPDF = Split(dict(mfe), vbTab)
        
        ' get email addresses
        sTo = ""
        For r = 1 To UBound(arAddr)
            If mfe = arAddr(r, 1) Then
                sTo = sTo & arAddr(r, 2) & ";"
            End If
        Next
        Debug.Print key, sTo
               
        'Set OutMail = OutApp.CreateItem(0)
        'With OutMail
                     
            '.To = LCase(sTo)
            '.cc = ""
            '.BCC = ""
            '.Subject = "Test subject text"
            ' attach pdfs
            For Each f In arPDF
                '.Attachments.Add folder & f
                Debug.Print , folder & f
            Next
            '.signature.Delete
            '.HTMLBody = "<font face=""arial"" style=""font-size:10pt;"">" & "Test email body text" & .HTMLBody
            '.Display
        
        'End With
    Next
    
    'OutApp.quit
End Sub
gxwragnw

gxwragnw2#

On Error Resume Next似乎屏蔽了错误并隐藏了跳过原因。请尝试使用更专用的文件名掩码:

...
folder = Worksheets("START").Range("A14")
If Dir(folder, vbDirectory) = "" Then
    MsgBox "PDF destination file path doesn't exist.", vbcritial, "Path error"
    Exit Sub
End If
strfile = Dir(fso.BuildPath(folder, "*_*.pdf")
rundate = Worksheets("TEMPLATE").Range("E7")
b = Worksheets("START").Range("H25")
'Sheets("EMAIL").Select 'no need to select a sheet
emaillastrow = Worksheets("EMAIL").Range("A1000000").End(xlUp).Row

...

相关问题