如何识别包含嵌入图表的文档?

时间:2013-06-11 21:14:32

标签: vba vsto office-2007 office-2010 office-2013

我有一个用于Excel的COM加载项,它与活动工作簿一起使用,虽然它主要起作用,但我遇到了一个特定场景的问题。

如果我在使用Insert-> Chart创建的Word 2010文档中有一个图表,那么当我单击Chart Tools-> Design-> Edit Data时,它会打开包含该数据的工作簿。图表。我的加载项可以(主要)使用该工作簿。

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

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

2 个答案:

答案 0 :(得分:1)

让我们再试一次......

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

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

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

您可以在Names管理员中查看它们,也可以参考其名称.Names("docPath").Names("docName")以编程方式访问它们。

Named Variable with Container .DOC path & name

将它放在XLAM文件的标准模块中:

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

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

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

答案 1 :(得分: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已添加到VBA对象模型中   Word提供对a的底层链接或嵌入数据的访问   图表。每个图表都与之相关,用于绘制数据   Word中的图表。图表数据可以从外部链接   Excel工作簿,或作为图表本身的一部分嵌入。 ChartData   object封装了对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。
  4. 进一步阅读:

    Update Chart Data

    Creating Charts with VBA