Excel VBA Outlook/Mail函数需要重新计算或将所有公式设置为#Value



我会尽量保持简短和精确。我真的希望你能帮助我。

我面临以下问题:

背景:

  • 包含大量公式的工作簿->计算设置为手动
  • 每次重新计算需要5-10分钟

我想做的事:

  • 为多个人单独生成数据范围
  • 然后选择这些范围,并将它们粘贴到电子邮件正文中
  • 一封接一封地发送这些电子邮件

问题出在哪里

  1. 如果我使用"Envelope"方法来准备电子邮件,那么在我按下send之前一切都很好。然而,每次我按下sendexcel时,都会自动重新计算整个工作簿。显然,我不想等待5-10分钟来发送每封电子邮件(总是在10到20之间)

  2. 由于我认为这可能与"信封"方法有关,我决定改用直接通过Outlook(Outlook对象)创建电子邮件。它可以很好地打开电子邮件并在不重新计算的情况下发送。但是,Outlook打开电子邮件后,整个工作簿中的所有(!)公式都设置为#Value。这显然也迫使我重新计算,因为我无法为下一个人的电子邮件创建表。

有人知道是什么导致了重新计算/错误值,以及我能做些什么来阻止它吗?如果有任何建议的解决方案,我会非常高兴。

我还附上了我的代码,尽管我怀疑它是否有助于解决问题


`'描述:'此例程准备一封电子邮件,用于向可交付成果所有者请求进度估计'1.根据PI和Config工作表中的命名范围设置所有值'2.将所有相关字符串连接到完整的电子邮件文本'3.选择PI表'4.创建电子邮件并显示

Sub-PrepareEmail()

Dim s_EmailAddress As String, s_FirstName As String
Dim s_Email_Greeting As String, s_Email_MainText1 As String, s_Email_MainText2 As String, s_Email_DeadlineRequest As String
Dim s_Email_Deadline As String, s_Email_Subject As String, s_Email_ClosingStatement As String, s_Email_SenderName As String, s_Email_CC As String
Dim s_Email_Full As String
Dim rng_PI_TableValues As Range, rng_PI_TableFull As Range
Dim s_Email_FullText As String
Dim obj_OutApp As Object
Dim obj_OutMail As Object

s_EmailAddress = [ptr_PI_Email]
s_FirstName = [ptr_PI_FirstName]
s_Email_Subject = [ptr_Config_PIEmail_Subject]
s_Email_Greeting = [ptr_Config_PIEmail_Greeting]
s_Email_MainText1 = [ptr_Config_PIEmail_MainText1]
s_Email_MainText2 = [ptr_Config_PIEmail_MainText2]
s_Email_DeadlineRequest = [ptr_Config_PIEmail_DeadlineRequest]
s_Email_Deadline = [ptr_Config_PIEmail_Deadline]
s_Email_ClosingStatement = [ptr_Config_PIEmail_ClosingStatement]
s_Email_SenderName = [ptr_Config_PIEmail_SenderName]
s_Email_CC = [ptr_Config_PIEmail_CC]
'Concatenate full e-mail (using HTML):
s_Email_Full = _
    "<basefont face=""Calibri"">" _
    & s_Email_Greeting & " " _
    & s_FirstName & ", " & "<br> <br>" _
    & s_Email_MainText1 & "<br>" _
    & s_Email_MainText2 & "<br> <br>" _
    & "<b>" & s_Email_DeadlineRequest & " " _
    & s_Email_Deadline & "</b>" & "<br> <br>" _
    & s_Email_ClosingStatement & "," & "<br>" _
    & s_Email_SenderName _
    & "<br><br><br>"
'-------------------------------------------------------
Set rng_PI_TableValues = Range("tbl_PI_ProgressInput")
Set rng_PI_TableFull = Union(rng_PI_TableValues, Range("tbl_PI_ProgressInput[#Headers]"))
Application.EnableEvents = False
Application.ScreenUpdating = False
Set obj_OutApp = CreateObject("Outlook.Application")
Set obj_OutMail = obj_OutApp.CreateItem(0)

With obj_OutMail
       .To = s_EmailAddress
       .CC = s_Email_CC
       .Subject = s_Email_Subject
       .HTMLBody = s_Email_Full & RangetoHTML(rng_PI_TableFull)
       .Display
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
Call update_Status

结束子

`

如果您使用的是Ron de Bruin网站上的RangeToHTML,这就是导致问题的原因。如果你需要完美的保真度,并且有一个格式很重但其他方面相当简单的范围,那么这个实用程序很好。但是,如果你的范围有很多依赖项,你就会遇到问题。它将范围放入自己的工作簿中,因此任何引用范围外数据的公式都会变得很奇怪。

如果你需要完美的保真度,那么你就会陷入困境,因为唯一完美的方法就是将范围保存为HTML并读回。但是,如果您没有大量的格式,或者只需要一个好看的表,那么我建议您编写自己的RangeToHTML函数来生成HTML字符串。

David McRitchie有一些功能,如果你不想自己滚动,它们会做得很好。http://dmcritchie.mvps.org/excel/xl2html.htm

此外,我不知道update_Status是做什么的,但如果它导致了recalc,那么你有两个问题。如果是这样的话,那么就想办法存储update_status所做的所有事情,并在最后做一次,而不是在循环中。

最新更新