AddPicture in VBA without explict reference to a file path?

  • Thread starter Vincent Verheul
  • Start date
V

Vincent Verheul

Hello Group,

I am able to generate a Word document using Visual Basic for Applications
with an InLine Shape that links to an external JPEG file. This works fine as
long as the filename includes the full path
("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
"../../Folder3\MyPicture.jpg").

Now I want to create an InLine Shape that links to an external JPEG file
that sits in the same folder as the document itself (whatever that folder
may be). This is because I want to send the document with JPEG to others
without having to include the image into the Word document: when I do, the
Word document translates JPEG to BitMap and bloats to an impractical size.

I have tried the following code:

Set oMyShape = .InlineShapes.AddPicture(FileName:="/" & MyImageFileName,
LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)

or

Set oMyShape = .InlineShapes.AddPicture(FileName:=MyImageFileName,
LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)

The variable MyImageFileName is a String containing "MyPicture.jpg"

However, Word does not find the Image (that DOES exist in the same folder as
the Word document itself) and fails the operation, returning the object
oMyShape with the value 'Nothing'.

Any suggestions?

TIA
Vincent
 
M

macropod

Hi Vincent,

There's two ways you could approach this problem.

One way is to code the INCLUDEPICTURE fields so that they always look in the current folder. To do this, each field would be coded
along the lines of:
{ INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
where 'Filename.jpg' is the name of the picture file.

Note that the field braces around 'filename \p' are created via Ctrl-F9 - you can't just type them.

If you have a lot of these to do, I'd suggest doing the first one, copying that field to all the remaining picture positions, then
pressing Alt-F9 to expose all the field codes and changing the filenames to suit. Delete the old fields as you go. When you're done,
press Alt-F9 again to hide the field codes, then Alt-A to select the whole document and F9 to update all the fields.

The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but not with LINK fields.

The other way is to use a macro to automatically update the field paths whenever the document is opened. The following macro updates
INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.

Option Explicit
Dim TrkStatus As Boolean ' Track Changes flag

Private Sub AutoOpen()
' This routine runs whenever the document is opened.
' It calls on the others to do the real work.
' Prepare the environment.
Call MacroEntry
' Most of the work is done by this routine.
Call UpdateFields
' Set the saved status of the document to true, so that changes via
' this code are ignored. Since the same changes will be made the
' next time the document is opened, saving them doesn't matter.
ActiveDocument.Saved = True
' Go to the start of the document
Selection.HomeKey Unit:=wdStory
' Clean up and exit.
Call MacroExit
End Sub

Private Sub MacroEntry()
' Store current Track Changes status, then switch off temporarily.
With ActiveDocument
TrkStatus = .TrackRevisions
.TrackRevisions = False
End With
' Turn Off Screen Updating temporarily.
Application.ScreenUpdating = False
End Sub

Private Sub MacroExit()
' Restore original Track Changes status
ActiveDocument.TrackRevisions = TrkStatus
' Restore Screen Updating
Application.ScreenUpdating = True
End Sub

Private Sub UpdateFields()
' This routine sets the new path for external links.
Dim oRange As Word.Range
Dim oField As Word.Field
Dim OldPath As String
Dim NewPath As String
' Set the new path
NewPath = Replace$(ActiveDocument.Path, "\", "\\")
' Go through all story ranges in the document, including shapes,
' headers & footers.
For Each oRange In ActiveDocument.StoryRanges
' Go through the fields in the story range.
For Each oField In oRange.Fields
With oField
' Skip over fields that don't have links to external files
If Not .LinkFormat Is Nothing Then
' Get the old path
OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
' Replace the link to the external file
.Code.Text = Replace(.Code.Text, OldPath, NewPath)
End If
End With
Next oField
Next oRange
End Sub

Amongst other things, the macro gives feedback on its progress.

To make the macro update only INCLUDEPICTURE fields, you'd change the line:
If Not .LinkFormat Is Nothing Then
to
If .Type = wdFieldIncludePicture Then

Cheers

--
macropod
[MVP - Microsoft Word]


| Hello Group,
|
| I am able to generate a Word document using Visual Basic for Applications
| with an InLine Shape that links to an external JPEG file. This works fine as
| long as the filename includes the full path
| ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| "../../Folder3\MyPicture.jpg").
|
| Now I want to create an InLine Shape that links to an external JPEG file
| that sits in the same folder as the document itself (whatever that folder
| may be). This is because I want to send the document with JPEG to others
| without having to include the image into the Word document: when I do, the
| Word document translates JPEG to BitMap and bloats to an impractical size.
|
| I have tried the following code:
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:="/" & MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| or
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:=MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| The variable MyImageFileName is a String containing "MyPicture.jpg"
|
| However, Word does not find the Image (that DOES exist in the same folder as
| the Word document itself) and fails the operation, returning the object
| oMyShape with the value 'Nothing'.
|
| Any suggestions?
|
| TIA
| Vincent
|
|
|
|
 
V

Vincent Verheul

Thanks!

This works fine! I have changed the routine a little to have *no* path at
all in the linked field. This allows me to move the Word document (together
with the image files) to any folder I would like (or email it to someone
else).

Private Sub SetLinkedImagesLocalPath()
' This routine sets the new path for external links.
' The new path is empty: indicates that the external
' link is in the same folder as the Word document.
Dim oRange As Word.Range
Dim oField As Word.Field
Dim OldPath As String
Dim NewPath As String
'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
NewPath = vbNullString
' Go through all story ranges in the document, including shapes,
' headers & footers.
For Each oRange In ActiveDocument.StoryRanges
' Go through the fields in the story range.
For Each oField In oRange.Fields
With oField
' Skip over fields that don't have links to external images
If .Type = wdFieldIncludePicture Then
If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
' Get the old <absolute> path
OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
Else
' Get the old <relative> path
OldPath = .LinkFormat.SourcePath & "/"
End If
' Replace the link to the external file
.Code.Text = Replace(.Code.Text, OldPath, NewPath)
End If
End With
Next oField
Next oRange
End Sub



macropod said:
Hi Vincent,

There's two ways you could approach this problem.

One way is to code the INCLUDEPICTURE fields so that they always look in
the current folder. To do this, each field would be coded
along the lines of:
{ INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
where 'Filename.jpg' is the name of the picture file.

Note that the field braces around 'filename \p' are created via Ctrl-F9 -
you can't just type them.

If you have a lot of these to do, I'd suggest doing the first one, copying
that field to all the remaining picture positions, then
pressing Alt-F9 to expose all the field codes and changing the filenames
to suit. Delete the old fields as you go. When you're done,
press Alt-F9 again to hide the field codes, then Alt-A to select the whole
document and F9 to update all the fields.

The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but not
with LINK fields.

The other way is to use a macro to automatically update the field paths
whenever the document is opened. The following macro updates
INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.

Option Explicit
Dim TrkStatus As Boolean ' Track Changes flag

Private Sub AutoOpen()
' This routine runs whenever the document is opened.
' It calls on the others to do the real work.
' Prepare the environment.
Call MacroEntry
' Most of the work is done by this routine.
Call UpdateFields
' Set the saved status of the document to true, so that changes via
' this code are ignored. Since the same changes will be made the
' next time the document is opened, saving them doesn't matter.
ActiveDocument.Saved = True
' Go to the start of the document
Selection.HomeKey Unit:=wdStory
' Clean up and exit.
Call MacroExit
End Sub

Private Sub MacroEntry()
' Store current Track Changes status, then switch off temporarily.
With ActiveDocument
TrkStatus = .TrackRevisions
.TrackRevisions = False
End With
' Turn Off Screen Updating temporarily.
Application.ScreenUpdating = False
End Sub

Private Sub MacroExit()
' Restore original Track Changes status
ActiveDocument.TrackRevisions = TrkStatus
' Restore Screen Updating
Application.ScreenUpdating = True
End Sub

Private Sub UpdateFields()
' This routine sets the new path for external links.
Dim oRange As Word.Range
Dim oField As Word.Field
Dim OldPath As String
Dim NewPath As String
' Set the new path
NewPath = Replace$(ActiveDocument.Path, "\", "\\")
' Go through all story ranges in the document, including shapes,
' headers & footers.
For Each oRange In ActiveDocument.StoryRanges
' Go through the fields in the story range.
For Each oField In oRange.Fields
With oField
' Skip over fields that don't have links to external files
If Not .LinkFormat Is Nothing Then
' Get the old path
OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
' Replace the link to the external file
.Code.Text = Replace(.Code.Text, OldPath, NewPath)
End If
End With
Next oField
Next oRange
End Sub

Amongst other things, the macro gives feedback on its progress.

To make the macro update only INCLUDEPICTURE fields, you'd change the
line:
If Not .LinkFormat Is Nothing Then
to
If .Type = wdFieldIncludePicture Then

Cheers

--
macropod
[MVP - Microsoft Word]


| Hello Group,
|
| I am able to generate a Word document using Visual Basic for
Applications
| with an InLine Shape that links to an external JPEG file. This works
fine as
| long as the filename includes the full path
| ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| "../../Folder3\MyPicture.jpg").
|
| Now I want to create an InLine Shape that links to an external JPEG file
| that sits in the same folder as the document itself (whatever that
folder
| may be). This is because I want to send the document with JPEG to others
| without having to include the image into the Word document: when I do,
the
| Word document translates JPEG to BitMap and bloats to an impractical
size.
|
| I have tried the following code:
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| or
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:=MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| The variable MyImageFileName is a String containing "MyPicture.jpg"
|
| However, Word does not find the Image (that DOES exist in the same
folder as
| the Word document itself) and fails the operation, returning the object
| oMyShape with the value 'Nothing'.
|
| Any suggestions?
|
| TIA
| Vincent
|
|
|
|
 
V

Vincent Verheul

Hmm,

I was too quick, after a better test I found out that it doesn't work:
- The path in the linked image IS changed
- but Word does not seem to use it
- Word keeps a copy of the original Path and uses that one

Inspecting the Word file with a plain text editor (like Notepad) reveals
that the original Path and Filename is stored at the very end of the
document. Testing with the image files present in one or the other location
indicates that Word still uses the original Path and Filename.

Too bad!

This takes the focus back on the real issue: inserting an image using the
VBA method AddPicture results in a conversion to BitMap and a hugely bloated
Word document. When I insert the .JPEG and .GIF images (ten images of 25 Kb
each) into my 30 page document programatically I end up with a file of 7000
Kb. When I insert the images by hand (Insert=>Picture=>From File...) I end
up with a file of only 310 Kb (a factor 22!). Isn't there a method to do
programatically what I can do by hand?

Note: I use VBA out of a Microsoft Access environment to generate reports in
Word.

Any ideas a welcome, thanks!

Vincent


Vincent Verheul said:
Thanks!

This works fine! I have changed the routine a little to have *no* path at
all in the linked field. This allows me to move the Word document
(together with the image files) to any folder I would like (or email it to
someone else).

Private Sub SetLinkedImagesLocalPath()
' This routine sets the new path for external links.
' The new path is empty: indicates that the external
' link is in the same folder as the Word document.
Dim oRange As Word.Range
Dim oField As Word.Field
Dim OldPath As String
Dim NewPath As String
'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
NewPath = vbNullString
' Go through all story ranges in the document, including shapes,
' headers & footers.
For Each oRange In ActiveDocument.StoryRanges
' Go through the fields in the story range.
For Each oField In oRange.Fields
With oField
' Skip over fields that don't have links to external images
If .Type = wdFieldIncludePicture Then
If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
' Get the old <absolute> path
OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
Else
' Get the old <relative> path
OldPath = .LinkFormat.SourcePath & "/"
End If
' Replace the link to the external file
.Code.Text = Replace(.Code.Text, OldPath, NewPath)
End If
End With
Next oField
Next oRange
End Sub



macropod said:
Hi Vincent,

There's two ways you could approach this problem.

One way is to code the INCLUDEPICTURE fields so that they always look in
the current folder. To do this, each field would be coded
along the lines of:
{ INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
where 'Filename.jpg' is the name of the picture file.

Note that the field braces around 'filename \p' are created via Ctrl-F9 -
you can't just type them.

If you have a lot of these to do, I'd suggest doing the first one,
copying that field to all the remaining picture positions, then
pressing Alt-F9 to expose all the field codes and changing the filenames
to suit. Delete the old fields as you go. When you're done,
press Alt-F9 again to hide the field codes, then Alt-A to select the
whole document and F9 to update all the fields.

The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but not
with LINK fields.

The other way is to use a macro to automatically update the field paths
whenever the document is opened. The following macro updates
INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.

Option Explicit
Dim TrkStatus As Boolean ' Track Changes flag

Private Sub AutoOpen()
' This routine runs whenever the document is opened.
' It calls on the others to do the real work.
' Prepare the environment.
Call MacroEntry
' Most of the work is done by this routine.
Call UpdateFields
' Set the saved status of the document to true, so that changes via
' this code are ignored. Since the same changes will be made the
' next time the document is opened, saving them doesn't matter.
ActiveDocument.Saved = True
' Go to the start of the document
Selection.HomeKey Unit:=wdStory
' Clean up and exit.
Call MacroExit
End Sub

Private Sub MacroEntry()
' Store current Track Changes status, then switch off temporarily.
With ActiveDocument
TrkStatus = .TrackRevisions
.TrackRevisions = False
End With
' Turn Off Screen Updating temporarily.
Application.ScreenUpdating = False
End Sub

Private Sub MacroExit()
' Restore original Track Changes status
ActiveDocument.TrackRevisions = TrkStatus
' Restore Screen Updating
Application.ScreenUpdating = True
End Sub

Private Sub UpdateFields()
' This routine sets the new path for external links.
Dim oRange As Word.Range
Dim oField As Word.Field
Dim OldPath As String
Dim NewPath As String
' Set the new path
NewPath = Replace$(ActiveDocument.Path, "\", "\\")
' Go through all story ranges in the document, including shapes,
' headers & footers.
For Each oRange In ActiveDocument.StoryRanges
' Go through the fields in the story range.
For Each oField In oRange.Fields
With oField
' Skip over fields that don't have links to external files
If Not .LinkFormat Is Nothing Then
' Get the old path
OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
' Replace the link to the external file
.Code.Text = Replace(.Code.Text, OldPath, NewPath)
End If
End With
Next oField
Next oRange
End Sub

Amongst other things, the macro gives feedback on its progress.

To make the macro update only INCLUDEPICTURE fields, you'd change the
line:
If Not .LinkFormat Is Nothing Then
to
If .Type = wdFieldIncludePicture Then

Cheers

--
macropod
[MVP - Microsoft Word]


| Hello Group,
|
| I am able to generate a Word document using Visual Basic for
Applications
| with an InLine Shape that links to an external JPEG file. This works
fine as
| long as the filename includes the full path
| ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| "../../Folder3\MyPicture.jpg").
|
| Now I want to create an InLine Shape that links to an external JPEG
file
| that sits in the same folder as the document itself (whatever that
folder
| may be). This is because I want to send the document with JPEG to
others
| without having to include the image into the Word document: when I do,
the
| Word document translates JPEG to BitMap and bloats to an impractical
size.
|
| I have tried the following code:
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| or
|
| Set oMyShape = .InlineShapes.AddPicture(FileName:=MyImageFileName,
| LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
|
| The variable MyImageFileName is a String containing "MyPicture.jpg"
|
| However, Word does not find the Image (that DOES exist in the same
folder as
| the Word document itself) and fails the operation, returning the object
| oMyShape with the value 'Nothing'.
|
| Any suggestions?
|
| TIA
| Vincent
|
|
|
|
 
M

macropod

Hi Vincent,

I already gave you two quite workable solutions for automatically updating the links to the files.

As for the file size with embedded images, Word 97 and later store JPEG images in JPEG format and converts all other raster formats
to a compressed PNG format. I experimented with inserting a 62kb png image and a 4kb gif image into an empty Word 2000 document and
Windows explorer reported a file size increases of only 62kb and 4Kb, respectively - the same as the image sizes. I got exactly the
same results manually and with the VBA AddPicture method. Word 95 and earlier stored all image data in an uncompressed form, which
would greatly increase the file size with any embedded image. Which raises the question - which version are you using?

Cheers

--
macropod
[MVP - Microsoft Word]


| Hmm,
|
| I was too quick, after a better test I found out that it doesn't work:
| - The path in the linked image IS changed
| - but Word does not seem to use it
| - Word keeps a copy of the original Path and uses that one
|
| Inspecting the Word file with a plain text editor (like Notepad) reveals
| that the original Path and Filename is stored at the very end of the
| document. Testing with the image files present in one or the other location
| indicates that Word still uses the original Path and Filename.
|
| Too bad!
|
| This takes the focus back on the real issue: inserting an image using the
| VBA method AddPicture results in a conversion to BitMap and a hugely bloated
| Word document. When I insert the .JPEG and .GIF images (ten images of 25 Kb
| each) into my 30 page document programatically I end up with a file of 7000
| Kb. When I insert the images by hand (Insert=>Picture=>From File...) I end
| up with a file of only 310 Kb (a factor 22!). Isn't there a method to do
| programatically what I can do by hand?
|
| Note: I use VBA out of a Microsoft Access environment to generate reports in
| Word.
|
| Any ideas a welcome, thanks!
|
| Vincent
|
|
| | > Thanks!
| >
| > This works fine! I have changed the routine a little to have *no* path at
| > all in the linked field. This allows me to move the Word document
| > (together with the image files) to any folder I would like (or email it to
| > someone else).
| >
| > Private Sub SetLinkedImagesLocalPath()
| > ' This routine sets the new path for external links.
| > ' The new path is empty: indicates that the external
| > ' link is in the same folder as the Word document.
| > Dim oRange As Word.Range
| > Dim oField As Word.Field
| > Dim OldPath As String
| > Dim NewPath As String
| > 'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
| > NewPath = vbNullString
| > ' Go through all story ranges in the document, including shapes,
| > ' headers & footers.
| > For Each oRange In ActiveDocument.StoryRanges
| > ' Go through the fields in the story range.
| > For Each oField In oRange.Fields
| > With oField
| > ' Skip over fields that don't have links to external images
| > If .Type = wdFieldIncludePicture Then
| > If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
| > ' Get the old <absolute> path
| > OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
| > Else
| > ' Get the old <relative> path
| > OldPath = .LinkFormat.SourcePath & "/"
| > End If
| > ' Replace the link to the external file
| > .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > End If
| > End With
| > Next oField
| > Next oRange
| > End Sub
| >
| >
| >
| > | >> Hi Vincent,
| >>
| >> There's two ways you could approach this problem.
| >>
| >> One way is to code the INCLUDEPICTURE fields so that they always look in
| >> the current folder. To do this, each field would be coded
| >> along the lines of:
| >> { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
| >> where 'Filename.jpg' is the name of the picture file.
| >>
| >> Note that the field braces around 'filename \p' are created via Ctrl-F9 -
| >> you can't just type them.
| >>
| >> If you have a lot of these to do, I'd suggest doing the first one,
| >> copying that field to all the remaining picture positions, then
| >> pressing Alt-F9 to expose all the field codes and changing the filenames
| >> to suit. Delete the old fields as you go. When you're done,
| >> press Alt-F9 again to hide the field codes, then Alt-A to select the
| >> whole document and F9 to update all the fields.
| >>
| >> The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but not
| >> with LINK fields.
| >>
| >> The other way is to use a macro to automatically update the field paths
| >> whenever the document is opened. The following macro updates
| >> INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.
| >>
| >> Option Explicit
| >> Dim TrkStatus As Boolean ' Track Changes flag
| >>
| >> Private Sub AutoOpen()
| >> ' This routine runs whenever the document is opened.
| >> ' It calls on the others to do the real work.
| >> ' Prepare the environment.
| >> Call MacroEntry
| >> ' Most of the work is done by this routine.
| >> Call UpdateFields
| >> ' Set the saved status of the document to true, so that changes via
| >> ' this code are ignored. Since the same changes will be made the
| >> ' next time the document is opened, saving them doesn't matter.
| >> ActiveDocument.Saved = True
| >> ' Go to the start of the document
| >> Selection.HomeKey Unit:=wdStory
| >> ' Clean up and exit.
| >> Call MacroExit
| >> End Sub
| >>
| >> Private Sub MacroEntry()
| >> ' Store current Track Changes status, then switch off temporarily.
| >> With ActiveDocument
| >> TrkStatus = .TrackRevisions
| >> .TrackRevisions = False
| >> End With
| >> ' Turn Off Screen Updating temporarily.
| >> Application.ScreenUpdating = False
| >> End Sub
| >>
| >> Private Sub MacroExit()
| >> ' Restore original Track Changes status
| >> ActiveDocument.TrackRevisions = TrkStatus
| >> ' Restore Screen Updating
| >> Application.ScreenUpdating = True
| >> End Sub
| >>
| >> Private Sub UpdateFields()
| >> ' This routine sets the new path for external links.
| >> Dim oRange As Word.Range
| >> Dim oField As Word.Field
| >> Dim OldPath As String
| >> Dim NewPath As String
| >> ' Set the new path
| >> NewPath = Replace$(ActiveDocument.Path, "\", "\\")
| >> ' Go through all story ranges in the document, including shapes,
| >> ' headers & footers.
| >> For Each oRange In ActiveDocument.StoryRanges
| >> ' Go through the fields in the story range.
| >> For Each oField In oRange.Fields
| >> With oField
| >> ' Skip over fields that don't have links to external files
| >> If Not .LinkFormat Is Nothing Then
| >> ' Get the old path
| >> OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
| >> ' Replace the link to the external file
| >> .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| >> End If
| >> End With
| >> Next oField
| >> Next oRange
| >> End Sub
| >>
| >> Amongst other things, the macro gives feedback on its progress.
| >>
| >> To make the macro update only INCLUDEPICTURE fields, you'd change the
| >> line:
| >> If Not .LinkFormat Is Nothing Then
| >> to
| >> If .Type = wdFieldIncludePicture Then
| >>
| >> Cheers
| >>
| >> --
| >> macropod
| >> [MVP - Microsoft Word]
| >>
| >>
| >> | >> | Hello Group,
| >> |
| >> | I am able to generate a Word document using Visual Basic for
| >> Applications
| >> | with an InLine Shape that links to an external JPEG file. This works
| >> fine as
| >> | long as the filename includes the full path
| >> | ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| >> | "../../Folder3\MyPicture.jpg").
| >> |
| >> | Now I want to create an InLine Shape that links to an external JPEG
| >> file
| >> | that sits in the same folder as the document itself (whatever that
| >> folder
| >> | may be). This is because I want to send the document with JPEG to
| >> others
| >> | without having to include the image into the Word document: when I do,
| >> the
| >> | Word document translates JPEG to BitMap and bloats to an impractical
| >> size.
| >> |
| >> | I have tried the following code:
| >> |
| >> | Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
| >> MyImageFileName,
| >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| >> |
| >> | or
| >> |
| >> | Set oMyShape = .InlineShapes.AddPicture(FileName:=MyImageFileName,
| >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| >> |
| >> | The variable MyImageFileName is a String containing "MyPicture.jpg"
| >> |
| >> | However, Word does not find the Image (that DOES exist in the same
| >> folder as
| >> | the Word document itself) and fails the operation, returning the object
| >> | oMyShape with the value 'Nothing'.
| >> |
| >> | Any suggestions?
| >> |
| >> | TIA
| >> | Vincent
| >> |
| >> |
| >> |
| >> |
| >>
| >>
| >
| >
|
|
 
V

Vincent Verheul

Hi macropod,

Thanks for your response. I double checked the way that I insert pictures
and I owe you an opology: I was using the .InlineShapes.AddOLEObject method
in that case, instead of the .InlineShapes.AddPicture method! Now that I use
the latter with LinkToFile = False and SaveWithDocument = True the bloating
issue is solved!

Your VBA suggestion indeed works fine, as long as the VBA code is run out of
Word itself. What I wanted is a Word document without Marco (VBA) that has
'local' links, i.e. without the mention of any path, assuming the current
document's path. Probably that is not possible.

I create a Word document out of Ms Access using the Microsoft Word 11.0
Object Library (located in C:\Program Files\Micrsoft
Office\OFFICE11\MSWORD.OLB). I am using office 2003 as you can see. The
result is a Word document without a macro. This is highly preferrable
because of security standards not allowing Word Macros.

Thanks again!

Vincent

macropod said:
Hi Vincent,

I already gave you two quite workable solutions for automatically updating
the links to the files.

As for the file size with embedded images, Word 97 and later store JPEG
images in JPEG format and converts all other raster formats
to a compressed PNG format. I experimented with inserting a 62kb png image
and a 4kb gif image into an empty Word 2000 document and
Windows explorer reported a file size increases of only 62kb and 4Kb,
respectively - the same as the image sizes. I got exactly the
same results manually and with the VBA AddPicture method. Word 95 and
earlier stored all image data in an uncompressed form, which
would greatly increase the file size with any embedded image. Which raises
the question - which version are you using?

Cheers

--
macropod
[MVP - Microsoft Word]


| Hmm,
|
| I was too quick, after a better test I found out that it doesn't work:
| - The path in the linked image IS changed
| - but Word does not seem to use it
| - Word keeps a copy of the original Path and uses that one
|
| Inspecting the Word file with a plain text editor (like Notepad) reveals
| that the original Path and Filename is stored at the very end of the
| document. Testing with the image files present in one or the other
location
| indicates that Word still uses the original Path and Filename.
|
| Too bad!
|
| This takes the focus back on the real issue: inserting an image using
the
| VBA method AddPicture results in a conversion to BitMap and a hugely
bloated
| Word document. When I insert the .JPEG and .GIF images (ten images of 25
Kb
| each) into my 30 page document programatically I end up with a file of
7000
| Kb. When I insert the images by hand (Insert=>Picture=>From File...) I
end
| up with a file of only 310 Kb (a factor 22!). Isn't there a method to do
| programatically what I can do by hand?
|
| Note: I use VBA out of a Microsoft Access environment to generate
reports in
| Word.
|
| Any ideas a welcome, thanks!
|
| Vincent
|
|
| | > Thanks!
| >
| > This works fine! I have changed the routine a little to have *no* path
at
| > all in the linked field. This allows me to move the Word document
| > (together with the image files) to any folder I would like (or email
it to
| > someone else).
| >
| > Private Sub SetLinkedImagesLocalPath()
| > ' This routine sets the new path for external links.
| > ' The new path is empty: indicates that the external
| > ' link is in the same folder as the Word document.
| > Dim oRange As Word.Range
| > Dim oField As Word.Field
| > Dim OldPath As String
| > Dim NewPath As String
| > 'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
| > NewPath = vbNullString
| > ' Go through all story ranges in the document, including shapes,
| > ' headers & footers.
| > For Each oRange In ActiveDocument.StoryRanges
| > ' Go through the fields in the story range.
| > For Each oField In oRange.Fields
| > With oField
| > ' Skip over fields that don't have links to external images
| > If .Type = wdFieldIncludePicture Then
| > If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
| > ' Get the old <absolute> path
| > OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
| > Else
| > ' Get the old <relative> path
| > OldPath = .LinkFormat.SourcePath & "/"
| > End If
| > ' Replace the link to the external file
| > .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > End If
| > End With
| > Next oField
| > Next oRange
| > End Sub
| >
| >
| >
| > | >> Hi Vincent,
| >>
| >> There's two ways you could approach this problem.
| >>
| >> One way is to code the INCLUDEPICTURE fields so that they always look
in
| >> the current folder. To do this, each field would be coded
| >> along the lines of:
| >> { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
| >> where 'Filename.jpg' is the name of the picture file.
| >>
| >> Note that the field braces around 'filename \p' are created via
Ctrl-F9 -
| >> you can't just type them.
| >>
| >> If you have a lot of these to do, I'd suggest doing the first one,
| >> copying that field to all the remaining picture positions, then
| >> pressing Alt-F9 to expose all the field codes and changing the
filenames
| >> to suit. Delete the old fields as you go. When you're done,
| >> press Alt-F9 again to hide the field codes, then Alt-A to select the
| >> whole document and F9 to update all the fields.
| >>
| >> The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but
not
| >> with LINK fields.
| >>
| >> The other way is to use a macro to automatically update the field
paths
| >> whenever the document is opened. The following macro updates
| >> INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.
| >>
| >> Option Explicit
| >> Dim TrkStatus As Boolean ' Track Changes flag
| >>
| >> Private Sub AutoOpen()
| >> ' This routine runs whenever the document is opened.
| >> ' It calls on the others to do the real work.
| >> ' Prepare the environment.
| >> Call MacroEntry
| >> ' Most of the work is done by this routine.
| >> Call UpdateFields
| >> ' Set the saved status of the document to true, so that changes via
| >> ' this code are ignored. Since the same changes will be made the
| >> ' next time the document is opened, saving them doesn't matter.
| >> ActiveDocument.Saved = True
| >> ' Go to the start of the document
| >> Selection.HomeKey Unit:=wdStory
| >> ' Clean up and exit.
| >> Call MacroExit
| >> End Sub
| >>
| >> Private Sub MacroEntry()
| >> ' Store current Track Changes status, then switch off temporarily.
| >> With ActiveDocument
| >> TrkStatus = .TrackRevisions
| >> .TrackRevisions = False
| >> End With
| >> ' Turn Off Screen Updating temporarily.
| >> Application.ScreenUpdating = False
| >> End Sub
| >>
| >> Private Sub MacroExit()
| >> ' Restore original Track Changes status
| >> ActiveDocument.TrackRevisions = TrkStatus
| >> ' Restore Screen Updating
| >> Application.ScreenUpdating = True
| >> End Sub
| >>
| >> Private Sub UpdateFields()
| >> ' This routine sets the new path for external links.
| >> Dim oRange As Word.Range
| >> Dim oField As Word.Field
| >> Dim OldPath As String
| >> Dim NewPath As String
| >> ' Set the new path
| >> NewPath = Replace$(ActiveDocument.Path, "\", "\\")
| >> ' Go through all story ranges in the document, including shapes,
| >> ' headers & footers.
| >> For Each oRange In ActiveDocument.StoryRanges
| >> ' Go through the fields in the story range.
| >> For Each oField In oRange.Fields
| >> With oField
| >> ' Skip over fields that don't have links to external files
| >> If Not .LinkFormat Is Nothing Then
| >> ' Get the old path
| >> OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
| >> ' Replace the link to the external file
| >> .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| >> End If
| >> End With
| >> Next oField
| >> Next oRange
| >> End Sub
| >>
| >> Amongst other things, the macro gives feedback on its progress.
| >>
| >> To make the macro update only INCLUDEPICTURE fields, you'd change the
| >> line:
| >> If Not .LinkFormat Is Nothing Then
| >> to
| >> If .Type = wdFieldIncludePicture Then
| >>
| >> Cheers
| >>
| >> --
| >> macropod
| >> [MVP - Microsoft Word]
| >>
| >>
| >> | >> | Hello Group,
| >> |
| >> | I am able to generate a Word document using Visual Basic for
| >> Applications
| >> | with an InLine Shape that links to an external JPEG file. This
works
| >> fine as
| >> | long as the filename includes the full path
| >> | ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| >> | "../../Folder3\MyPicture.jpg").
| >> |
| >> | Now I want to create an InLine Shape that links to an external JPEG
| >> file
| >> | that sits in the same folder as the document itself (whatever that
| >> folder
| >> | may be). This is because I want to send the document with JPEG to
| >> others
| >> | without having to include the image into the Word document: when I
do,
| >> the
| >> | Word document translates JPEG to BitMap and bloats to an
impractical
| >> size.
| >> |
| >> | I have tried the following code:
| >> |
| >> | Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
| >> MyImageFileName,
| >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| >> |
| >> | or
| >> |
| >> | Set oMyShape =
.InlineShapes.AddPicture(FileName:=MyImageFileName,
| >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| >> |
| >> | The variable MyImageFileName is a String containing
"MyPicture.jpg"
| >> |
| >> | However, Word does not find the Image (that DOES exist in the same
| >> folder as
| >> | the Word document itself) and fails the operation, returning the
object
| >> | oMyShape with the value 'Nothing'.
| >> |
| >> | Any suggestions?
| >> |
| >> | TIA
| >> | Vincent
| >> |
| >> |
| >> |
| >> |
| >>
| >>
| >
| >
|
|
 
M

macropod

Hi Vincent,

In that case, the field coding solution I posted should work fine. No macros involved there.

Cheers

--
macropod
[MVP - Microsoft Word]


| Hi macropod,
|
| Thanks for your response. I double checked the way that I insert pictures
| and I owe you an opology: I was using the .InlineShapes.AddOLEObject method
| in that case, instead of the .InlineShapes.AddPicture method! Now that I use
| the latter with LinkToFile = False and SaveWithDocument = True the bloating
| issue is solved!
|
| Your VBA suggestion indeed works fine, as long as the VBA code is run out of
| Word itself. What I wanted is a Word document without Marco (VBA) that has
| 'local' links, i.e. without the mention of any path, assuming the current
| document's path. Probably that is not possible.
|
| I create a Word document out of Ms Access using the Microsoft Word 11.0
| Object Library (located in C:\Program Files\Micrsoft
| Office\OFFICE11\MSWORD.OLB). I am using office 2003 as you can see. The
| result is a Word document without a macro. This is highly preferrable
| because of security standards not allowing Word Macros.
|
| Thanks again!
|
| Vincent
|
| | > Hi Vincent,
| >
| > I already gave you two quite workable solutions for automatically updating
| > the links to the files.
| >
| > As for the file size with embedded images, Word 97 and later store JPEG
| > images in JPEG format and converts all other raster formats
| > to a compressed PNG format. I experimented with inserting a 62kb png image
| > and a 4kb gif image into an empty Word 2000 document and
| > Windows explorer reported a file size increases of only 62kb and 4Kb,
| > respectively - the same as the image sizes. I got exactly the
| > same results manually and with the VBA AddPicture method. Word 95 and
| > earlier stored all image data in an uncompressed form, which
| > would greatly increase the file size with any embedded image. Which raises
| > the question - which version are you using?
| >
| > Cheers
| >
| > --
| > macropod
| > [MVP - Microsoft Word]
| >
| >
| > | > | Hmm,
| > |
| > | I was too quick, after a better test I found out that it doesn't work:
| > | - The path in the linked image IS changed
| > | - but Word does not seem to use it
| > | - Word keeps a copy of the original Path and uses that one
| > |
| > | Inspecting the Word file with a plain text editor (like Notepad) reveals
| > | that the original Path and Filename is stored at the very end of the
| > | document. Testing with the image files present in one or the other
| > location
| > | indicates that Word still uses the original Path and Filename.
| > |
| > | Too bad!
| > |
| > | This takes the focus back on the real issue: inserting an image using
| > the
| > | VBA method AddPicture results in a conversion to BitMap and a hugely
| > bloated
| > | Word document. When I insert the .JPEG and .GIF images (ten images of 25
| > Kb
| > | each) into my 30 page document programatically I end up with a file of
| > 7000
| > | Kb. When I insert the images by hand (Insert=>Picture=>From File...) I
| > end
| > | up with a file of only 310 Kb (a factor 22!). Isn't there a method to do
| > | programatically what I can do by hand?
| > |
| > | Note: I use VBA out of a Microsoft Access environment to generate
| > reports in
| > | Word.
| > |
| > | Any ideas a welcome, thanks!
| > |
| > | Vincent
| > |
| > |
| > | | > | > Thanks!
| > | >
| > | > This works fine! I have changed the routine a little to have *no* path
| > at
| > | > all in the linked field. This allows me to move the Word document
| > | > (together with the image files) to any folder I would like (or email
| > it to
| > | > someone else).
| > | >
| > | > Private Sub SetLinkedImagesLocalPath()
| > | > ' This routine sets the new path for external links.
| > | > ' The new path is empty: indicates that the external
| > | > ' link is in the same folder as the Word document.
| > | > Dim oRange As Word.Range
| > | > Dim oField As Word.Field
| > | > Dim OldPath As String
| > | > Dim NewPath As String
| > | > 'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
| > | > NewPath = vbNullString
| > | > ' Go through all story ranges in the document, including shapes,
| > | > ' headers & footers.
| > | > For Each oRange In ActiveDocument.StoryRanges
| > | > ' Go through the fields in the story range.
| > | > For Each oField In oRange.Fields
| > | > With oField
| > | > ' Skip over fields that don't have links to external images
| > | > If .Type = wdFieldIncludePicture Then
| > | > If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
| > | > ' Get the old <absolute> path
| > | > OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
| > | > Else
| > | > ' Get the old <relative> path
| > | > OldPath = .LinkFormat.SourcePath & "/"
| > | > End If
| > | > ' Replace the link to the external file
| > | > .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > | > End If
| > | > End With
| > | > Next oField
| > | > Next oRange
| > | > End Sub
| > | >
| > | >
| > | >
| > | > | > | >> Hi Vincent,
| > | >>
| > | >> There's two ways you could approach this problem.
| > | >>
| > | >> One way is to code the INCLUDEPICTURE fields so that they always look
| > in
| > | >> the current folder. To do this, each field would be coded
| > | >> along the lines of:
| > | >> { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
| > | >> where 'Filename.jpg' is the name of the picture file.
| > | >>
| > | >> Note that the field braces around 'filename \p' are created via
| > Ctrl-F9 -
| > | >> you can't just type them.
| > | >>
| > | >> If you have a lot of these to do, I'd suggest doing the first one,
| > | >> copying that field to all the remaining picture positions, then
| > | >> pressing Alt-F9 to expose all the field codes and changing the
| > filenames
| > | >> to suit. Delete the old fields as you go. When you're done,
| > | >> press Alt-F9 again to hide the field codes, then Alt-A to select the
| > | >> whole document and F9 to update all the fields.
| > | >>
| > | >> The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but
| > not
| > | >> with LINK fields.
| > | >>
| > | >> The other way is to use a macro to automatically update the field
| > paths
| > | >> whenever the document is opened. The following macro updates
| > | >> INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.
| > | >>
| > | >> Option Explicit
| > | >> Dim TrkStatus As Boolean ' Track Changes flag
| > | >>
| > | >> Private Sub AutoOpen()
| > | >> ' This routine runs whenever the document is opened.
| > | >> ' It calls on the others to do the real work.
| > | >> ' Prepare the environment.
| > | >> Call MacroEntry
| > | >> ' Most of the work is done by this routine.
| > | >> Call UpdateFields
| > | >> ' Set the saved status of the document to true, so that changes via
| > | >> ' this code are ignored. Since the same changes will be made the
| > | >> ' next time the document is opened, saving them doesn't matter.
| > | >> ActiveDocument.Saved = True
| > | >> ' Go to the start of the document
| > | >> Selection.HomeKey Unit:=wdStory
| > | >> ' Clean up and exit.
| > | >> Call MacroExit
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroEntry()
| > | >> ' Store current Track Changes status, then switch off temporarily.
| > | >> With ActiveDocument
| > | >> TrkStatus = .TrackRevisions
| > | >> .TrackRevisions = False
| > | >> End With
| > | >> ' Turn Off Screen Updating temporarily.
| > | >> Application.ScreenUpdating = False
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroExit()
| > | >> ' Restore original Track Changes status
| > | >> ActiveDocument.TrackRevisions = TrkStatus
| > | >> ' Restore Screen Updating
| > | >> Application.ScreenUpdating = True
| > | >> End Sub
| > | >>
| > | >> Private Sub UpdateFields()
| > | >> ' This routine sets the new path for external links.
| > | >> Dim oRange As Word.Range
| > | >> Dim oField As Word.Field
| > | >> Dim OldPath As String
| > | >> Dim NewPath As String
| > | >> ' Set the new path
| > | >> NewPath = Replace$(ActiveDocument.Path, "\", "\\")
| > | >> ' Go through all story ranges in the document, including shapes,
| > | >> ' headers & footers.
| > | >> For Each oRange In ActiveDocument.StoryRanges
| > | >> ' Go through the fields in the story range.
| > | >> For Each oField In oRange.Fields
| > | >> With oField
| > | >> ' Skip over fields that don't have links to external files
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> ' Get the old path
| > | >> OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
| > | >> ' Replace the link to the external file
| > | >> .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > | >> End If
| > | >> End With
| > | >> Next oField
| > | >> Next oRange
| > | >> End Sub
| > | >>
| > | >> Amongst other things, the macro gives feedback on its progress.
| > | >>
| > | >> To make the macro update only INCLUDEPICTURE fields, you'd change the
| > | >> line:
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> to
| > | >> If .Type = wdFieldIncludePicture Then
| > | >>
| > | >> Cheers
| > | >>
| > | >> --
| > | >> macropod
| > | >> [MVP - Microsoft Word]
| > | >>
| > | >>
| > | >> | > | >> | Hello Group,
| > | >> |
| > | >> | I am able to generate a Word document using Visual Basic for
| > | >> Applications
| > | >> | with an InLine Shape that links to an external JPEG file. This
| > works
| > | >> fine as
| > | >> | long as the filename includes the full path
| > | >> | ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| > | >> | "../../Folder3\MyPicture.jpg").
| > | >> |
| > | >> | Now I want to create an InLine Shape that links to an external JPEG
| > | >> file
| > | >> | that sits in the same folder as the document itself (whatever that
| > | >> folder
| > | >> | may be). This is because I want to send the document with JPEG to
| > | >> others
| > | >> | without having to include the image into the Word document: when I
| > do,
| > | >> the
| > | >> | Word document translates JPEG to BitMap and bloats to an
| > impractical
| > | >> size.
| > | >> |
| > | >> | I have tried the following code:
| > | >> |
| > | >> | Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
| > | >> MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| > | >> |
| > | >> | or
| > | >> |
| > | >> | Set oMyShape =
| > .InlineShapes.AddPicture(FileName:=MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| > | >> |
| > | >> | The variable MyImageFileName is a String containing
| > "MyPicture.jpg"
| > | >> |
| > | >> | However, Word does not find the Image (that DOES exist in the same
| > | >> folder as
| > | >> | the Word document itself) and fails the operation, returning the
| > object
| > | >> | oMyShape with the value 'Nothing'.
| > | >> |
| > | >> | Any suggestions?
| > | >> |
| > | >> | TIA
| > | >> | Vincent
| > | >> |
| > | >> |
| > | >> |
| > | >> |
| > | >>
| > | >>
| > | >
| > | >
| > |
| > |
| >
| >
|
|
 
B

Bill Schopper

First let me say you are my hero . . .

I write large appraisal reports with many linked photos and graphics with
Word 2003 all being contained in the same folder as the report to save fiel
size. My work process is that while I am working on the report I am on the
desktop and then file the folder when I am done. Many times I start with a
previous appraisal similar to the one I am working on where many of the
graphics wil be the same. That has worked very well for years . . . until
some sort of Microsoft update, probably security

I was trying to figure out why my linked photos quit working when I copy and
paste out of one report to another or change the folder name. The new
copy will refer to the old location and the photos in the old appraisal.
When I change the old folder's name the photos can not be found.

I have always kept the photos in the same folder as the word document and
all of the refernces are relative. I can inspect the links and they are
right, I can edit them and they will change to the curent location simply by
putting mergformat at the end.

Macropod, is your code { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
correct? Should there be another "? Above where it says filename \p
should that be filename.jpg \p ?

Any ideas whre I am messing up.

Thank you,

Bill Schopper

macropod said:
Hi Vincent,

In that case, the field coding solution I posted should work fine. No macros involved there.

Cheers

--
macropod
[MVP - Microsoft Word]


| Hi macropod,
|
| Thanks for your response. I double checked the way that I insert pictures
| and I owe you an opology: I was using the .InlineShapes.AddOLEObject method
| in that case, instead of the .InlineShapes.AddPicture method! Now that I use
| the latter with LinkToFile = False and SaveWithDocument = True the bloating
| issue is solved!
|
| Your VBA suggestion indeed works fine, as long as the VBA code is run out of
| Word itself. What I wanted is a Word document without Marco (VBA) that has
| 'local' links, i.e. without the mention of any path, assuming the current
| document's path. Probably that is not possible.
|
| I create a Word document out of Ms Access using the Microsoft Word 11.0
| Object Library (located in C:\Program Files\Micrsoft
| Office\OFFICE11\MSWORD.OLB). I am using office 2003 as you can see. The
| result is a Word document without a macro. This is highly preferrable
| because of security standards not allowing Word Macros.
|
| Thanks again!
|
| Vincent
|
| | > Hi Vincent,
| >
| > I already gave you two quite workable solutions for automatically updating
| > the links to the files.
| >
| > As for the file size with embedded images, Word 97 and later store JPEG
| > images in JPEG format and converts all other raster formats
| > to a compressed PNG format. I experimented with inserting a 62kb png image
| > and a 4kb gif image into an empty Word 2000 document and
| > Windows explorer reported a file size increases of only 62kb and 4Kb,
| > respectively - the same as the image sizes. I got exactly the
| > same results manually and with the VBA AddPicture method. Word 95 and
| > earlier stored all image data in an uncompressed form, which
| > would greatly increase the file size with any embedded image. Which raises
| > the question - which version are you using?
| >
| > Cheers
| >
| > --
| > macropod
| > [MVP - Microsoft Word]
| >
| >
| > | > | Hmm,
| > |
| > | I was too quick, after a better test I found out that it doesn't work:
| > | - The path in the linked image IS changed
| > | - but Word does not seem to use it
| > | - Word keeps a copy of the original Path and uses that one
| > |
| > | Inspecting the Word file with a plain text editor (like Notepad) reveals
| > | that the original Path and Filename is stored at the very end of the
| > | document. Testing with the image files present in one or the other
| > location
| > | indicates that Word still uses the original Path and Filename.
| > |
| > | Too bad!
| > |
| > | This takes the focus back on the real issue: inserting an image using
| > the
| > | VBA method AddPicture results in a conversion to BitMap and a hugely
| > bloated
| > | Word document. When I insert the .JPEG and .GIF images (ten images of 25
| > Kb
| > | each) into my 30 page document programatically I end up with a file of
| > 7000
| > | Kb. When I insert the images by hand (Insert=>Picture=>From File...) I
| > end
| > | up with a file of only 310 Kb (a factor 22!). Isn't there a method to do
| > | programatically what I can do by hand?
| > |
| > | Note: I use VBA out of a Microsoft Access environment to generate
| > reports in
| > | Word.
| > |
| > | Any ideas a welcome, thanks!
| > |
| > | Vincent
| > |
| > |
| > | | > | > Thanks!
| > | >
| > | > This works fine! I have changed the routine a little to have *no* path
| > at
| > | > all in the linked field. This allows me to move the Word document
| > | > (together with the image files) to any folder I would like (or email
| > it to
| > | > someone else).
| > | >
| > | > Private Sub SetLinkedImagesLocalPath()
| > | > ' This routine sets the new path for external links.
| > | > ' The new path is empty: indicates that the external
| > | > ' link is in the same folder as the Word document.
| > | > Dim oRange As Word.Range
| > | > Dim oField As Word.Field
| > | > Dim OldPath As String
| > | > Dim NewPath As String
| > | > 'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
| > | > NewPath = vbNullString
| > | > ' Go through all story ranges in the document, including shapes,
| > | > ' headers & footers.
| > | > For Each oRange In ActiveDocument.StoryRanges
| > | > ' Go through the fields in the story range.
| > | > For Each oField In oRange.Fields
| > | > With oField
| > | > ' Skip over fields that don't have links to external images
| > | > If .Type = wdFieldIncludePicture Then
| > | > If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
| > | > ' Get the old <absolute> path
| > | > OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") & "\\"
| > | > Else
| > | > ' Get the old <relative> path
| > | > OldPath = .LinkFormat.SourcePath & "/"
| > | > End If
| > | > ' Replace the link to the external file
| > | > .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > | > End If
| > | > End With
| > | > Next oField
| > | > Next oRange
| > | > End Sub
| > | >
| > | >
| > | >
| > | > | > | >> Hi Vincent,
| > | >>
| > | >> There's two ways you could approach this problem.
| > | >>
| > | >> One way is to code the INCLUDEPICTURE fields so that they always look
| > in
| > | >> the current folder. To do this, each field would be coded
| > | >> along the lines of:
| > | >> { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
| > | >> where 'Filename.jpg' is the name of the picture file.
| > | >>
| > | >> Note that the field braces around 'filename \p' are created via
| > Ctrl-F9 -
| > | >> you can't just type them.
| > | >>
| > | >> If you have a lot of these to do, I'd suggest doing the first one,
| > | >> copying that field to all the remaining picture positions, then
| > | >> pressing Alt-F9 to expose all the field codes and changing the
| > filenames
| > | >> to suit. Delete the old fields as you go. When you're done,
| > | >> press Alt-F9 again to hide the field codes, then Alt-A to select the
| > | >> whole document and F9 to update all the fields.
| > | >>
| > | >> The same technique works with INCLUDETEXT, RD & HYPERLINK fields, but
| > not
| > | >> with LINK fields.
| > | >>
| > | >> The other way is to use a macro to automatically update the field
| > paths
| > | >> whenever the document is opened. The following macro updates
| > | >> INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.
| > | >>
| > | >> Option Explicit
| > | >> Dim TrkStatus As Boolean ' Track Changes flag
| > | >>
| > | >> Private Sub AutoOpen()
| > | >> ' This routine runs whenever the document is opened.
| > | >> ' It calls on the others to do the real work.
| > | >> ' Prepare the environment.
| > | >> Call MacroEntry
| > | >> ' Most of the work is done by this routine.
| > | >> Call UpdateFields
| > | >> ' Set the saved status of the document to true, so that changes via
| > | >> ' this code are ignored. Since the same changes will be made the
| > | >> ' next time the document is opened, saving them doesn't matter.
| > | >> ActiveDocument.Saved = True
| > | >> ' Go to the start of the document
| > | >> Selection.HomeKey Unit:=wdStory
| > | >> ' Clean up and exit.
| > | >> Call MacroExit
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroEntry()
| > | >> ' Store current Track Changes status, then switch off temporarily.
| > | >> With ActiveDocument
| > | >> TrkStatus = .TrackRevisions
| > | >> .TrackRevisions = False
| > | >> End With
| > | >> ' Turn Off Screen Updating temporarily.
| > | >> Application.ScreenUpdating = False
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroExit()
| > | >> ' Restore original Track Changes status
| > | >> ActiveDocument.TrackRevisions = TrkStatus
| > | >> ' Restore Screen Updating
| > | >> Application.ScreenUpdating = True
| > | >> End Sub
| > | >>
| > | >> Private Sub UpdateFields()
| > | >> ' This routine sets the new path for external links.
| > | >> Dim oRange As Word.Range
| > | >> Dim oField As Word.Field
| > | >> Dim OldPath As String
| > | >> Dim NewPath As String
| > | >> ' Set the new path
| > | >> NewPath = Replace$(ActiveDocument.Path, "\", "\\")
| > | >> ' Go through all story ranges in the document, including shapes,
| > | >> ' headers & footers.
| > | >> For Each oRange In ActiveDocument.StoryRanges
| > | >> ' Go through the fields in the story range.
| > | >> For Each oField In oRange.Fields
| > | >> With oField
| > | >> ' Skip over fields that don't have links to external files
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> ' Get the old path
| > | >> OldPath = Replace(.LinkFormat.SourcePath, "\", "\\")
| > | >> ' Replace the link to the external file
| > | >> .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > | >> End If
| > | >> End With
| > | >> Next oField
| > | >> Next oRange
| > | >> End Sub
| > | >>
| > | >> Amongst other things, the macro gives feedback on its progress.
| > | >>
| > | >> To make the macro update only INCLUDEPICTURE fields, you'd change the
| > | >> line:
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> to
| > | >> If .Type = wdFieldIncludePicture Then
| > | >>
| > | >> Cheers
| > | >>
| > | >> --
| > | >> macropod
| > | >> [MVP - Microsoft Word]
| > | >>
| > | >>
| > | >> | > | >> | Hello Group,
| > | >> |
| > | >> | I am able to generate a Word document using Visual Basic for
| > | >> Applications
| > | >> | with an InLine Shape that links to an external JPEG file. This
| > works
| > | >> fine as
| > | >> | long as the filename includes the full path
| > | >> | ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path ( like
| > | >> | "../../Folder3\MyPicture.jpg").
| > | >> |
| > | >> | Now I want to create an InLine Shape that links to an external JPEG
| > | >> file
| > | >> | that sits in the same folder as the document itself (whatever that
| > | >> folder
| > | >> | may be). This is because I want to send the document with JPEG to
| > | >> others
| > | >> | without having to include the image into the Word document: when I
| > do,
| > | >> the
| > | >> | Word document translates JPEG to BitMap and bloats to an
| > impractical
| > | >> size.
| > | >> |
| > | >> | I have tried the following code:
| > | >> |
| > | >> | Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
| > | >> MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| > | >> |
| > | >> | or
| > | >> |
| > | >> | Set oMyShape =
| > .InlineShapes.AddPicture(FileName:=MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False, Range:=.Selection.Range)
| > | >> |
| > | >> | The variable MyImageFileName is a String containing
| > "MyPicture.jpg"
| > | >> |
| > | >> | However, Word does not find the Image (that DOES exist in the same
| > | >> folder as
 
C

Cliff

Relative paths do not work reliably in Word fields. You should only use
absolute paths, so renaming directories is a no-no. (However, you could use
VBA to update paths when directories are renamed/files moved.)

Bill Schopper said:
First let me say you are my hero . . .

I write large appraisal reports with many linked photos and graphics with
Word 2003 all being contained in the same folder as the report to save
fiel
size. My work process is that while I am working on the report I am on
the
desktop and then file the folder when I am done. Many times I start with
a
previous appraisal similar to the one I am working on where many of the
graphics wil be the same. That has worked very well for years . . . until
some sort of Microsoft update, probably security

I was trying to figure out why my linked photos quit working when I copy
and
paste out of one report to another or change the folder name. The new
copy will refer to the old location and the photos in the old appraisal.
When I change the old folder's name the photos can not be found.

I have always kept the photos in the same folder as the word document and
all of the refernces are relative. I can inspect the links and they are
right, I can edit them and they will change to the curent location simply
by
putting mergformat at the end.

Macropod, is your code { INCLUDEPICTURE "{ filename
\p }\\..\\Filename.jpg}
correct? Should there be another "? Above where it says filename \p
should that be filename.jpg \p ?

Any ideas whre I am messing up.

Thank you,

Bill Schopper

macropod said:
Hi Vincent,

In that case, the field coding solution I posted should work fine. No
macros involved there.

Cheers

--
macropod
[MVP - Microsoft Word]


| Hi macropod,
|
| Thanks for your response. I double checked the way that I insert
pictures
| and I owe you an opology: I was using the .InlineShapes.AddOLEObject
method
| in that case, instead of the .InlineShapes.AddPicture method! Now that
I use
| the latter with LinkToFile = False and SaveWithDocument = True the
bloating
| issue is solved!
|
| Your VBA suggestion indeed works fine, as long as the VBA code is run
out of
| Word itself. What I wanted is a Word document without Marco (VBA) that
has
| 'local' links, i.e. without the mention of any path, assuming the
current
| document's path. Probably that is not possible.
|
| I create a Word document out of Ms Access using the Microsoft Word 11.0
| Object Library (located in C:\Program Files\Micrsoft
| Office\OFFICE11\MSWORD.OLB). I am using office 2003 as you can see. The
| result is a Word document without a macro. This is highly preferrable
| because of security standards not allowing Word Macros.
|
| Thanks again!
|
| Vincent
|
| | > Hi Vincent,
| >
| > I already gave you two quite workable solutions for automatically
updating
| > the links to the files.
| >
| > As for the file size with embedded images, Word 97 and later store
JPEG
| > images in JPEG format and converts all other raster formats
| > to a compressed PNG format. I experimented with inserting a 62kb png
image
| > and a 4kb gif image into an empty Word 2000 document and
| > Windows explorer reported a file size increases of only 62kb and 4Kb,
| > respectively - the same as the image sizes. I got exactly the
| > same results manually and with the VBA AddPicture method. Word 95 and
| > earlier stored all image data in an uncompressed form, which
| > would greatly increase the file size with any embedded image. Which
raises
| > the question - which version are you using?
| >
| > Cheers
| >
| > --
| > macropod
| > [MVP - Microsoft Word]
| >
| >
| > | > | Hmm,
| > |
| > | I was too quick, after a better test I found out that it doesn't
work:
| > | - The path in the linked image IS changed
| > | - but Word does not seem to use it
| > | - Word keeps a copy of the original Path and uses that one
| > |
| > | Inspecting the Word file with a plain text editor (like Notepad)
reveals
| > | that the original Path and Filename is stored at the very end of
the
| > | document. Testing with the image files present in one or the other
| > location
| > | indicates that Word still uses the original Path and Filename.
| > |
| > | Too bad!
| > |
| > | This takes the focus back on the real issue: inserting an image
using
| > the
| > | VBA method AddPicture results in a conversion to BitMap and a
hugely
| > bloated
| > | Word document. When I insert the .JPEG and .GIF images (ten images
of 25
| > Kb
| > | each) into my 30 page document programatically I end up with a file
of
| > 7000
| > | Kb. When I insert the images by hand (Insert=>Picture=>From
File...) I
| > end
| > | up with a file of only 310 Kb (a factor 22!). Isn't there a method
to do
| > | programatically what I can do by hand?
| > |
| > | Note: I use VBA out of a Microsoft Access environment to generate
| > reports in
| > | Word.
| > |
| > | Any ideas a welcome, thanks!
| > |
| > | Vincent
| > |
| > |
| > | | > | > Thanks!
| > | >
| > | > This works fine! I have changed the routine a little to have *no*
path
| > at
| > | > all in the linked field. This allows me to move the Word document
| > | > (together with the image files) to any folder I would like (or
email
| > it to
| > | > someone else).
| > | >
| > | > Private Sub SetLinkedImagesLocalPath()
| > | > ' This routine sets the new path for external links.
| > | > ' The new path is empty: indicates that the external
| > | > ' link is in the same folder as the Word document.
| > | > Dim oRange As Word.Range
| > | > Dim oField As Word.Field
| > | > Dim OldPath As String
| > | > Dim NewPath As String
| > | > 'NewPath = Replace(ActiveDocument.Path, "\", "\\") 'do not use
| > | > NewPath = vbNullString
| > | > ' Go through all story ranges in the document, including shapes,
| > | > ' headers & footers.
| > | > For Each oRange In ActiveDocument.StoryRanges
| > | > ' Go through the fields in the story range.
| > | > For Each oField In oRange.Fields
| > | > With oField
| > | > ' Skip over fields that don't have links to external
images
| > | > If .Type = wdFieldIncludePicture Then
| > | > If InStr(1, .LinkFormat.SourcePath, "\") > 0 Then
| > | > ' Get the old <absolute> path
| > | > OldPath = Replace(.LinkFormat.SourcePath, "\", "\\") &
"\\"
| > | > Else
| > | > ' Get the old <relative> path
| > | > OldPath = .LinkFormat.SourcePath & "/"
| > | > End If
| > | > ' Replace the link to the external file
| > | > .Code.Text = Replace(.Code.Text, OldPath, NewPath)
| > | > End If
| > | > End With
| > | > Next oField
| > | > Next oRange
| > | > End Sub
| > | >
| > | >
| > | >
| > | > | > | >> Hi Vincent,
| > | >>
| > | >> There's two ways you could approach this problem.
| > | >>
| > | >> One way is to code the INCLUDEPICTURE fields so that they always
look
| > in
| > | >> the current folder. To do this, each field would be coded
| > | >> along the lines of:
| > | >> { INCLUDEPICTURE "{ filename \p }\\..\\Filename.jpg}
| > | >> where 'Filename.jpg' is the name of the picture file.
| > | >>
| > | >> Note that the field braces around 'filename \p' are created via
| > Ctrl-F9 -
| > | >> you can't just type them.
| > | >>
| > | >> If you have a lot of these to do, I'd suggest doing the first
one,
| > | >> copying that field to all the remaining picture positions, then
| > | >> pressing Alt-F9 to expose all the field codes and changing the
| > filenames
| > | >> to suit. Delete the old fields as you go. When you're done,
| > | >> press Alt-F9 again to hide the field codes, then Alt-A to select
the
| > | >> whole document and F9 to update all the fields.
| > | >>
| > | >> The same technique works with INCLUDETEXT, RD & HYPERLINK
fields, but
| > not
| > | >> with LINK fields.
| > | >>
| > | >> The other way is to use a macro to automatically update the
field
| > paths
| > | >> whenever the document is opened. The following macro updates
| > | >> INCLUDEPICTURE, INCLUDETEXT, RD, HYPERLINK & LINK fields.
| > | >>
| > | >> Option Explicit
| > | >> Dim TrkStatus As Boolean ' Track Changes flag
| > | >>
| > | >> Private Sub AutoOpen()
| > | >> ' This routine runs whenever the document is opened.
| > | >> ' It calls on the others to do the real work.
| > | >> ' Prepare the environment.
| > | >> Call MacroEntry
| > | >> ' Most of the work is done by this routine.
| > | >> Call UpdateFields
| > | >> ' Set the saved status of the document to true, so that changes
via
| > | >> ' this code are ignored. Since the same changes will be made the
| > | >> ' next time the document is opened, saving them doesn't matter.
| > | >> ActiveDocument.Saved = True
| > | >> ' Go to the start of the document
| > | >> Selection.HomeKey Unit:=wdStory
| > | >> ' Clean up and exit.
| > | >> Call MacroExit
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroEntry()
| > | >> ' Store current Track Changes status, then switch off
temporarily.
| > | >> With ActiveDocument
| > | >> TrkStatus = .TrackRevisions
| > | >> .TrackRevisions = False
| > | >> End With
| > | >> ' Turn Off Screen Updating temporarily.
| > | >> Application.ScreenUpdating = False
| > | >> End Sub
| > | >>
| > | >> Private Sub MacroExit()
| > | >> ' Restore original Track Changes status
| > | >> ActiveDocument.TrackRevisions = TrkStatus
| > | >> ' Restore Screen Updating
| > | >> Application.ScreenUpdating = True
| > | >> End Sub
| > | >>
| > | >> Private Sub UpdateFields()
| > | >> ' This routine sets the new path for external links.
| > | >> Dim oRange As Word.Range
| > | >> Dim oField As Word.Field
| > | >> Dim OldPath As String
| > | >> Dim NewPath As String
| > | >> ' Set the new path
| > | >> NewPath = Replace$(ActiveDocument.Path, "\", "\\")
| > | >> ' Go through all story ranges in the document, including shapes,
| > | >> ' headers & footers.
| > | >> For Each oRange In ActiveDocument.StoryRanges
| > | >> ' Go through the fields in the story range.
| > | >> For Each oField In oRange.Fields
| > | >> With oField
| > | >> ' Skip over fields that don't have links to external
files
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> ' Get the old path
| > | >> OldPath = Replace(.LinkFormat.SourcePath, "\",
"\\")
| > | >> ' Replace the link to the external file
| > | >> .Code.Text = Replace(.Code.Text, OldPath,
NewPath)
| > | >> End If
| > | >> End With
| > | >> Next oField
| > | >> Next oRange
| > | >> End Sub
| > | >>
| > | >> Amongst other things, the macro gives feedback on its progress.
| > | >>
| > | >> To make the macro update only INCLUDEPICTURE fields, you'd
change the
| > | >> line:
| > | >> If Not .LinkFormat Is Nothing Then
| > | >> to
| > | >> If .Type = wdFieldIncludePicture Then
| > | >>
| > | >> Cheers
| > | >>
| > | >> --
| > | >> macropod
| > | >> [MVP - Microsoft Word]
| > | >>
| > | >>
| > | >> | > | >> | Hello Group,
| > | >> |
| > | >> | I am able to generate a Word document using Visual Basic for
| > | >> Applications
| > | >> | with an InLine Shape that links to an external JPEG file. This
| > works
| > | >> fine as
| > | >> | long as the filename includes the full path
| > | >> | ("C:\Folder1\Folder2\MyPicture.jpg") or a 'relative' path (
like
| > | >> | "../../Folder3\MyPicture.jpg").
| > | >> |
| > | >> | Now I want to create an InLine Shape that links to an external
JPEG
| > | >> file
| > | >> | that sits in the same folder as the document itself (whatever
that
| > | >> folder
| > | >> | may be). This is because I want to send the document with JPEG
to
| > | >> others
| > | >> | without having to include the image into the Word document:
when I
| > do,
| > | >> the
| > | >> | Word document translates JPEG to BitMap and bloats to an
| > impractical
| > | >> size.
| > | >> |
| > | >> | I have tried the following code:
| > | >> |
| > | >> | Set oMyShape = .InlineShapes.AddPicture(FileName:="/" &
| > | >> MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False,
Range:=.Selection.Range)
| > | >> |
| > | >> | or
| > | >> |
| > | >> | Set oMyShape =
| > .InlineShapes.AddPicture(FileName:=MyImageFileName,
| > | >> | LinkToFile:=True, SaveWithDocument:=False,
Range:=.Selection.Range)
| > | >> |
| > | >> | The variable MyImageFileName is a String containing
| > "MyPicture.jpg"
| > | >> |
| > | >> | However, Word does not find the Image (that DOES exist in the
same
| > | >> folder as
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top