使用多个RangeToHTML范围发送电子邮件

时间:2017-03-29 14:43:04

标签: excel vba excel-vba email

我正在使用从Ron de Bruin网站上复制的一些代码(真棒,顺便说一句),并且遇到了麻烦。

生成的电子邮件只会将标题粘贴到completedTasks范围内。

它会将SummaryincompletedTasks范围正确粘贴到电子邮件正文中。

如果我删除了处理incompletedTasks的所有代码,那么它会正确地将SummarycompletedTasks HTML粘贴到电子邮件正文中。

提前感谢您的帮助。

Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
    Dim fso As Object
    Dim ts As Object
    Dim TempFile As String
    Dim TempWB As Workbook

    TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"

    'Copy the range and create a new workbook to past the data in
    rng.Copy
    Set TempWB = Workbooks.Add(1)
    With TempWB.Sheets(1)
        .Cells(1).PasteSpecial Paste:=8
        .Cells(1).PasteSpecial xlPasteValues, , False, False
        .Cells(1).PasteSpecial xlPasteFormats, , False, False
        .Cells(1).Select
        Application.CutCopyMode = False
        On Error Resume Next
        .DrawingObjects.Visible = True
        .DrawingObjects.Delete
        On Error GoTo 0
    End With

    'Publish the sheet to a htm file
    With TempWB.PublishObjects.Add( _
         SourceType:=xlSourceRange, _
         Filename:=TempFile, _
         Sheet:=TempWB.Sheets(1).Name, _
         Source:=TempWB.Sheets(1).UsedRange.Address, _
         HtmlType:=xlHtmlStatic)
        .Publish (True)
    End With

    'Read all data from the htm file into RangetoHTML
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
    RangetoHTML = ts.readall
    ts.Close
    RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
                          "align=left x:publishsource=")

    'Close TempWB
    TempWB.Close savechanges:=False

    'Delete the htm file we used in this function
    Kill TempFile

    Set ts = Nothing
    Set fso = Nothing
    Set TempWB = Nothing
End Function


Sub Monthly_Close_Daily_Report()
'
'

Dim yearMonth As String
Dim closeDay As String
Dim currTime As String
Dim summaryRange As Range
Dim completedTasks As Range
Dim incompleteTasks As Range
Dim emailRng As Range, cl As Range
Dim sTo As String

Application.ScreenUpdating = False
Sheets("Inputs").Select

'Check to make sure there are no errors, then proceed
If Not IsError(Sheets("Inputs").Range("B12")) Then
    If Sheets("Inputs").Range("B12") = "Yes" Then
        'Store the YY-MM as a variable
        Sheets("Inputs").Select
        yearMonth = Range("B4").Value

        'Store the MM/DD/YYYY as a variable
        Sheets("Inputs").Select
        closeDay = Range("B5").Value

        'Store the current time as a variable
        Sheets("Inputs").Select
        currTime = Format(Now(), "h:mmAM/PM")

        'Unfilter the Task Listing tab
        Sheets("Task Listing").Select
        Activesheet.ShowAllData

        'Refresh the table with new Sharepoint data
        ActiveWorkbook.Connections("SharePoint").Refresh

            'Create a new email with the Email Listing tab in the "To" line
            Set OutApp = CreateObject("Outlook.Application")
            Set OutMail = OutApp.CreateItem(0)

            'Determine the email addresses to send to
            Set emailRng = Worksheets("Email Listing").Range("B2:B50")
            For Each cl In emailRng
                sTo = sTo & ";" & cl.Value
            Next
            sTo = Mid(sTo, 2)

            'Set the Summary range to be copied into the email
            Set summaryRange = Sheets("Summary").Range("A1:G11")
            summaryRange.Copy

            'Filter the Task Listing tab for this month's completed tasks & copy to range
            Sheets("Task Listing").Select
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=1, Criteria1:=yearMonth, Operator:=xlFilterValues
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=6, Criteria1 _
                :="Completed"
            Set completedTasks = Application.Intersect(ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible), Range("A:G"))
            'Set completedTasks = Sheets("Task Listing").UsedRange.SpecialCells(xlCellTypeVisible)
            Worksheets("Task Listing").ShowAllData

            'Filter the Task Listing tab for this month's non-completed tasks & copy to range
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=1, Criteria1:=yearMonth, Operator:=xlFilterValues
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=6, Criteria1:="<>Completed"
            Set incompleteTasks = Application.Intersect(ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible), Range("A:G"))

            'On Error Resume Next
            With OutMail
                .To = sTo
                .CC = ""
                .BCC = ""
                .Subject = "Month End Close Status for " & yearMonth & " As Of " & currTime & " on " & closeDay
                .HTMLBody = RangetoHTML(summaryRange) & "<br><br><strong>Completed Tasks" & RangetoHTML(completedTasks) & "<br><br><strong>Incomplete Tasks" & RangetoHTML(incompleteTasks)
                .Display 'Can also use .Send which will send the email.  We want to preview before sending, though.
            End With

            Set OutMail = Nothing
            Set OutApp = Nothing

    Else
        'If tasks are missing Due Dates, flag those for the user and exit the macro
        MsgBox ("There are ""Due Dates"" missing for some tasks.  Please correct the issue and run the macro again.")
    End If

