【问题标题】:Excel process still running even after .Quit即使在 .Quit 之后,Excel 进程仍在运行
【发布时间】:2018-01-30 09:30:08
【问题描述】:

在我运行 Outlook VBA 宏后,Excel 进程并未停止运行。我怀疑它是由一些 Excel 对象函数引起的,但我真的不确定是哪个。 该问题还通过在我的 Excel 工作簿所在的文件夹中创建多个 .tmp 文件来表现出来。(我认为?) 我将发布我用来打开和关闭 Excel 的代码,以及所有使用 Excel 对象的方法。

Option Explicit
Public xlApp As Object
Public xlWB As Object
Public xlSheet As Object

Sub LeaveRequests()
    Dim enviro As String
    Dim strPath As String
    Dim filePath As String
    Dim bXStarted As Boolean
    Dim i As Long
    Dim j As Long
     'Get Excel set up
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
 filePath = enviro & "\AppData\Roaming\Microsoft\Outlook\path.txt"
 Open filePath For Input As #1
 Do Until EOF(1)
    Line Input #1, strPath
 Loop
 Close #1
     On Error Resume Next
     Set xlApp = GetObject(, "Excel.Application")
     If Err <> 0 Then
         Application.StatusBar = "Please wait while Excel source is opened ... "
         Set xlApp = CreateObject("Excel.Application")
         bXStarted = True
     End If
     On Error GoTo 0
     'Open the workbook to input the data
     Set xlWB = xlApp.Workbooks.Open(enviro & strPath)
     Set xlSheet = xlWB.Sheets("Sheet1")
    ' Process the message record
    On Error Resume Next
    xlWB.Worksheets("Sheet1").Columns("A:NB").entirecolumn.AutoFit
    For j = 2 To 367
        If xlSheet.cells(1, j).Value <> Date And xlSheet.cells(1, j).Interior.ColorIndex = 4 Then
            xlSheet.Columns(j).Interior.ColorIndex = 0
        End If
        If xlSheet.cells(1, j).Value = Date Then
            xlSheet.Columns(j).Interior.ColorIndex = 4
            xlSheet.Columns(j).Select
            If xlSheet.cells(2, j).Value = "Monday" Then
                For i = 2 To j - 1
                xlSheet.Columns(i).Hidden = True
                Next i
            End If
     xlWB.Close SaveChanges:=True
     If bXStarted Then
         xlApp.Quit
     End If
End Sub

这就是Excel的打开和关闭。 我还有一个在 leaverequests 子中的收件箱迭代期间调用的子。

Sub FillIn(ByVal x As String, ByVal y As Date, ByVal z As Date, ByVal id As String)
    Dim currentRow As Long
    Dim i As Long
    Dim j As Long
    Dim date1Pos As Integer
    Dim date2Pos As Integer
    Dim datePos As Integer
    Dim lastRow As Integer
        lastRow = xlSheet.Range("A" & xlSheet.Rows.Count).End(-4162).Row
        date1Pos = 0
        date2Pos = 0
        For i = 3 To lastRow
            If xlSheet.cells(i, 1).Value = id Then
                currentRow = i
                Exit For
            End If
        Next i
            For j = 2 To 367
                If xlSheet.cells(1, j).Value = y Then
                    date1Pos = j
                End If
                If xlSheet.cells(1, j).Value = z Then
                    date2Pos = j
                    Exit For
                End If
            Next j
            If date1Pos <> 0 And date2Pos <> 0 Then
                datePos = date1Pos
                For j = 1 To date2Pos + 1 - date1Pos
                    xlSheet.cells(currentRow, datePos).Value = x
                    xlSheet.cells(currentRow, datePos).HorizontalAlignment = xlCenter
                    datePos = datePos + 1
                Next j
            End If
End Sub

【问题讨论】:

  • For j = 2 To 367 似乎没有匹配的Next
  • 可以,就在If date1Pos &lt;&gt; 0 and date2Pos &lt;&gt; 0 Then上面,我试试缩进代码。
  • 抱歉,我仍然没有在 LeaveRequests 中看到 Next J
  • 我推荐 Smart Indenter oaltd.co.uk/indenter/indentpage.asp ;-)(我与他们无关)

标签: excel vba outlook


【解决方案1】:

您的 Excel 对象变量已在模块级别声明并公开:

Public xlApp As Object

这意味着:它们将无限期地保留对 Excel 的引用,从而防止 Excel 关闭,除非您将它们明确设置为 Nothing

Set xlSheet = Nothing
Set xlWB = Nothing
Set xlApp = Nothing

关闭工作簿/Excel 之后。

使用局部变量被认为是更好的编程实践,并根据需要将它们传递给被调用的函数(例如,从LeaveRequests()FillIn())。

例如:

Sub LeaveRequests()

    Dim xlApp As Object
    Dim xlWB As Object
    Dim xlSheet As Object

    ' stuff, loops, ...
    Call FillIn(xlSheet, x, y, z, id)

End Sub

Sub FillIn(xlSheet As Object, ByVal x As String, ByVal y As Date, ByVal z As Date, ByVal id As String)
    ' as is
End Sub

【讨论】:

  • 这太棒了!使用这些命令终止该进程。您如何建议我将对象作为函数中的变量传递?我不得不将它们声明为公开,因为将它们放在 LeaveRequests() 中会使它们无法使用 FillIn() 进行编写,而且它也使 For i = 3 to lastRow 行为异常,因为它使 i 成为常​​数 3,并且即使它迭代了正确的次数。
【解决方案2】:

你能试试下面的代码吗,这有点矫枉过正,但它对我有用,我把它用作一个函数,但这个代码可以用作 On Error GoTo 或 Sub rou

Dim objWMIService
Dim colProcessList
Dim objProcess
Dim strComputer

strComputer = "." 
Set objWMIService = GetObject("winmgmts://./root/cimv2")  ' Task mgr
Set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process Where Name in ('EXCEL.EXE') ")  '''''','Chrome.exe','iexplore.exe'

For Each objProcess in colProcessList 
    objProcess.Terminate() 
Next

【讨论】:

  • 你建议我在哪里添加这段代码?在 xlWB.Close 之后?
  • 你可以用上面的代码代替xlApp.Quit。例如,您可以创建一个函数并编写此代码,然后调用该函数而不是 xlApp.Quit
  • objProcess.Terminate() 出现语法错误,我删除了括号,但最终结果还是一样,进程没有终止。
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2012-08-20
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
  • 2016-04-10
相关资源
最近更新 更多