Programmatically update an embedded excel file

I am trying to modify an embedded excel table in a text document programmatically. To do this, I modified the docx file and the excel embedded file.

A significant part of the main document is as follows:

<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> 

The document document uses OLEObject to reference the embedded excel document. To display targets, a .wmf file is used (using the v:shape element). I modified an excel document that is deprecated in this preview.

This leads to some weird behavior in the document:

  • An embedded table preview (excel) shows incorrect data
  • Double-clicking on the embedded table opens the table in the embedded excel and shows the correct data.
  • Closing the built-in editor starts generating a new preview, displaying the correct data.

Of course, I want the table to display the correct table when opening the document. How can I make Word discard the image and redraw the preview?

The ideal solution for me would be to initiate the regeneration of the preview by simply changing the contents of the docx document, but solutions using a small script will also help.

+4
source share
2 answers

There is no ideal solution for this, but most of the time it should be used to open / close OLEFormat.Object . It doesnโ€™t matter if you are translating embedded Excel worksheets from outside the Word (i.e., manipulating the Open XML format) or doing it through the object model. It includes opening the embedded Excel spreadsheet from Word and then closing this object to change the image to the current values โ€‹โ€‹in the embedded spreadsheet and creating a new image.

It depends a little if you do this in many Word documents or in just one. In the first case, a global template (for example, normal.dot or a custom one that you create and put in the STARTUP folder) or in a later case, just run the code behind one document. Both have another way to make things work, but essentially you will hook into the Document_Open event and from there check if the current document has OLE Embedded objects, and if so, opening and closing them.

Without going into the hook, as I said, the code is not very good. Mostly because it uses SendKeys . In most cases this will work. For a while it will not be. This is the nature of SendKeys and other programs that receive focus without consent (for example, an instant messaging program).

If Word has focus (this means you cannot open VBE and press F5 ), this code should do the trick:

 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 

At least you can put this code in your normal.dot and assign it a QAT to run as a macro.

Please note that the code does not apply to opening Excel, the values โ€‹โ€‹change and then close, which is an integral part of using built-in objects. Using links instead of nesting would be a smoother way to do all this, but I understand that this is not always an option.

+5
source

Just add an old entry in case someone stumbles upon it like me:

The code above works fine, but I changed it to use bookmarks instead of using SendKeys. The SendKeys statement really works with NumLock on my keyboard. Only one of the quirks of this team.

What I did was bookmark the Word Doc template. Then in my code I created a bookmark pointer:

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

Then, instead of the SendKeys statement, I did the following:

 bMark.Range.Select Selection.EndKey 

This basically pulled focus from the built-in worksheet and into the page tab. Then the .EndKey statement simply deleted the selection. You donโ€™t even need it.

Hope this helps!

+1
source

Source: https://habr.com/ru/post/1344765/


All Articles