简体   繁体   English

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

[英]Access VBA (open excel file and close): turn off "file now available"

I used the following Access VBA code to open four different excel workbooks in a loop while I need to edit the excel data and then update the Access table through recordset.我使用以下 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;"";"

*****Other Codes****** *****其他代码*****

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

However, even though I close the excel file without saving for all the four files, I still receive the following notice after the full loop.但是,即使我在没有保存所有四个文件的情况下关闭了 excel 文件,在完整循环后我仍然收到以下通知。在此处输入图片说明
with Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False) , I was still not able to turn off the notice.使用Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False) ,我仍然无法关闭通知。

PS.附注。 I did not receive the read-write notification for all the four files, normally one or two, which really confused me.我没有收到所有四个文件的读写通知,通常是一两个,这让我很困惑。

Any recommendations for solving the issue?任何解决问题的建议?

Thanks in advance for all the help!在此先感谢所有帮助!

You can't manually control garbage collection in VBA but you can structure your data so that garbage collection is more predictable.您无法在 VBA 中手动控制垃圾收集,但您可以构造数据,以便垃圾收集更可预测。 The first thing I recommend is to place the Excel inter-op code in to it's own procedure that is called from your main loop.我建议的第一件事是将 Excel 互操作代码放入它自己的从主循环调用的过程中。 The reason is that when the procedure ends, the garbage collection will occur.原因是当程序结束时,会发生垃圾收集。 Next time the loop calls the open procedure you will be working with a fresh set of object handles, instead of recycling the objects as you are currently doing.下一次循环调用 open 过程时,您将使用一组新的对象句柄,而不是像当前那样回收对象。 If you do it this way you never have to set your objects to nothing because they are destroyed as they go out of scope at the end of the procedure.如果你这样做,你永远不必将你的对象设置为空,因为它们在过程结束时超出范围时被销毁。 Just be sure to always use local variables.只要确保始终使用局部变量。

In order to do this without closing and opening Excel repetitively you need to get a handle on the currently running Excel instance.为了在不重复关闭和打开 Excel 的情况下执行此操作,您需要获取当前正在运行的 Excel 实例的句柄。 That is provided by the GetExcelApp procedure below.这是由下面的GetExcelApp过程提供的。

EXAMPLE:例子:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM