2

我有一个适用于活动工作簿的 Excel 的 COM 加载项,虽然它大部分都有效,但我在一个特定的场景中遇到了麻烦。

如果我在 Word 2010 文档中有一个使用插入->图表创建的图表,那么当我单击图表工具->设计->编辑数据时,它会打开包含图表数据的工作簿。我的加载项(大部分)可以与该工作簿一起使用。

但是,我的加载项需要知道保存工作簿的文件夹,在这种情况下,我想使用保存包含文档(Word 文档或 PowerPoint 演示文稿)的文件夹。但是,我找不到获取有关容器文档的任何信息的方法——事实上,我什至找不到方法来判断我正在处理的工作簿是否嵌入在文档中。

是否有任何方法可以让我访问容器文档?

4

2 回答 2

1

让我们再试一次...

然后创建另一个加载项(我将给出一个 XLAM 的示例),或者您可以将您的 COM 加载项修改为此,或确保此新加载项正在运行。此插件将捕获应用程序级App_WorkbookActivate事件,并检查新工作簿名称以查看它是否可能来自 Microsoft Word。

如果工作簿符合这个标准,因为它正在触发事件,那么假设MS Word 中的当前是容器App_WorkbookActivate似乎是相当安全的。ActiveDocument

然后,我们只需设置一些对象变量来捕获Word.Application,然后只需获取ActiveDocument、it's.Path和 it's .Name,我们可以将这些值存储在 Excel 工作簿中的命名变量中。

您可以在Names管理器中查看它们,或通过引用它们的名称以编程方式访问它们,.Names("docPath")并且.Names("docName").

带有容器 .DOC 路径和名称的命名变量

将其放入 XLAM 文件中的标准模块中:

Sub Auto_Open()
    Application.Run "ThisWorkbook.Workbook_Open" 'just in case
End Sub

以下代码位于ThisWorkbookXLAM 文件的模块中:

Option Explicit
Private WithEvents App As Application
Dim dictWorkbooks As Object
Private Sub Workbook_Open()
    '## Instantiate the public variables for this Add-in:
    Set App = Application
    Set dictWorkbooks = CreateObject("Scripting.Dictionary")
End Sub

Private Sub App_WorkbookActivate(ByVal Wb As Workbook)
    '## Attempt to determine if a Workbook is opened from MS Word,
    '   and if so, store the container document's path & name in
    '   named variable/range in the Workbook.
    Dim wdApp As Object
    Dim wdDoc As Object
    Dim docPath As String
    Dim docName As String
    Dim w As Integer

    If Wb.Name Like "Chart in Microsoft Word" Then
        'Get out of here if we already have this workbook activated.
        If dictWorkbooks.Exists(Wb.Name) Then Exit Sub
        Set wdApp = GetObject(, "Word.Application")
        Set wdDoc = wdApp.ActiveDocument
        docPath = wdDoc.Path
        docName = wdDoc.Name
        dictWorkbooks.Add Wb.Name, docName

        With Wb
            On Error Resume Next
            .Names("docPath").Delete
            .Names("docName").Delete
            On Error GoTo 0
            .Names.Add Name:="docPath", RefersToR1C1:=docPath
            .Names("docPath").Comment = "A variable stores the parent DOC file's path"
            .Names.Add Name:="docName", RefersToR1C1:=docName
            .Names("docName").Comment = "A variable stores the parent DOC file's name"
        End With
    End If

End Sub
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
    '## If you open multiple charts from the word document, without closing the Workbook
    ' they will be assigned unique names. However, if you open & close multiple Workbook
    ' they will all have the same name "Chart in Microsoft Word".  This method will
    ' remove an existing Key from our Dictionary when a workbook is closed, in order to
    ' prevent false matches.
    If dictWorkbooks.Exists(Wb.Name) Then _
        dictWorkbooks.Remove Wb.Name
End Sub
于 2013-06-14T16:24:42.663 回答
0

我很确定通过Insert | Chart功能区创建的图表不是链接文档,因此它没有.Path属性。您不需要路径,可以直接访问工作簿和图表对象:

要访问ChartData工作簿/工作表对象,您可以执行以下操作:

Sub OpenChartData(shp as InlineShape)


Dim shp As InlineShape
Dim cht As Chart
Dim wb As ChartData

    If shp.Type = wdInlineShapeChart Then
        Set wb = shp.Chart.ChartData
        Set cht = shp.Chart  '## In case you need to manipulate the Chart options like Title, Axes, etc... you can use this variable.
        wb.Activate  '## Activate the chart's ChartData sheet

        ' do stuff to the worksheet

        wb.Workbook.Application.WindowState = -4140  '## Hide the ChartData when you're finished.
    End If

End Sub

来自评论的更新:

图表数据要么是链接的工作簿,要么不是。如果它不是链接的工作簿,那么它作为具有完整路径的“已保存”文件等不存在于某处。

回答您的问题:

Are there any methods that would give me access to the container document?

ChartData您可以通过对象 访问容器文档。

但是,您不想使用此对象,因为您坚持或错误地理解该工作簿已“保存”在某处,而这仅仅是确定此工作簿保存在何处的问题,以便您的宏/加载项无需任何修改即可工作。

你的假设是不正确的。工作簿没有保存在某个地方,它完全封装在ChartData对象中,该对象是 Microsoft Word 对象模型的一部分。

来自 MSDN

一个新对象 ChartData 已添加到 Word 的 VBA 对象模型中,以提供对图表的基础链接或嵌入数据的访问。每个图表都有与之关联的用于在 Word 中绘制图表的数据。图表数据既可以从外部 Excel 工作簿链接,也可以作为图表本身的一部分嵌入。ChartData 对象封装了对 Word 中给定图表的数据的访问。例如,以下 VBA 代码示例显示并最小化 Word 中活动文档所包含的每个图表的图表数据。

http://msdn.microsoft.com/en-us/library/office/ff821389.aspx

因此,您的选择是:

  1. 重新设计宏以与ChartData对象兼容,或者
  2. 在 Excel 中创建图表并作为 OLEObjects 插入/粘贴到 DOC,而不是使用 Word 的Insert | Chart.
  3. 尝试将以前使用创建的所有图表转换Word Insert | Chart为 OLEObjects。

进一步阅读:

更新图表数据

用 VBA 创建图表

于 2013-06-12T01:19:34.240 回答