Modify embedded Excel workbook in Word document via VBA

后端 未结 3 878
無奈伤痛
無奈伤痛 2020-12-10 06:21

I have a Word document with two embedded Excel files (added using Insert -> Object -> Create From File) which I wish to modify using Word VBA. I have got to the point where

相关标签:
3条回答
  • 2020-12-10 06:56

    Have another hackey way to get the chart to close: Simply use the find function to find something in the document that is not there.

    EG

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

    This will take you out of the embedded file, close the instance and back to the main document, you can just code from there.

    Hope this helps, this problem was driving me crazy.

    0 讨论(0)
  • 2020-12-10 07:15

    I have a solution to my own problem. Any further comments will be appreciated -

    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
    
    0 讨论(0)
  • 2020-12-10 07:16

    Yikes, don't do what you're suggesting in your comment. You'll probably end up with multiple instances of Excel (check Task Manager and see how many there are after executing your code).

    Firstly, add a reference to the Excel object library (Project->References & choose Microsoft Excel Object Library). Now you can declare your objects as bona-fide Excel types and use early binding rather than declaring them as "Object" and using late binding. This isn't strictly necessary, but apart from anything else it means you get Intellisense when editing your code.

    You're doing the right thing right up until you do .OleFormat.Edit. (I would personally use .OleFormat.Activate but since I've never tried using .Edit I couldn't say that it makes a difference).

    Having done .Activate (or, presumably, .Edit), you can then access the OleFormat.Object member. Since the embedded Object is an Excel chart, the "Object" will be the Excel Workbook, so you can do this:

    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
    

    Note that you do NOT need to close Excel, and indeed you cannot - Word "owns" the instance used for an edit-in-place, and will decide when to close it. This is actually something of a problem, since there's no obvious way to force the embedded object to be de-activated, so the chart would stay open after you execute the code above.

    There is a hack-y way to get the chart to close, though. If you add tell Word to activate it as something else, it'll de-activate it first. So, if you tell it to activate it as something non-sensical, you'll achieve the right result because it'll de-activate it and then fail to re-activate it. So, add the following line:

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

    Note that this will raise an error, so you'll need to temporarily disable error handling using On Error Resume Next. For that reason, I normally create a Deactivate method, to avoid disrupting the error handling in my main method. As in:

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

    Hope this helps. Gary

    0 讨论(0)
提交回复
热议问题