2012-06-25 60 views
2

我正在使用來自的VBA自動化Access 2010使用創建圖表Excel 2010。我的代碼工作正常,但離開了一個孤立的Excel.exe進程運行。我已經將問題追溯到在單獨的模塊中調用Excel VBA函數。如果我取消了對此函數的調用,則在代碼結束時關閉Excel進程。該功能是Chip Pearson的FindAll,並進行了修改以使其在Access中運行,例如將範圍聲明爲Excel.Range並明確將Union方法指定爲Excel.Application.Union。我該如何修改這個函數,以便不會讓孤立的Excel進程運行?Excel.exe在宏完成後保留在內存中

下面的代碼綁定在主過程中的Excel應用程序:

Dim oApp As New excel.Application 
Dim oBook As excel.Workbook 
Dim oSheet As excel.Worksheet 

Set oBook = oApp.Workbooks.Add 
Set oSheet = oBook.Worksheets(1) 

然後,在結束:

oBook.Close False 
oApp.Quit 

Set oSheet = Nothing 
Set oBook = Nothing 
Set oApp = Nothing 

,我使用這行調用的FindAll:

 b = FindAll(oSheet.Range("a2", oSheet.Range("a2").End(xlDown)), strWellID).Rows.Count 

FindAll功能如下:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
' modFindAll 
' By Chip Pearson, [email protected] www.cpearson.com 
' 24-October-2007 
' This module is described at www.cpearson.com/Excel/FindAll.aspx 
' Requires Excel 2000 or later. 
' 
' This module contains two functions, FindAll and FindAllOnWorksheets that are use 
' to find values on a worksheet or multiple worksheets. 
' 
' FindAll searches a range and returns a range containing the cells in which the 
' searched for text was found. If the string was not found, it returns Nothing. 

' FindAllOnWorksheets searches the same range on one or more workshets. It return 
' an array of ranges, each of which is the range on that worksheet in which the 
' value was found. If the value was not found on a worksheet, that worksheet's 
' element in the returned array will be Nothing. 
' 
' In both functions, the parameters that control the search have the same meaning 
' and effect as they do in the Range.Find method. 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 

Function FindAll(SearchRange As Excel.Range, _ 
       FindWhat As Variant, _ 
       Optional LookIn As XlFindLookIn = xlValues, _ 
       Optional LookAt As XlLookAt = xlWhole, _ 
       Optional SearchOrder As XlSearchOrder = xlByRows, _ 
       Optional MatchCase As Boolean = False) As Range 
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
    ' FindAll 
    ' This searches the range specified by SearchRange and returns a Range object 
    ' that contains all the cells in which FindWhat was found. The search parameters to 
    ' this function have the same meaning and effect as they do with the 
    ' Range.Find method. If the value was not found, the function return Nothing. 
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 

    Dim FoundCell As Excel.Range 
    Dim FirstFound As Excel.Range 
    Dim LastCell As Excel.Range 
    Dim ResultRange As Excel.Range 

    With SearchRange 
     Set LastCell = .Cells(.Cells.Count) 
    End With 

    'On Error Resume Next 
    On Error GoTo 0 

    Set FoundCell = SearchRange.Find(What:=FindWhat, _ 
      after:=LastCell, _ 
      LookIn:=LookIn, _ 
      LookAt:=LookAt, _ 
      SearchOrder:=SearchOrder, _ 
      MatchCase:=MatchCase) 

    If Not FoundCell Is Nothing Then 

     Set FirstFound = FoundCell 
     Set ResultRange = FoundCell 
     Set FoundCell = SearchRange.FindNext(after:=FoundCell) 

     Do Until False ' Loop forever. We'll "Exit Do" when necessary. 
      If (FoundCell Is Nothing) Then 
       Exit Do 
      End If 

      If (FoundCell.Address = FirstFound.Address) Then 
       Exit Do 
      End If 

      Set ResultRange = Excel.Application.Union(ResultRange, FoundCell) 
      Set FoundCell = SearchRange.FindNext(after:=FoundCell) 
     Loop 
    End If 

    Set FindAll = ResultRange 

    'added below 

    Set ResultRange = Nothing 
    Set FoundCell = Nothing 
    Set FirstFound = Nothing 
    Set LastCell = Nothing 
    Set SearchRange = Nothing 
End Function 
+0

在將'SearchRange'傳遞給上述函數之前,您如何與Excel應用程序綁定? Excel留下實例的原因是因爲您不是'沖洗廁所';)必須退出Excel應用程序,並在運行上述函數後將其設置爲空。 –

+0

當主要程序結束時,我有以下衝洗廁所。 oBook.Close假 oApp.Quit 設置oSheet =無 設置oBook =無 設置oApp =無 – Jeff

+1

試試這個。用'oApp.Union(ResultRange,FoundCell)'替換'Excel.Application.Union(ResultRange,FoundCell)'並試試它... –

回答

0

Jimmy Pena和Siddharth Rout對於如何幫助移除幻影excel過程提供了極好的評論。

我只想補充一點,雖然我不一定會在所有情況下都推薦它,但如果這是一個持續性問題,並且您在排查故障時正在尋找一個快速「修復」,則可以蠻力逼近在這太問題指出:VBA script to close every instance of Excel except itself

Sub ForceExcelExit() 

Dim BruteForce As String 

BruteForce = "TASKKILL /F /IM excel.exe" 
Shell BruteForce, vbHide 

End Sub 

測試揭示了一個快速的如果不是特別優雅的結束進程。

您還可以使用迭代循環在一個稍微更優雅的方式來結束這樣的過程 - 但仍然使用系統的過程方法,而不是應用程序/應用程序接口中的方法:HOW TO close Excel instance started by mail merge

雖然我不認可其中任一方法作爲通過錯誤檢查,代碼封裝或通用回調,方法使用,變量實例化或其他程序性問題導致實例處於活動狀態的一攬子解決方案,這是在需要修復的情況下的一種修復方法。

相關問題