我之前曾以其他帐户名称发布在这里,并感谢所有以前的帮助。
我有一个电子表格,可以从Data Historian中提取信息,以生成有关工厂状态的报告,然后通过Lotus Notes以固定的时间间隔自动将其通过电子邮件发送给收件人。
有时,可能存在影响工厂DCS,Data Historian(Aspen)或Lotus Notes的网络问题。当脚本运行时,这会给出运行时错误。通常,所需要做的只是结束脚本,等待一段时间,重新计算工作表,然后重新运行脚本。
希望有人可以建议添加什么代码来实现这一目标。我真正需要知道的是编写什么代码以及在运行时错误的情况下将其插入到哪里以结束脚本,然后触发另一个可以在其中添加application.wait和application的子例程。在重新运行脚本之前进行计算。我需要脚本结束并运行一个单独的子程序,因为它会导致多个计划的事件出现问题,否则最终会发出多封电子邮件。
我已经标记了脚本中通常会失败的部分。
Sub Macro6()
Windows("Silo report 2 hourly.xlsm").Activate
' Range("A1").Select
'Calculate all workbooks
Application.Calculate
'Set up the objects required for Automation into lotus notes
Dim Maildb As Object 'The mail database
Dim UserName As String 'The current users notes name
Dim MailDbName As String 'THe current users notes mail database name
Dim MailDoc As Object 'The mail document itself
Dim AttachME As Object 'The attachment richtextfile object
Dim Session As Object 'The notes session
Dim EmbedObj As Object 'The embedded object (Attachment)
'Start a session to notes
Set Session = CreateObject("Notes.NotesSession")
'Next line only works with 5.x and above. Replace password with your password
'Get the sessions username and then calculate the mail file name
'You may or may not need this as for MailDBname with some systems you
'can pass an empty string or using above password you can use other mailboxes.
UserName = Session.UserName
MailDbName = Left$(UserName, 1) & Right$(UserName, (Len(UserName) - InStr(1, UserName, " "))) & ".nsf"
'Open the mail database in notes
Set Maildb = Session.GETDATABASE("", MailDbName)
If Maildb.IsOpen = True Then
'Already open for mail
Else
Maildb.OPENMAIL
End If
'Set up the new mail document
Set MailDoc = Maildb.CreateDocument
MailDoc.Form = "Memo"
vaRecipient = VBA.Array("xxx.xxx@xxx.com", "yyy.yyy@yyy.com", "zzz.zzz@zzz.com")
MailDoc.SendTo = vaRecipient
MailDoc.Subject = Range("B1").Value
Set workspace = CreateObject("Notes.NotesUIWorkspace")
'**THE RUNTIME ERROR USUALLY OCCURS WITHIN THE NEXT 5 LINES OF SCRIPT**
Dim notesUIDoc As Object
Set notesUIDoc = workspace.EditDocument(True, MailDoc)
Call notesUIDoc.GOTOFIELD("Body")
Call notesUIDoc.FieldClear("Body")
Call notesUIDoc.FieldAppendText("Body", Range("B9").Value & vbCrLf & vbCrLf & Range("b10").Value & Range("I10").Value & Range("D10").Value & vbCrLf & Range("b11").Value & Range("I11").Value & Range("D11").Value & vbCrLf & Range("b12").Value & Range("I12").Value & Range("D12").Value & vbCrLf & vbCrLf & Range("b13").Value & Range("I13").Value & Range("D13").Value & vbCrLf & vbCrLf & Range("b14").Value & Range("C14").Value & Range("D14").Value & vbCrLf & vbCrLf & Range("b15").Value & Range("I15").Value & Range("D15").Value & vbCrLf)
notesUIDoc.Send
notesUIDoc.Close
MailDoc.PostedDate = Now() 'Gets the mail to appear in the sent items folder
'MailDoc.Send 0, vaRecipient
'Clean Up
Set Maildb = Nothing
Set MailDoc = Nothing
Set AttachME = Nothing
Set Session = Nothing
Set EmbedObj = Nothing
End Sub
最佳答案
在LotusScript以及Visual Basic/VBA中,错误处理的工作原理完全相同。在脚本的开头,您定义了发生错误时的去向:
On Error Goto ErrorHandler
发生错误时,在要重新开始的行上方放置一个跳转标记:
TryAgain:
在子代码的最后,您定义了错误处理程序本身:
EndSub:
'- prohibit that error handler is called without an error
Exit Sub
ErrorHandler:
'- here you can react on the error, e.g. check for the err (Error number)
If err = NumberOfErrorThatOccursWhenNetworkErrorOccurs then
'- wait some time to give the network time to recover
Sleep x '- put in x as best for your problem
'- jump back
Resume TryAgain
Else
'- another error occured: inform user
Messagebox err & ", " & Error & " in line " & Erl
'- now jump to the end of the sub
Resume EndSub
End If
当然,这是最小的错误处理,并且可能您不希望在不做进一步检查的情况下跳来跳去,但是这个示例应该使思路很清楚。
评论中仅提供了另外一件事:您根本不需要UI!只需忽略它,因为它完全不必要,并使您的代码不稳定。
用两行代码替换以
Set workspace...
开头,以notesUIDoc.close
结尾的整个段落:Call Maildoc.ReplaceItemValue( "Body", Range("B9").Value ..... )
Call Maildoc.Send( False )
这样一来,您就不必担心出现问题-当代码再次运行或结束时,文档将被丢弃,并且比处理ui窗口要稳定得多,并且屏幕不会闪烁...
关于email - 错误处理-如果网络中断,则循环生成电子邮件的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29529899/