连续循环的 VBScript 需要对错误更健壮
Continuously looping VBScript needs to be more robust to errors
我正在编写一个程序来打开服务器上的 运行 多个 VBA 模块,以将新数据上传到云端。我需要至少每 5 分钟(最好每 2 分钟)运行 模块,而不要长时间 24/7 停止。到目前为止,我的代码可以运行 1000-4000 个循环,但每 1-4 天就会失败一次。如何让我的程序更健壮?
我是 VBScript 的新手,但是从我通过研究发现的其他示例中拼凑了一些运行良好的代码。我添加了一些错误处理(On Error Resume Next 和每次主要操作后的错误检查),但仍然偶尔会出现错误并停止程序。
我看到的错误包括 "unknown VBA runtime error," 权限错误(打开本地日志时)和服务器错误。我试图通过 ping 和错误处理来减轻或忽略这些问题,但有些人仍然设法阻止代码循环。
我也尝试过使用 Windows 任务计划程序,但最多只能每 5 分钟执行一次,我无法可靠地达到 运行。
On Error Resume Next
Set WshShell = CreateObject("WScript.Shell")
Dim objFSO
Dim myLog
Dim myLocalLog
Dim pingResultV
Dim pingResultN
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objExcel = CreateObject("Excel.Application")
objExcel.DisplayAlerts = False
objExcel.Visible = True
Set myLog = objFSO.OpenTextFile("location of log on server", 8)
Set myLocalLog = objFSO.OpenTextFile("location of log on local hard drive", 8)
Dim i
i = 0
Do While i < 1000000
'Ping the server to check if the connection is open
PINGFlagV = Not CBool(WshShell.run("ping -n 1 server",0,True))
pingResultV = "Null"
'if the ping was successful, open each file in sequence and run the VBA modules
If PINGFlagV = True Then
timeStamp = Now()
Set Wb = objExcel.WorkBooks.Open("excel file on server",,True)
objExcel.Application.Run "VBA module to copy data to cloud"
objExcel.Application.Quit
If Err.Number <> 0 Then
myLocalLog.WriteLine(timeStamp & " Error in running VBA Script: " & Err.Description)
Err.Clear
End If
Set Wb2 = objExcel.WorkBooks.Open("second excel file on server",,True)
objExcel.Application.Run "VBA module to copy this data to cloud"
objExcel.Application.Quit
If Err.Number <> 0 Then
myLocalLog.WriteLine(timeStamp & " Error in running VBA Script 2: " & Err.Description)
Err.Clear
End If
'Write to the server log that it succeeded or failed
pingResultV = "Server Ping Success"
myLog.WriteLine(timeStamp & " i=" & i & " --- " & pingResultV)
Else
pingResultV = "Server Ping Failed"
timeStamp = Now()
End If
'Write to a local log whether the server was available or not
myLocalLog.WriteLine(timeStamp & " i=" & i & " --- " & pingResultV)
If Err.Number <> 0 Then
myLog.WriteLine(timeStamp & " Error in writing to local log: " & Err.Description)
Err.Clear
End If
'Time between iterations in milliseconds. 120000 ms = 2 minutes
WScript.Sleep(30000)
i = i + 1
Loop
我并不是要请人修改我的代码,但我将不胜感激任何改进建议。如果 VBScript 以外的方法更健壮,我也愿意使用它们。
系统的一些其他背景知识可能会有所帮助:我有 2 台计算机每隔几分钟就会将数据上传到服务器,但出于安全原因,这些计算机无法连接到互联网。我需要每隔几分钟将这些计算机生成的数据上传到互联网数据库,以便可以远程访问。我在连接到服务器和互联网的单独计算机上编写的代码 运行s,它会定期以只读模式打开服务器上的 excel 文件,并且 运行s a VBA 上传新数据线到云端的脚本。
很难判断是您的 VBScript 还是 VBA 模块或两者都失败了。从您的错误描述来看,我有点希望是后者。因此,我还建议(再次)检查您的 VBA 尾声。至于这个脚本,我建议摆脱权限/日志文件错误的一件事是将日志记录移动到它自己的方法,例如
' *** VBScript (FSO) ***
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
' Log file
Const LOG_FILE = "C:\MyData\MyLog.txt"
Sub WriteLog (ByVal sLogFile, ByVal sText)
Dim oFso
Dim oLogFile
Set oFso = CreateObject("Scripting.FileSystemObject")
Set oLogFile = oFso.OpenTextFile(sLogFile, ForAppending, True)
' Prefix log message with current date/time
sText = Now & " " & sText
oLogFile.WriteLine sText
oLogFile.Close
' Free resources
Set oLogFile = Nothing
Set oFso = Nothing
End Sub
然后这样称呼它
If Err.Number <> 0 Then
WriteLog LOG_FILE, "Error in writing to local log: " & CStr(Err.Number) & ", " & Err.Description
Err.Clear
End If
我还建议在循环结束时释放所有资源,例如Excel 对象,为此您需要将对象创建移动到循环中:
Dim i
i = 0
Do While i < 1000000
' Start of loop
Set objExcel = CreateObject("Excel.Application")
objExcel.DisplayAlerts = False
objExcel.Visible = True
' Do your stuff ...
' End of Loop -> free resources
Set Wb = Nothing
Set Wb2 = Nothing
objExcel.WorkBooks.Close
Set objExcel = Nothing
' Time between iterations in milliseconds. 120000 ms = 2 minutes
WScript.Sleep(30000)
i = i + 1
Loop
由于我不是 Excel 专家,我想知道 objExcel.Visible = True
在这里是否有意义,或者是否最好设置为 False
?
我正在编写一个程序来打开服务器上的 运行 多个 VBA 模块,以将新数据上传到云端。我需要至少每 5 分钟(最好每 2 分钟)运行 模块,而不要长时间 24/7 停止。到目前为止,我的代码可以运行 1000-4000 个循环,但每 1-4 天就会失败一次。如何让我的程序更健壮?
我是 VBScript 的新手,但是从我通过研究发现的其他示例中拼凑了一些运行良好的代码。我添加了一些错误处理(On Error Resume Next 和每次主要操作后的错误检查),但仍然偶尔会出现错误并停止程序。
我看到的错误包括 "unknown VBA runtime error," 权限错误(打开本地日志时)和服务器错误。我试图通过 ping 和错误处理来减轻或忽略这些问题,但有些人仍然设法阻止代码循环。
我也尝试过使用 Windows 任务计划程序,但最多只能每 5 分钟执行一次,我无法可靠地达到 运行。
On Error Resume Next
Set WshShell = CreateObject("WScript.Shell")
Dim objFSO
Dim myLog
Dim myLocalLog
Dim pingResultV
Dim pingResultN
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objExcel = CreateObject("Excel.Application")
objExcel.DisplayAlerts = False
objExcel.Visible = True
Set myLog = objFSO.OpenTextFile("location of log on server", 8)
Set myLocalLog = objFSO.OpenTextFile("location of log on local hard drive", 8)
Dim i
i = 0
Do While i < 1000000
'Ping the server to check if the connection is open
PINGFlagV = Not CBool(WshShell.run("ping -n 1 server",0,True))
pingResultV = "Null"
'if the ping was successful, open each file in sequence and run the VBA modules
If PINGFlagV = True Then
timeStamp = Now()
Set Wb = objExcel.WorkBooks.Open("excel file on server",,True)
objExcel.Application.Run "VBA module to copy data to cloud"
objExcel.Application.Quit
If Err.Number <> 0 Then
myLocalLog.WriteLine(timeStamp & " Error in running VBA Script: " & Err.Description)
Err.Clear
End If
Set Wb2 = objExcel.WorkBooks.Open("second excel file on server",,True)
objExcel.Application.Run "VBA module to copy this data to cloud"
objExcel.Application.Quit
If Err.Number <> 0 Then
myLocalLog.WriteLine(timeStamp & " Error in running VBA Script 2: " & Err.Description)
Err.Clear
End If
'Write to the server log that it succeeded or failed
pingResultV = "Server Ping Success"
myLog.WriteLine(timeStamp & " i=" & i & " --- " & pingResultV)
Else
pingResultV = "Server Ping Failed"
timeStamp = Now()
End If
'Write to a local log whether the server was available or not
myLocalLog.WriteLine(timeStamp & " i=" & i & " --- " & pingResultV)
If Err.Number <> 0 Then
myLog.WriteLine(timeStamp & " Error in writing to local log: " & Err.Description)
Err.Clear
End If
'Time between iterations in milliseconds. 120000 ms = 2 minutes
WScript.Sleep(30000)
i = i + 1
Loop
我并不是要请人修改我的代码,但我将不胜感激任何改进建议。如果 VBScript 以外的方法更健壮,我也愿意使用它们。
系统的一些其他背景知识可能会有所帮助:我有 2 台计算机每隔几分钟就会将数据上传到服务器,但出于安全原因,这些计算机无法连接到互联网。我需要每隔几分钟将这些计算机生成的数据上传到互联网数据库,以便可以远程访问。我在连接到服务器和互联网的单独计算机上编写的代码 运行s,它会定期以只读模式打开服务器上的 excel 文件,并且 运行s a VBA 上传新数据线到云端的脚本。
很难判断是您的 VBScript 还是 VBA 模块或两者都失败了。从您的错误描述来看,我有点希望是后者。因此,我还建议(再次)检查您的 VBA 尾声。至于这个脚本,我建议摆脱权限/日志文件错误的一件事是将日志记录移动到它自己的方法,例如
' *** VBScript (FSO) ***
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
' Log file
Const LOG_FILE = "C:\MyData\MyLog.txt"
Sub WriteLog (ByVal sLogFile, ByVal sText)
Dim oFso
Dim oLogFile
Set oFso = CreateObject("Scripting.FileSystemObject")
Set oLogFile = oFso.OpenTextFile(sLogFile, ForAppending, True)
' Prefix log message with current date/time
sText = Now & " " & sText
oLogFile.WriteLine sText
oLogFile.Close
' Free resources
Set oLogFile = Nothing
Set oFso = Nothing
End Sub
然后这样称呼它
If Err.Number <> 0 Then
WriteLog LOG_FILE, "Error in writing to local log: " & CStr(Err.Number) & ", " & Err.Description
Err.Clear
End If
我还建议在循环结束时释放所有资源,例如Excel 对象,为此您需要将对象创建移动到循环中:
Dim i
i = 0
Do While i < 1000000
' Start of loop
Set objExcel = CreateObject("Excel.Application")
objExcel.DisplayAlerts = False
objExcel.Visible = True
' Do your stuff ...
' End of Loop -> free resources
Set Wb = Nothing
Set Wb2 = Nothing
objExcel.WorkBooks.Close
Set objExcel = Nothing
' Time between iterations in milliseconds. 120000 ms = 2 minutes
WScript.Sleep(30000)
i = i + 1
Loop
由于我不是 Excel 专家,我想知道 objExcel.Visible = True
在这里是否有意义,或者是否最好设置为 False
?