Excel.Application对象.Quit使EXCEL.EXE运行

时间:2017-02-08 12:25:32

标签: excel vba excel-vba ms-access access-vba

我在Windows 10上的MS Access 2013中工作,我只是尝试编写一个Sub,在磁盘上打开Excel文件,更改列格式和一些列,保存和退出。 Sub运行并按预期运行,但问题是即使在.Quit命令之后," EXCEL.EXE"继续运行以及对该Sub的后续调用将导致运行时错误。 如果我在运行sub后关闭Access," EXCEL.EXE"在任务管理器上消失,但如果我这样做则不会消失"紧凑和修复"数据库。

我已经完成了另外一个Sub,它只是在磁盘上打开一个Excel文件,并将所有列的宽度改为"自动宽度"然后关闭,哪个工作正常,并且没有?离开" EXCEL.EXE"运行

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

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

感谢您阅读本文。

代码如下:

Sub changeXLcolumnFormatting()

Dim XL As Object
Set XL = CreateObject("Excel.Application")
XL.Visible = False
XL.DisplayAlerts = False
XL.Workbooks.Open "C:\Users\640344\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

2 个答案:

答案 0 :(得分:0)

声明并使用特定的工作簿对象 - 与工作表范围一样,如下所示:

    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

此外,请勿使用Select,仅供可见的使用。改为定义范围。

Cinetyk的编辑:

使用@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:\Users\640344\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

答案 1 :(得分:0)

这是解决该问题的一种奇特方式 - 使用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

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

Cinetyk的编辑:

使用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:\Users\640344\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