【问题标题】:Close specific Excel file opened by user from Access-VBA关闭用户从 Access-VBA 打开的特定 Excel 文件
【发布时间】:2017-09-07 03:50:31
【问题描述】:

我看到了如何使用

执行此操作的版本
Dim ran as Excel.Applcation 

但我使用的 Access 版本没有 Excel.Application 作为选项。

我编写了以下代码,可以运行,但不会关闭文件

Dim Path1 as String
Dim objXL As Object
Dim xlWB As Object
Path1 = "C:/....."
Set objXL = CreateObject("Excel.Application")
Set xlWB = objXL.Workbooks.Open(Path1)


xlWB.Close False
Set xlWB = Nothing
objXL.Quit
Set objXL = Nothing

【问题讨论】:

  • 您是要关闭已从 Access 中打开的 Excel 应用程序,还是已由用户打开的 Excel 应用程序?
  • 用户打开

标签: excel ms-access vba


【解决方案1】:

您可以使用以下代码关闭所有 Excel 文件(已发布here):

Public Sub CloseAllExcel()
    Dim obj As Object
    On Error GoTo ExitSub
    Dim i As Integer
    'There shouldn't be more than 10000 running Excel applications
    'Can use While True too, but small risk of infinite loop
    For i = 0 To 10000
        Set obj = GetObject(, "Excel.Application")
        obj.Quit
    Next i
ExitSub:
End Sub

但是如果我们要关闭一个特定的,我们需要一些我做不到的 Win32 魔法,但是,如果你不能做某事,你可以在 StackOverflow 上找到它。 Florent B 发现的大部分代码 here

首先,声明我们的 Win32 函数

#If VBA7 Then
  Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hwnd As LongPtr, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long

  Private Declare PtrSafe Function FindWindowExA Lib "user32" ( _
    ByVal hwndParent As LongPtr, ByVal hwndChildAfter As LongPtr, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
#Else
  Private Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long

  Private Declare Function FindWindowExA Lib "user32" ( _
    ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If

然后使用它们来获取所有正在运行的 Excel 应用程序对象

Public Function GetExcelInstances() As Collection
  Dim guid&(0 To 3), acc As Object, hwnd, hwnd2, hwnd3
  guid(0) = &H20400
  guid(1) = &H0
  guid(2) = &HC0
  guid(3) = &H46000000

  Set GetExcelInstances = New Collection
  Do
    hwnd = FindWindowExA(0, hwnd, "XLMAIN", vbNullString)
    If hwnd = 0 Then Exit Do
    hwnd2 = FindWindowExA(hwnd, 0, "XLDESK", vbNullString)
    hwnd3 = FindWindowExA(hwnd2, 0, "EXCEL7", vbNullString)
    If AccessibleObjectFromWindow(hwnd3, &HFFFFFFF0, guid(0), acc) = 0 Then
      GetExcelInstances.Add acc.Application
    End If
  Loop
End Function

然后使用该集合,以便我们可以检查哪个工作簿打开并关闭它

Public Sub closeWorkbook(workbookPath As String)
    Dim excelInstances As Collection
    Set excelInstances = GetExcelInstances
    Dim excelApp As Object
    Dim excelWorkbook As Object
    For Each excelApp In excelInstances
        For Each excelWorkbook In excelApp.Workbooks
            If excelWorkbook.FullName = workbookPath Then
                excelWorkbook.Close False
            End If
        Next excelWorkbook
        If excelApp.Workbooks.Count = 0 Then
            excelApp.Quit
        End If
    Next excelApp
End Sub

然后,实现那个关闭函数

Dim Path1 as String
Path1 = "C:/....."
closeWorkbook Path1

【讨论】:

  • 如果我只想关闭一个特定文件怎么办?
  • 这是一个非常复杂的问题,我怀疑它是否可以正确完成。关闭不是通过 Access 打开的 Excel 应用程序并不容易。
  • 感谢您的帮助,我只是要添加一个消息框,告诉人们如果在流程开始时打开文件就关闭它。
  • 查看当前编辑以关闭一个特定的工作簿(我说它更复杂,不是吗?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
  • 2022-08-16
相关资源
最近更新 更多