We insert and link pictures (insert picture from file .emf) in our Word documents (.docx). Our documents and the graphic files are stored on our network drives. We then provide our documents to the authors to be worked on. The pictures in the documents are useful for the authors.
How do I programmatically and globally (document wise, not batch processing documents): Extract the filename (without the file extension) of the pictures linked and inserted?
We have a tool that exports the Word document .docx to .XML.
Ps: I googled for possible/potential VBA solutions. So far, I gather:
- there’s no way one can be sure / check that the pictures have been linked and inserted properly / correctly in a .docx
- there’s no way to view the source code (? at least I tried Alt+ F9 / Shift+F9)
Or is macro/ vba not the way to go?
Specs:
Word 2013.
64 bit
Graphic format. Emf
Graphic and word documents store on a network drive
Graphics not inserted and linked via the INCLUDEPICTURE field.
Graphics formatted with text wrappping fall into the Shapes
collection. These cannot use IncludePicture
to manage the link - they "live" in a different layer of the document than text and field codes. So the only way to access or manage this information is through the object model (VBA, for example), or through the Word Open XML.
The object model provides the LinkFormat
property for the Shape
object to query and manage link information. Among other things, there are properties and methods for breaking the link, getting the file name, the file path and the complete file information.
The following loops all Shape
objects in the main body of the document and tests whether the type is a linked picture. If it is, the full file information is assigned to sSource
.
Sub GetSourceFromLinkedShape()
Dim shp As Word.Shape
Dim sSource As String
For Each shp In ActiveDocument.shapes
If shp.Type = msoLinkedPicture Then
sSource = shp.LinkFormat.SourceFullName
End If
Next
End Sub
To get a listing of floating and inline linked pictures alike, you might use code like:
Sub Demo()
Dim Shp As Shape, iShp As InlineShape, StrOut As String
With ActiveDocument.Range
StrOut = "Linked Shapes:"
For Each Shp In .ShapeRange
With Shp
If .Type = msoLinkedPicture Then
StrOut = StrOut & Chr(11) & Split(.LinkFormat.SourceName, ".")(0)
End If
End With
Next
If InStr(StrOut, Chr(11)) = 0 Then StrOut = StrOut & " None."
.InsertAfter vbCr & StrOut
StrOut = "Linked InlineShapes:"
For Each iShp In .InlineShapes
With iShp
If .Type = wdInlineShapeLinkedPicture Then
StrOut = StrOut & Chr(11) & Split(.LinkFormat.SourceName, ".")(0)
End If
End With
Next
If InStr(StrOut, Chr(11)) = 0 Then StrOut = StrOut & " None."
.InsertAfter vbCr & StrOut
End With
End Sub
Do note that the above code only searches the document body; not headers, footers, etc. The listings are output at the end of the document.