End If

    'Filter the "Task Listing" tab for the current month
    Sheets("Task Listing").Select
    Range("A2").Select
    Selection.AutoFilter
    ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=1, Criteria1:=yearMonth, Operator:=xlFilterValues

'

End Sub

2 个答案:

答案 0 :(得分:0)

您似乎从同一张纸张中拉出两个范围,只有过滤才会显示相同的纸张。

将输入设置为已完成 将输入设置为“不完整”

completed = RangetoHTML(输入)//你正在阅读不完整的内容 incomplete = RangetoHTML(输入)//你再次阅读不完整的内容

相反尝试这个

将输入设置为已完成 htmlBodyBuffer = RangetoHTML(输入)

将输入设为不完整 .HTMLBody = htmlBodyBuffer&amp; RangetoHTML(输入)

答案 1 :(得分:0)

使用@Asaf的建议来解决这个问题,使用&#34;持有&#34;用于组合范围,然后将HTML粘贴到电子邮件的工作表。

class Parser:

    def __init__(self, data):
        self.data = data
        self.pos = 0

    def get_cur_char(self):
        """
        Returns the current character or None if the input is over
        """
        return None if self.pos == len(self.data) else self.data[self.pos]

    def advance(self):
        """
        Moves to the next character of the input if the input is not over.
        """
        if self.pos < len(self.data):
            self.pos += 1

    def get_and_advance(self):
        """
        Returns the current character and moves to the next one.
        """
        res = self.get_cur_char()
        self.advance()
        return res

    def parse_expr(self):
        """
        Parse the EXPR according to the speficied grammar.
        """
        cur_char = self.get_cur_char()
        if cur_char == '(':
            # EXPR -> (LIST) EXPR rule
            self.advance()
            # Parser the list and the rest of the expression and combines
            # the result.
            prefixes = self.parse_list()
            suffices = self.parse_expr()
            return [p + s for p in prefixes for s in suffices]
        elif not cur_char or cur_char == ')' or cur_char == '|':
            # EXPR -> Empty rule. Returns a list with an empty string without
            # consuming the input.
            return ['']
        else:
            # EXPR -> A EXPR rule.
            # Parses the rest of the expression and prepends the current 
            # character.
            self.advance()
            return [cur_char + s for s in self.parse_expr()]

    def parse_list(self):
        """
        Parser the LIST according to the speficied grammar.
        """
        first_expr = self.parse_expr()
        # Uses the LIST -> EXPR | LIST rule if the next character is | and
        # LIST -> EXPR otherwise    
        return first_expr + (self.parse_list() if self.get_and_advance() == '|' else [])


if __name__ == '__main__':
    string = "(A((B|C)D|E|F))"
    parser = Parser(string)
    print('\n'.join(parser.parse_expr()))