访问VBA(打开Excel文件并关闭):关闭“文件现已可用”

时间:2019-01-22 20:37:24

标签: excel vba ms-access

我使用以下Access VBA代码在一个循环中打开四个不同的excel工作簿,而我需要编辑excel数据,然后通过记录集更新Access表。

xl.Application.DisplayAlerts = False
Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False)
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Worksheets.Add
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fileName & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;"";"

*****其他代码******

wb.Close savechanges:=False
Set wb = Nothing
Set xlc = Nothing
Set ws = Nothing
Set ws2 = Nothing
Set xl = Nothing
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing

但是,即使我关闭了excel文件却没有保存所有四个文件,在完整循环后,我仍然收到以下通知。 enter image description here
使用Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False),我仍然无法关闭该通知。

PS。我没有收到所有四个文件的读写通知,通常是一两个,这真的让我感到困惑。

有解决问题的建议吗?

提前感谢所有帮助!

1 个答案:

答案 0 :(得分:1)

您不能在VBA中手动控制垃圾收集,但是可以对数据进行结构化,以便更容易预测垃圾收集。我建议的第一件事是将Excel互操作代码放入它自己的过程中,该过程从主循环中调用。原因是当过程结束时,将发生垃圾回收。下次循环调用打开过程时,您将使用一组新的对象句柄,而不是像当前那样回收对象。如果以这种方式进行操作,则无需将对象设置为空,因为在过程结束时对象会超出范围而被破坏。只要确保始终使用局部变量即可。

要执行此操作而不重复关闭和打开Excel,您需要获取当前正在运行的Excel实例的句柄。这由下面的GetExcelApp过程提供。

示例:

Private Sub YourMainLoop()
    For Each fileName in fileNames
        ProcessExcelData fileName
    Next fileName
End Sub

Private Sub ProcessExcelData(ByVal fileName as String)
    Dim xl As Object
    Set xl = GetExcelApp
    xl.Application.DisplayAlerts = False
    Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False)
    Set ws = wb.Sheets("Sheet1")
    Set ws2 = wb.Worksheets.Add
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fileName & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;"";"
    ' Process the data, blah blah blah
    wb.Close savechanges:=False
    rs.Close
    cn.Close
End Sub

Public Function GetExcelApp() As Object
' Returns open excel instance.
'   If it doesn't exist, creates one to return
On Error GoTo ErrHandler
Const ERR_APP_NOTRUNNING As Long = 429    

    Set GetExcelApp = GetObject(, "Excel.Application")

CleanExit:
    Exit Function
ErrHandler:
    If Err.number = ERR_APP_NOTRUNNING Then
        Set GetExcelApp = CreateObject("Excel.Application")
        Resume CleanExit
    Else
        ShowErrorMessageBox
    End If
End Function