我已经看到了很多关于这个问题的建议,我已经尝试了所有这些,但似乎都没有.VBA代码位于非Microsoft产品(SAP Business Objects,这可能是问题).我创建了一个Excel对象:
Set oExcel = CreateObject("Excel.Application")
从特定工作簿中的某个工作表的第1列加载内容,然后关闭Excel.每次,它在内存中留下一个进程,占用5+ mb的内存.
我尝试使oExcel对象可见,这样至少我可以在不使用任务管理器的情况下杀死它,但是当我调用Quit时,UI退出,仍然离开了进程.
每次运行代码时,它都会创建一个新进程.所以我尝试通过调用重用任何现有的Excel进程
Set m_oExcel = GetObject(, "Excel.Application")
并且只有在该调用不返回任何内容时才创建它
这并没有扩散这些过程,但单个过程每次增长5+ mb,因此问题基本相同.
在每种情况下,我关闭我打开的工作簿,并在退出之前将DisplayAlerts设置为False:
m_oBook.Close SaveChanges:=False
m_oExcel.DisplayAlerts = False
m_oExcel.Quit
Run Code Online (Sandbox Code Playgroud)
这段代码已经使用了至少五年,但是在我们迁移到Windows 7之前,这个问题并没有出现.
如果它有帮助,这是完整的代码.请注意,所有Excel对象都是每个建议的模块级变量("m_"前缀),并且我已根据另一个建议使用了"一点"规则.我也尝试使用通用对象(即后期绑定),但这也没有解决问题:
Private Function GetVariablesFromXLS(ByVal sFile As String) As Boolean
On Error GoTo SubError
If Dir(sFile) = "" Then
MsgBox "File '" & sFile & "' does not exist. " & _
"The Agent and Account lists have not been updated."
Else
Set m_oExcel = CreateObject("Excel.Application")
Set m_oBooks = m_oExcel.Workbooks
Set m_oBook = m_oBooks.Open(sFile)
ThisDocument.Variables("Agent(s)").Value = DelimitedList("Agents")
ThisDocument.Variables("Account(s)").Value = DelimitedList("Accounts")
End If
GetVariablesFromXLS = True
SubExit:
On Error GoTo ResumeNext
m_oBook.Close SaveChanges:=False
Set m_oBook = Nothing
Set m_oBooks = Nothing
m_oExcel.DisplayAlerts = False
m_oExcel.Quit
Set m_oExcel = Nothing
Exit Function
SubError:
MsgBox Err.Description
GetVariablesFromXLS = False
Resume SubExit
ResumeNext:
MsgBox Err.Description
GetVariablesFromXLS = False
Resume Next
End Function
Run Code Online (Sandbox Code Playgroud)
虽然这种情况不应该发生,但您可以向 Excel 发送“WindowClose”消息以强制关闭。
您将需要这些 API 函数
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Run Code Online (Sandbox Code Playgroud)
它应该看起来像这样:
// First, get the handle
hWindow = FindWindow(vbNullString, "Excel")
//Get proccess ID
GetWindowThreadProcessId(hWindow, ProcessValueID)
//Kill the process
ProcessValue = OpenProcess(PROCESS_ALL_ACCESS, CLng(0), ProcessValueID)
TerminateProcess(ProcessValue, CLng(0))
CloseHandle ProcessValueID
Run Code Online (Sandbox Code Playgroud)