【问题标题】:VBA Send email when cell changes using Worksheet_CalculateVBA 使用 Worksheet_Calculate 在单元格更改时发送电子邮件
【发布时间】:2018-08-31 22:53:02
【问题描述】:

所以我的代码循环遍历一系列单元格并触发一封电子邮件,条件是,在本例中,N150 = F150。这有效,电子邮件已发送。但我发现困难的是在电子邮件正文中引用更改后的单元格。您可以在 xMailBody 变量中看到我尝试过 cll.Offset(0, -12) ,因此当 N150 = F150 时,单元格值为左侧 12 列,应为 B150。相反,我得到的 B145 的值是正确的,因为它是正确的列,但显然是不正确的行。我的目标范围是 N145:N160 所以我认为它只是引用我范围内的第一行。任何帮助将不胜感激,试图解决这个问题好几天!

Dim target As Range
Dim cll As Range

Private Sub Worksheet_Calculate()

    Set target = Range("N145:N160")

    For Each cll In target
        If (Range("N150") = Range("F150"))
            Call Mail_small_Text_Outlook(target)
            Exit For
        End If
    Next
End Sub
Sub Mail_small_Text_Outlook()
    Dim xOutApp As Object
    Dim xOutMail As Object
    Dim xMailBody As String
    Set xOutApp = CreateObject("Outlook.Application")
    Set xOutMail = xOutApp.CreateItem(0)
    xMailBody = "Hi there" & vbNewLine & vbNewLine & _
          cll.Offset(0, -12) & " has reached its target"

    On Error Resume Next
    With xOutMail
        .To = "email"
        .CC = ""
        .BCC = ""
        .Subject = "Target Reached"
        .Body = xMailBody
        .Send   'or use .Display
    End With
    On Error GoTo 0
    Set xOutMail = Nothing
    Set xOutApp = Nothing
End Sub

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    您从 N145:N160 循环,但只检查 Range("N150") = Range("F150")。如果该检查为真,则在第一次迭代时 cll 为 N145 时为真,因此发送电子邮件并退出循环,因此不会处理其他 cll。

    ...
    Set target = Range("N145:N160")
    
    For Each cll In target
        If cll = cll.offset(0, -12) then
            'cll is public, no need to pass it or target across
            Mail_small_Text_Outlook
            Exit For
        End If
    Next   
    ...
    

    【讨论】:

    • 我也尝试过这种方法。我发现范围内第一个满足条件的单元格,例如 N150 = F150,工作正常。参考 B150。但是也可以说 N151 = F151。电子邮件被触发两次,这是正确的,但两次都引用了 B150 而不是 B150 和 B151。换句话说,第一个满足条件的单元格之外的任何单元格都是不正确的。
    • 我认为一旦满足条件,循环就会退出。因此,如果 N150 = F150 发送电子邮件并退出循环。之后的任何单元格都没有被覆盖。
    • 是的,出口就是这样做的。
    【解决方案2】:

    不要使用全局变量,而是将电子邮件中所需的值作为 Mail_small_Text_Outlook 函数的参数传递。

    Dim target As Range
    
    Private Sub Worksheet_Calculate()
        Dim FoundCell as String
        Set target = Range("N145:N160")
    
        For Each cll In target
            If (Range("N150") = Range("F150"))
                FoundCell = Cstr(cll.Offset(0, -12).Value2)
                Call Mail_small_Text_Outlook(FoundCell)
                Exit For
            End If
        Next
    End Sub
    
    Sub Mail_small_Text_Outlook(FoundCell as String)
        Dim xOutApp As Object
        Dim xOutMail As Object
        Dim xMailBody As String
        Set xOutApp = CreateObject("Outlook.Application")
        Set xOutMail = xOutApp.CreateItem(0)
        xMailBody = "Hi there" & vbNewLine & vbNewLine & _
              FoundCell & " has reached its target"
    
        On Error Resume Next
        With xOutMail
            .To = "email"
            .CC = ""
            .BCC = ""
            .Subject = "Target Reached"
            .Body = xMailBody
            .Send   'or use .Display
        End With
        On Error GoTo 0
        Set xOutMail = Nothing
        Set xOutApp = Nothing
    End Sub
    

    现在您可以在将 FoundCell 的值传递给函数之前查看它的值,从而使您的调试过程更加容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      相关资源
      最近更新 更多