Обновление встроенного файла Excel программно - PullRequest
4 голосов
/ 22 марта 2011

Я пытаюсь программно изменить встроенную таблицу 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, но решения, использующие небольшой скрипт, также помогли бы.

Ответы [ 2 ]

5 голосов
/ 25 марта 2011

Нет идеального решения для этого, но то, что работает большую часть времени, это принудительно открывать / закрывать OLEFormat.Object. Не имеет значения, будете ли вы повторно обрабатывать встроенный лист Excel из-за пределов Word (т.е. манипулировать форматом Open XML) или делать это через объектную модель. Для этого нужно открыть встроенную электронную таблицу Excel из Word, а затем закрыть этот объект, чтобы изображение сменилось на текущие значения во встроенной электронной таблице и новое изображение, которое будет создано.

Немного зависит, делаете ли вы это со многими документами 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, изменения значений, а затем закрытия - это неотъемлемая часть использования встроенных объектов. Использование связывания вместо встраивания было бы намного более плавным способом сделать все это, но я понимаю, что это не всегда вариант.

1 голос
/ 07 мая 2013

Просто чтобы добавить к старому сообщению, если кто-то наткнется на это, как я:

Приведенный выше код прекрасно работает, но я изменил его, чтобы использовать закладки вместо SendKeys.Оператор SendKeys действительно портит NumLock на моей клавиатуре.Просто одна из причуд этой команды.

Я создал закладки в шаблоне Word Doc.Затем в своем коде я создал указатель на закладку:

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

Затем вместо оператора SendKeys я сделал следующее:

bMark.Range.Select
Selection.EndKey

Это в основном вытащило фокусвстроенного листа и на закладку страницы.Тогда оператор .EndKey просто удалил выделение.Тебе это даже не нужно.

Надеюсь, это поможет!

...