从.vbs文件中杀死Excel.exe

时间:2012-12-17 17:19:34

标签: excel-vba vbscript vba excel

假设我正在运行.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

感谢,

2 个答案:

答案 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检查工作表,您将看到

  1. 不会有Excel.exe僵尸(如果使用调试器,则为execpt)
  2. 如果出现错误,则不会更改.xls
  3. 有关代码结构/布局/ 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