我有一个用于Excel的COM加载项,它与活动工作簿一起使用,虽然它主要起作用,但我遇到了一个特定场景的问题。
如果我在使用Insert-> Chart创建的Word 2010文档中有一个图表,那么当我单击Chart Tools-> Design-> Edit Data时,它会打开包含该数据的工作簿。图表。我的加载项可以(主要)使用该工作簿。
但是,我的加载项需要知道保存工作簿的文件夹,在这种情况下,我想使用包含文档的文件夹(Word文档或PowerPoint演示文稿)已保存。但是,我找不到获取有关容器文档的任何信息的方法 - 实际上,我甚至找不到一种方法来告诉我正在处理的工作簿是嵌入到文档中。
是否有任何方法可以让我访问容器文档?
答案 0 :(得分:1)
让我们再试一次......
创建另一个加载项(我将给出一个XLAM的示例),或者你可以修改你的COM加载项,或者确保这个新的加载项正在运行。此添加将捕获应用程序级App_WorkbookActivate
事件,并检查新工作簿名称以查看它是否可能来自Microsoft Word。
如果工作簿符合此条件,因为它触发了App_WorkbookActivate
事件,那么假设MS Word中的当前ActiveDocument
是容器似乎是相当安全的。
然后,我们只设置一些对象变量来捕获Word.Application
,然后只需要获取ActiveDocument
,它是.Path
而它是.Name
,我们可以将这些值存储在Excel工作簿中的命名变量中。
您可以在Names
管理员中查看它们,也可以参考其名称.Names("docPath")
和.Names("docName")
以编程方式访问它们。
将它放在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
所以,你的选择是:
ChartData
对象兼容,或Insert | Chart
。Word Insert | Chart
创建的所有图表转换为OLEObjects。 进一步阅读: