5

我正在尝试以编程方式修改 Word 文档中的嵌入式 Excel 表格。为此,我修改了 docx 文件和嵌入的 excel 文件。

主要文件的重要部分如下:

<w:object w:dxaOrig="8406" w:dyaOrig="2056">
  <v:shape id="_x0000_i1028" type="#_x0000_t75" 
    style="width:390.75pt;height:95.25pt" o:ole=""><v:imagedata r:id="rId14" 
    o:title=""/>
  </v:shape>
  <o:OLEObject Type="Embed" ProgID="Excel.Sheet.12" ShapeID="_x0000_i1028" 
    DrawAspect="Content" ObjectID="_1349794876" r:id="rId15" 
    UpdateMode="Always"/>
</w:object>

Word 文档使用 OLEObject 链接到嵌入的 excel 文档。出于显示目的,使用 .wmf 文件(使用v:shape元素)。我修改了 excel 文档,该文档已经过时了这个预览。

这会导致文档中出现一些奇怪的行为:

  • 嵌入(excel)表的预览显示错误的数据
  • 双击嵌入的表格会在嵌入的 Excel 中打开表格并显示正确的数据
  • 关闭嵌入式编辑器会触发新预览的生成,显示正确的数据

当然,我希望表格在打开文档时显示正确的表格。如何触发 Word 丢弃图像并重绘预览?

对我来说,一个理想的解决方案是仅通过修改 docx 的内容来触发预览的重新生成,但使用小脚本的解决方案也会有所帮助。

4

2 回答 2

5

对此没有完美的解决方案,但大多数情况下有效的解决方案是强制打开/关闭OLEFormat.Object. 无论您是从 Word 外部重新处理嵌入的 Excel 工作表(即操作 Open XML 格式)还是通过对象模型进行处理,都没有关系。它涉及的是从 Word 中打开嵌入的 Excel 电子表格,然后关闭该对象以将图像更改为嵌入电子表格中的当前值和要创建的新图像。

如果您对许多 Word 文档或仅一个文档执行此操作,这取决于一点。在前一种情况下,全局模板(例如 normal.dot 或您创建并放在 STARTUP 文件夹中的自定义模板)或在后一种情况下,只需在一个文档后面运行代码。两者都有不同的运行方式,但本质上您将挂钩Document_Open事件并从那里检查当前文档是否具有 OLE Embedded 对象,如果有,则打开和关闭它们。

就像我说的那样,如果不进入钩子,代码并不漂亮。基本上是因为它使用SendKeys. 大多数情况下,这会起作用。有时,它不会。这就是SendKeys未经同意而接收焦点的其他程序(例如即时通讯程序)的性质。

如果 Word 具有焦点(这意味着您无法打开 VBE 并按F5),则此代码应该可以解决问题:

Sub UpdateEmbeddedXLSX()
Dim workbook As InlineShape
    For Each workbook In ActiveDocument.InlineShapes
        With workbook
            If .Type = wdInlineShapeEmbeddedOLEObject Then
                ''# Excel.Sheet.12 for Excel 2007
                If .OLEFormat.ClassType = "Excel.Sheet.12" Then
                    ''# Open Object as spreadsheet
                    .OLEFormat.DoVerb wdOLEVerbPrimary
                    ''# If you want, you can also do any updates here like
                    .OLEFormat.Object.ActiveSheet.Cells(2, 2).Value = ".1"
                    ''# Nasty - but it works - SendKeys
                    SendKeys "{ESC}", True
                End If
            End If
        End With
    Next
End Sub

至少,您可以将此代码放在您的 normal.dot 中,并将其分配给 QAT 以作为宏运行。

请注意,代码不会绕过 Excel 打开、值更改然后关闭 - 这是使用嵌入对象的一部分。使用链接而不是嵌入将是一种更顺畅的方式来完成所有这些,但我意识到这并不总是一种选择。

于 2011-03-25T07:03:07.167 回答
1

如果有人像我一样偶然发现这个,只是为了添加到旧帖子中:

上面的代码效果很好,但是我修改它以使用书签而不是使用 SendKeys。SendKeys 语句确实与我键盘上的 NumLock 混淆了。只是该命令的怪癖之一。

我所做的是在我的 Word Doc 模板中创建书签。然后在我的代码中,我创建了一个指向书签的指针:

Dim bMark as bookmark
Set bMark as ActiveDocument.Bookmarks("NameOfBookmark")

然后代替 SendKeys 语句,我做了以下事情:

bMark.Range.Select
Selection.EndKey

这基本上将焦点从嵌入式工作表中拉出,并转移到页面的书签上。然后 .EndKey 语句简单地删除了选择。你甚至不需要它。

希望这可以帮助!

于 2013-05-07T15:12:20.673 回答