Изменить встроенную книгу Excel в документе Word через VBA - PullRequest
7 голосов
/ 27 января 2009

У меня есть документ Word с двумя встроенными файлами Excel (добавлен с помощью «Вставка» -> «Объект» -> «Создать из файла»), который я хочу изменить с помощью Word VBA. Я дошел до того, что могу открыть встроенные файлы для редактирования (см. Код ниже), но не могу получить ручку в книге Excel, с помощью которой я могу внести изменения и сохранить встроенный файл. У кого-нибудь есть решение для этого? Заранее спасибо.

Sub TestMacro()

    Dim lNumShapes As Long
    Dim lShapeCnt As Long
    Dim xlApp As Object
    Dim wrdActDoc As Document

    Set wrdActDoc = ActiveDocument

    For lShapeCnt = 1 To 1 'wrdActDoc.InlineShapes.Count
        If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
            If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
                'This opens the embedded Excel workbook using Excel
                wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
            End If
        End If
    Next lShapeCnt

End Sub

Ответы [ 3 ]

5 голосов
/ 01 мая 2009

Yikes, не делай того, что ты предлагаешь в своем комментарии. Вы, вероятно, в конечном итоге получите несколько экземпляров Excel (проверьте диспетчер задач и посмотрите, сколько их осталось после выполнения вашего кода).

Сначала добавьте ссылку на библиотеку объектов Excel («Проект» -> «Ссылки» и выберите «Библиотека объектов Microsoft Excel»). Теперь вы можете объявить ваши объекты как настоящие типы Excel и использовать раннее связывание, а не объявлять их как «Объект» и использовать позднее связывание. Это не является строго необходимым, но помимо всего прочего это означает, что вы получаете Intellisense при редактировании кода.

Вы делаете правильные вещи, пока не сделаете .OleFormat.Edit. (Я бы лично использовал .OleFormat.Activate, но так как я никогда не пытался использовать .Edit, я не мог сказать, что это имеет значение).

Сделав .Activate (или, предположительно, .Edit), вы можете получить доступ к члену OleFormat.Object. Поскольку внедренный объект представляет собой диаграмму Excel, «Объект» будет рабочей книгой Excel, поэтому вы можете сделать это:

Dim oOleFormat as OleFormat
Set oOleFormat = ...

oOleFormat.Activate

Dim oWorkbook As Excel.Workbook
Set oWorkbook = oOleFormat.Object

' Do stuff with the workbook
oWorkbook.Charts(1).ChartArea.Font.Bold = True

Обратите внимание, что вам НЕ нужно закрывать Excel, и вы действительно не можете - Word "владеет" экземпляром, используемым для редактирования на месте, и решит, когда его закрывать. На самом деле это является проблемой, поскольку нет очевидного способа принудительно деактивировать встроенный объект, поэтому диаграмма останется открытой после выполнения кода выше.

Однако есть хакерский способ закрыть график. Если вы добавите команду Word, чтобы активировать ее как-то еще, она сначала будет деактивирована. Таким образом, если вы скажете ему активировать его как нечто бессмысленное, вы достигнете правильного результата, потому что он деактивирует его, а затем не сможет повторно активировать. Итак, добавьте следующую строку:

oOleFormat.ActivateAs "This.Class.Does.Not.Exist"

Обратите внимание, что это вызовет ошибку, поэтому вам необходимо временно отключить обработку ошибок, используя On Error Resume Next. По этой причине я обычно создаю метод Deactivate, чтобы избежать нарушения обработки ошибок в моем основном методе. Как в:

Private Sub DeactivateOleObject(ByRef oOleFormat as OleFormat)
    On Error Resume Next
    oOleFormat.ActivateAs "This.Class.Does.Not.Exist"
End Sub

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

2 голосов
/ 08 февраля 2012

Есть еще один хакерский способ закрыть график: просто используйте функцию поиска, чтобы найти в документе что-то, чего нет.

EG

With Selection.Find
    .ClearFormatting
    .Text = "wiffleball"
    .Execute Forward:=True
End With

Это выведет вас из встроенного файла, закроет экземпляр и вернет к основному документу, вы можете просто написать оттуда код.

Надеюсь, это поможет, эта проблема сводила меня с ума.

1 голос
/ 27 января 2009

У меня есть решение моей проблемы. Любые дальнейшие комментарии будут оценены -

Sub TestMacro()

    Dim lNumShapes As Long
    Dim lShapeCnt As Long
    Dim xlApp As Object
    Dim wrdActDoc As Document

    Set wrdActDoc = ActiveDocument

    For lShapeCnt = 1 To 1 'wrdActDoc.InlineShapes.Count
        If wrdActDoc.InlineShapes(lShapeCnt).Type = wdInlineShapeEmbeddedOLEObject Then
            If wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.ProgID = "Excel.Sheet.8" Then
                wrdActDoc.InlineShapes(lShapeCnt).OLEFormat.Edit
                Set xlApp = GetObject(, "Excel.Application")
                xlApp.Workbooks(1).Worksheets(1).Range("A1") = "This is A modified"
                xlApp.Workbooks(1).Save
                xlApp.Workbooks(1).Close
                xlApp.Quit
            End If
        End If
    Next lShapeCnt

End Sub
...