假设我正在运行.vbs脚本来处理Excel工作表,现在如果出于任何原因由于任何原因发生任何错误,我想退出该.vbs脚本来运行,此外还要从中杀死进程EXCEL.EXE。 vbs file immedaitely。
杀死该进程EXCEL.EXE后,我希望excel表上的脚本所做的所有数据更改都需要 ROLLBACK
有可能吗?
更新:
我有一个代码,但我应该如何将其嵌入我的脚本,我无法理解:
Option Explicit
Dim objService,Process
set objService = getobject("winmgmts:")
for each Process in objService.InstancesOf("Win32_process")
WScript.echo Process.Name & vbTab & Process.processid
Next
SCRIPT
Option Explicit
Set objExcel1 = CreateObject("Excel.Application")'Object for Condition Dump
strPathExcel1 = "D:\VB\Copy of Original Scripts\CopyofGEWingtoWing_latest_dump_21112012.xls"
objExcel1.Workbooks.open strPathExcel1
Set objSheet1 = objExcel1.ActiveWorkbook.Worksheets(1)
Set objSheet2 = objExcel1.ActiveWorkbook.Worksheets("Bad Data")
objExcel1.ScreenUpdating = False
objExcel1.Calculation = -4135 'xlCalculationManual
IntRow2=2
IntRow1=4
Do Until IntRow1 > objSheet1.UsedRange.Rows.Count
ColStart = objExcel1.Application.WorksheetFunction.Match("Parent Business Process ID", objSheet1.Rows(3), 0) + 1
Do Until ColStart > objSheet1.UsedRange.Columns.Count And objSheet1.Cells(IntRow1,ColStart) = ""
If objSheet1.Cells(IntRow1,ColStart + 1) > objSheet1.Cells(IntRow1,ColStart + 5) And objSheet1.Cells(IntRow1,ColStart + 5) <> "" Then
objSheet1.Range(objSheet1.Cells(IntRow1,1),objSheet1.Cells(IntRow1,objSheet1.UsedRange.Columns.Count)).Copy
objSheet2.Range(objSheet2.Cells(IntRow2,1),objSheet2.Cells(IntRow2,objSheet1.UsedRange.Columns.Count)).PasteSpecial
IntRow2=IntRow2+1
Exit Do
End If
ColStart=ColStart+4
Loop
IntRow1=IntRow1+1
Loop
objExcel1.ScreenUpdating = True
objExcel1.Calculation = -4105 'xlCalculationAutomatic
'=======================
objExcel1.ActiveWorkbook.SaveAs strPathExcel1
objExcel1.Workbooks.close
objExcel1.Application.Quit
“======================
TerminateCode
strComputer = "FullComputerName"
strDomain = "DOMAIN"
strUser = InputBox("Enter user name")
strPassword = InputBox("Enter password")
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objSWbemLocator.ConnectServer(strComputer, _
"root\CIMV2", _
strUser, _
strPassword, _
"MS_409", _
"ntlmdomain:" + strDomain)
Set colProcessList = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = 'notepad.exe'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
感谢,
答案 0 :(得分:3)
评论显示,使用WMI杀死中止脚本遗留下来的僵尸Excel.exe是个坏主意。正确的方法是通过在包含您以前的顶级代码的函数周围放置OERN..OEG0来驯服VBScript的可怕错误处理:
Option Explicit
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
Dim goWAN : Set goWAN = WScript.Arguments.Named
Dim goExcel : Set goExcel = Nothing
Dim goWBook : Set goWBook = Nothing
Dim gnRet : gnRet = 1
Dim gaErr : gaErr = Array(0, "", "")
On Error Resume Next
gnRet = Main()
gaErr = Array(Err.Number, Err.Source, Err.Description)
On Error GoTo 0
If 0 = gaErr(0) Then
If goWBook Is Nothing Then
WScript.Echo "surprise: no oWBook, won't save"
Else
WScript.Echo "will save"
goWBook.Save
End If
Else
WScript.Echo Join(gaErr, " - ")
If goWBook Is Nothing Then
WScript.Echo "surprise: no oWBook, won't close"
Else
WScript.Echo "will close False"
goWBook.Close False
End If
End If
If goExcel Is Nothing Then
WScript.Echo "surprise: no oExcel, won't quit"
else
WScript.Echo "will quit"
goExcel.Quit
End If
WScript.Quit gnRet
Function Main()
Main = 1
If goWAN.Exists("alpha") Then Err.Raise vbObjectError + 2, "Main()", "before CO(Excel)"
Set goExcel = CreateObject("Excel.Application")
Set goWBook = goExcel.Workbooks.Open(goFS.GetAbsolutePathName("..\data\savexcel.xls"))
Dim oRngA1 : Set oRngA1 = goWBook.Worksheets(1).Range("$A1")
oRngA1.Value = oRngA1.Value + 1
Dim oRngA2 : Set oRngA2 = goWBook.Worksheets(1).Range("$A2")
If goWAN.Exists("beta") Then
oRngA2.Value = oRngA1.Value / 0
Else
oRngA2.Value = oRngA1.Value / 2
End If
Main = 0
End Function ' Main
输出三次:
cscript savexcel.vbs
will save
will quit
cscript savexcel.vbs /alpha
-2147221502 - Main() - before CO(Excel)
surprise: no oWBook, won't close
surprise: no oExcel, won't quit
cscript savexcel.vbs /beta
11 - Microsoft VBScript runtime error - Division by zero
will close False
will quit
如果您打开任务管理器并不时使用Excel检查工作表,您将看到
有关代码结构/布局/ Main()函数的一些背景信息,请参阅here。
更新 - 解释我对@ oracle答案的投票结果:
option explicit
-- A must
on error resume next
-- Global OERN - a short way to desaster
dim xl: set xl = CreateObject("Excel.Application")
-- Unchecked - script will continue, even if "ActiveX component can't create object"
dim book: set book = xl.WorkBooks.Open("...")
-- Unchecked - script will continue, even if "File not found"
' manipulate book etc
' whenever there is a chance of error, or at the end of the script
' check the err object and clean up if necessary
book.worksheets(1).range("whatever") = interesting computation which fails
if err.Number <> 0 then
SbCleanUp xl
WScript.echo err.Description
err.clear
-- SbCleanUp has quit Excel!
end if
-- now repeat those lines for each action you think of as risky
-- (and forget it for all those actions which really are dangerous)
' update changes, close Excel
book.Save
-- How? SbCleanUp has quit Excel!
-- What about error checking? Forgot it? Can't be bothered?
SbCleanUp xl
-- Why? SbCleanUp has quit Excel!
-- As we have no indication of trouble, let's
-- save the data based on wrong computations
-- in a .txt file and delete the .xls we don't
-- need anymore.
--- **OOOPS**
Sub SbCleanUp(byref xl)
if not (xl Is Nothing) then
dim book
for each book in xl.WorkBooks
book.Saved = true
next 'book
xl.Quit
end if
End Sub
更新II:
我撤销了@ oracle的回答,因为错误处理中的WScript.Quit如果这个错误,阻止将停止脚本。但请注意:所有其他未经检查的错误将保持隐藏状态并且不会中止该程序,每次检查将花费您大约5行样板代码。
答案 1 :(得分:2)
基本上,我使用Excel的方法是在错误处理程序中调用xl.Quit()
。要确保没有更改保存到图书,请事先使用book.Saved = true
。这可以防止Excel抱怨已更改的已打开工作簿
option explicit
on error resume next
dim xl: set xl = CreateObject("Excel.Application")
dim book: set book = xl.WorkBooks.Open("...")
' manipulate book etc
' whenever there is a chance of error, or at the end of the script
' check the err object and clean up if necessary
if err.Number <> 0 then
SbCleanUp xl
WScript.echo err.Description
err.clear
WScript.Quit 1
end if
' update changes, close Excel
book.Save
SbCleanUp xl
Sub SbCleanUp(byref xl)
if not (xl Is Nothing) then
dim book
for each book in xl.WorkBooks
book.Saved = true
next 'book
xl.Quit
end if
End Sub