vba Excel.Application Object .Quit 使 EXCEL.EXE 运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42113082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 12:04:18  来源:igfitidea点击:

Excel.Application Object .Quit leaves EXCEL.EXE running

excelvbaexcel-vbams-accessaccess-vba

提问by Cinetyk

I'm working within MS Access 2013 on Windows 10 and I'm simply trying to write a Sub that opens an Excel file on disk, changes the column formatting and some columns, saves and quits. The Sub runs and does as intended, but the problem is that even after the .Quit command, "EXCEL.EXE" keeps running and subsequent calls to that Sub will result in run-time errors. If I close Access after running the sub, "EXCEL.EXE" disappears on the Task Manager, but not if I do "Compact and Repair" the database.

我在 Windows 10 上的 MS Access 2013 中工作,我只是想编写一个 Sub 来打开磁盘上的 Excel 文件,更改列格式和一些列,保存并退出。Sub 运行并按预期执行,但问题是即使在 .Quit 命令之后,“EXCEL.EXE”也会继续运行,随后对该 Sub 的调用将导致运行时错误。如果我在运行子程序后关闭 Access,任务管理器上的“EXCEL.EXE”会消失,但如果我执行“压缩和修复”数据库,则不会。

I've done one other Sub that simply opens an Excel file on disk and alters te width of all columns to "auto-width", then closes, which works fine and doesn't leave "EXCEL.EXE" running.

我已经完成了另一个 Sub ,它只是在磁盘上打开一个 Excel 文件并将所有列的宽度更改为“自动宽度”,然后关闭,这工作正常并且不会让“EXCEL.EXE”运行。

What am I doing wrong? Is it possible in VBA to make sure that "EXCEL.EXE" correctly quits?

我究竟做错了什么?是否可以在 VBA 中确保“EXCEL.EXE”正确退出?

I tried a lot of different line order on Dims and Sets to Nothing, Workbook Closes, etc etc. Also, I searched here and on other sites on how to solve this, but after 2h the only suggestions I've seen for VBA is using something like ThisWorkbook.Saved = True, but I tried that before and after .Quit to no effect. Other than that, I only find solutions for VB.NET or other environments that I'm not using and now next to nothing of.

我在 Dims 和 Sets to Nothing、Workbook Closes 等上尝试了很多不同的行顺序。 另外,我在这里和其他网站上搜索了如何解决这个问题,但 2 小时后,我看到的 VBA 的唯一建议是使用ThisWorkbook.Saved = True 之类的东西,但我在 .Quit 之前和之后都尝试过,但没有效果。除此之外,我只找到 VB.NET 或其他我不使用的环境的解决方案,现在几乎没有。

Thanks for reading this.

感谢您阅读本文。

Code follows:

代码如下:

Sub changeXLcolumnFormatting()

Dim XL As Object
Set XL = CreateObject("Excel.Application")
XL.Visible = False
XL.DisplayAlerts = False
XL.Workbooks.Open "C:\Users0344\Desktop\rawDataTest.XLSX"
Dim sht As Worksheet

With XL
Set sht = ActiveWorkbook.Worksheets(1)

Dim rng As Range
Dim i As Integer, j As Integer

field_names = Split("datasistema|Data de Registo|Data Registo CMVM", "|")
sht.Select
end_of_table = sht.UsedRange.Columns.Count

For j = 0 To UBound(field_names)
    For i = 1 To end_of_table
        Set rng = sht.Cells(1, i)
        If InStr(rng.Text, field_names(j)) > 0 Then
            sht.Columns(i).NumberFormat = "yyyy-mm-dd  HH:MM:ss"
        End If
    Next i
Next j

End With

Set rng = Nothing
Set sht = Nothing
XL.ActiveWorkbook.Close (True)

XL.Quit
Set XL = Nothing

End Sub

采纳答案by Gustav

Declare and use a specific Workbookobject - as you do for Worksheetand Range, like this:

声明并使用特定的Workbook对象 - 就像对WorksheetRange所做的那样,如下所示:

    Dim xls ? ? As Excel.Application
