【问题标题】:Access VBA (open excel file and close): turn off "file now available"访问 VBA(打开 excel 文件并关闭):关闭“文件现在可用”
【发布时间】:2019-01-25 06:32:53
【问题描述】:

我使用以下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 文件而不保存所有四个文件,在完整循环后我仍然会收到以下通知。
使用Set wb = xl.Workbooks.Open(fileName, ReadOnly = True, editable = True, notify = False),我仍然无法关闭通知。

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

有解决问题的建议吗?

提前感谢所有帮助!

【问题讨论】:

  • 它并没有解决根本问题,但是设置以下是否可以解决提示? Application.DisplayAlerts = False
  • 我仍然收到此通知,如屏幕截图所示,我尝试了所有方法...
  • 也许“文件现在可用”提示是针对 ADO 记录集/连接对象的?也许您可以尝试使用客户端游标,或者如果可能,请尝试在关闭工作簿之前关闭记录集/连接以查看是否有帮助?

标签: excel vba ms-access


【解决方案1】:

您无法在 VBA 中手动控制垃圾回收,但您可以对数据进行结构化,以使垃圾回收更具可预测性。我建议的第一件事是将 Excel 互操作代码放入它自己的过程中,该过程从您的主循环中调用。原因是当程序结束时,会发生垃圾收集。下次循环调用 open 过程时,您将使用一组新的对象句柄,而不是像当前那样回收对象。如果你这样做,你永远不必将你的对象设置为空,因为它们在过程结束时超出范围时被销毁。请务必始终使用局部变量。

为了在不重复关闭和打开 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

【讨论】:

  • 您的代码完美运行!!!感谢您推荐处理大循环的方式。我将在以后的代码中使用这种方法。此外,您的Public Function GetExcelApp() As Object 工作完美。但是,我也尝试了另一个类似的功能,但是当我的循环实际上尝试打开不同的 excel 文件时它不能正常工作,请问原因?抱歉,我对 Access 很陌生。由于字符限制,下一条评论中的代码如下。
  • Public Function GetExcelObject() As Object On Error Resume Next Dim xlo As Object Set xlo = GetObject("Excel.Application") If xlo Is Nothing Then Set xlo = CreateObject("Excel.Application") End If Set GetExcelObject = xlo End Function
  • 我不明白。请提出一个新问题。如果此答案正确,则用绿色复选标记将其标记以关闭此问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多