从Word VBA编辑打开或关闭的工作簿

问题描述 投票:1回答:1

我正在尝试在Word中编写宏,以便可以将某些信息保存到计算机其他位置的Excel文件中。因此,我写了这个:

Dim exlApp As Object
Dim exlWbk As Object
Set exlApp = CreateObject("Excel.Application")
Set exlWbk = exlApp.Workbooks.Open(FileName:="D:\database.xlsx")
exlWbk.ActiveSheet.Cells(1, 1).Value = "some info"
exlWbk.Close SaveChanges:=True
Set exlWbk = Nothing
exlApp.Quit
Set exlApp = Nothing

该代码对我来说非常正常,除非用户已打开有问题的Excel文件(database.xlsx)。在这种情况下,运行宏将提示我将新更改保存到我的excel文件的新副本中,这不是我想要的。我希望新的更改包含在当前Excel文件中,而不创建第二个副本。

由于上述代码出现了一些问题,所以我这样写:

Dim exlApp As Object
Dim exlWbk As Object
Set exlApp = CreateObject("Excel.Application")
Set exlWbk = exlApp.GetObject("D:\database.xlsx")
exlWbk.ActiveSheet.Cells(1, 1).Value = "some info"
exlWbk.Save
Set exlWbk = Nothing
exlApp.Quit
Set exlApp = Nothing

但是什么都没有改变。我知道有一些方法可以确定我的Excel文件是否打开,但是问题是,如果我发现该文件是打开的,我不知道如何更改代码。

如何确定工作簿是否已在Excel中打开以便可以对其进行编辑,或者如何在关闭时打开文件进行编辑?

excel vba ms-word
1个回答
0
投票

根据documentationGetObject(filename)将选择现有文件(如果已打开);或者,如果没有打开,则选择打开该文件:

执行此代码后,与指定的路径名​​已启动,并且指定文件中的对象为已激活。

如果Excel未运行,默认情况下,执行GetObject(filename)时将看不到任何内容。将打开Excel,将打开并更改文件。因此,存在一个真正的危险,即Excel和工作簿的实例将在内存中“挂起”,这可以在Windows“任务管理器”中看到。重复运行此类代码最终可能会导致Windows崩溃,因此必须注意在每次迭代中正确清理内容。

由于该问题还规定用户可以打开该文件,因此有必要确定该文件以及Excel应用程序是否已在运行。

下面的代码示例演示了如何完成此操作。假定应用程序和文件均未打开。然后,它会测试Excel是否已在运行。

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

注意语法上的区别:逗号[而不是fileName后面是应用程序的名称。这将检查该应用程序是否可用;如果不是,将触发错误。因此,On Error Resume NextGetObject之前,这意味着该错误将被忽略。

由于忽略错误很危险,因此下一行Or Error GoTo 0将错误重新打开。

如果GetObject不成功,则无法实例化变量xlApp,并且其“值”为Nothing。如果可以实例化If Not xlApp Is Nothing并将布尔值xlApp设置为true,则执行appAlreadyOpen,以便在代码完成后我们知道not退出Excel。它还检查所需的工作簿是否已经打开。如果是,则可以实例化xlWb并将fileAlreadyOpened设置为true。

如果由于Excel应用程序未运行或工作簿尚未打开而无法实例化xlWb,则将执行GetObject(fileName)。将在现有的Excel实例(如果已运行)中或在Excel的新实例中打开工作簿。在此代码块的结尾处,注释了两行:如果新启动的Excel应用程序变得可见并在代码结束时保持打开状态,请取消注释它们。

然后可以编辑工作簿。

最后,需要清理东西。检查布尔值,如果不为true,则关闭工作簿和可能的应用程序。 非常重要是从内存中释放这些对象的最后两行。如果代码创建了任何其他对象,例如Range,则也应以实例化它们的相反顺序释放它们。

Sub GetFileOpenedOrClosed()
    Dim xlApp As Object              ' Excel.Application
    Dim xlWB As Object, wb As Object ' Excel.Workbook
    Dim fileName As String
    Dim fileAlreadyOpen As Boolean, appAlreadyOpen As Boolean

    fileName = "C:\Test\SampleChart.xlsx"
    fileAlreadyOpen = False
    appAlreadyOpen = False
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application")
    On Error GoTo 0
    If Not xlApp Is Nothing Then
        appAlreadyOpen = True
        For Each wb In xlApp.Workbooks
            If wb.FullName = fileName Then
                Set xlWB = wb
                fileAlreadyOpen = True
                Exit For
            End If
        Next
    End If
    If xlWB Is Nothing Then
        Set xlWB = GetObject(fileName)
        Set xlApp = xlWB.Application
        xlWB.Windows(1).Visible = True 'So that the window is not hidden when file is opened again
        'xlApp.Visible = True
        'xlApp.UserControl = True
    End If
    xlWB.Worksheets(1).Cells(7, 1).value = "some other info"
    If Not fileAlreadyOpen Then
        xlWB.Save
        xlWB.Close
    End If
    If Not appAlreadyOpen Then
        xlApp.Quit
    End If
    Set xlWB = Nothing
    Set xlApp = Nothing
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.