? ? Dim wkb ? ? As Excel.Workbook
? ? Dim wks ? ? As Excel.Worksheet
    Dim rng     As Range
? ? 
? ? Set xls = New Excel.Application
? ? Set wkb = xls.Workbooks.Open("c:\test\workbook1.xlsx")
? ? Set wks = wkb.Worksheets(1)
    Set rng = wks.Range(<something>)
? ? 
    ' Do stuff.
? ? wks.Name = "My New Name"
    With rng
         ' Do more.
    End With

? ? wkb.Close True
? ? 
    Set rng = Nothing
? ? Set wks = Nothing
? ? Set wkb = Nothing
? ? 
? ? xls.Quit
? ? 
? ? Set xls = Nothing

Also, don't use Select, that's for visible use only. Define ranges instead.

另外,不要使用 Select,它仅用于可见用途。而是定义范围。



Cinetyk's EDIT:

Cinetyk 的编辑:

Using @Gustav 's indications, the code that does what I wanted and solves the problem is:

使用@Gustav 的指示,执行我想要的并解决问题的代码是:

Sub changeXLcolumnFormatting()

Dim XL As Excel.Application
Dim sht As Excel.Worksheet
Dim wkb As Excel.Workbook
Dim rng As Range

Set XL = New Excel.Application
XL.Visible = False
XL.DisplayAlerts = False

Set wkb = XL.Workbooks.Open("C:\Users0344\Desktop\rawDataTest.XLSX")
Set sht = wkb.Worksheets(1)

Dim i As Integer, j As Integer

field_names = Split("datasistema|Data de Registo|Data Registo CMVM", "|")
end_of_table = sht.UsedRange.Columns.Count

For j = 0 To UBound(field_names)
    For i = 1 To end_of_table
        Set rng = sht.Cells(1, i)
        If InStr(rng.Text, field_names(j)) > 0 Then
            sht.Columns(i).NumberFormat = "yyyy-mm-dd  HH:MM:ss"
        End If
    Next i
Next j

wkb.Close (True)
Set rng = Nothing
Set sht = Nothing

XL.Quit
Set XL = Nothing

End Sub

回答by Vityata

Here is a fancy way to solve that problem - using with new Excel.Application:

这是解决该问题的一种奇特方法 - 使用with new Excel.Application

Option Compare Database
Option Explicit

Public Sub TestMe()

    Dim wkb     As Object
    Dim wks     As Object

    With New Excel.Application

        Set wkb = .Workbooks.Open("C:\Users\vityata\Desktop\myTest.xlsx")
        Set wks = wkb.Worksheets(1)

        wkb.Close True

        Set wks = Nothing
        Set wkb = Nothing
        .Quit

    End With

End Sub

In C# this is a standard with Using, in VBA very few people use it - I have never seen it production code.

在 C# 中这是一个标准Using,在 VBA 中很少有人使用它 - 我从未见过它生产代码。



Cinetyk's EDIT:

Cinetyk 的编辑:

Using Vityata's indications, the code that works as I intended is:

使用 Vityata 的指示,按我预期工作的代码是:

Option Compare Database
Option Explicit

Public Sub changeXLcolumnFormattingV2()

Dim sht As Object
Dim wkb As Object

With New Excel.Application
    .Visible = False
    .DisplayAlerts = False

    Set wkb = .Workbooks.Open("C:\Users0344\Desktop\rawDataTESTING.XLSX")
    Set wks = wkb.Worksheets(1)

    field_names = Split("datasistema|Data de Registo|Data Registo CMVM", "|")
    end_of_table = wks.UsedRange.Columns.Count

    For j = 0 To UBound(field_names)
        For i = 1 To end_of_table
            Set rng = wks.Cells(1, i)
            If InStr(rng.Text, field_names(j)) > 0 Then
                wks.Columns(i).NumberFormat = "yyyy-mm-dd  HH:MM:ss"
            End If
        Next i
    Next j

    wkb.Close True

    Set wks = Nothing
    Set wkb = Nothing
    .Quit

End With

End Sub