How can I add a jpg image to a word document on a predifined position

P

Philip De Vos

How can I add a jpg image to a word document on a predifined position
and how can I select images in a word document

I would like to replace the image in a document by an
automatically generated jpg
How can I do this ?

thank for you assistance
 
M

Mark Tangard

Philip,

To add a JPG at a specific position:

ActiveDocument.Shapes.AddPicture FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22

To select the last one added:

ActiveDocument.Shapes(ActiveDocument.Shapes.Count).Select

But to add one and select it then OR later (most convenient),

Dim s as Shape, picname as String
Set s = ActiveDocument.Shapes. _
AddPicture(FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22)
picname = s.Name

(Note the slightly different syntax in the AddPicture, with the
parentheses in this scenario.)

To locate a specific image without it being recently added or
selected, you need to know something about it that VBA can grab,
for example, its anchor. You can test the range of the anchor
to see if it matches a range VBA knows about. This can get
complicated, so post back with more details on exactly what
will be known about the picture you need to replace.
 
F

fedum

Hey,
I'm allso have some problems with pictures in Word. I have
the path (it can be more than one) in the textdocument.
Then I change this path with the picture as an
Inlineshape. But then my problem: how can i change this
pictures to a position and that the text is wraped around.
I have tryed to covert to a Shape but he only takes the
first picture. Maybe Mark can help!
My code:
Sub FindPicAndInsert()
Dim picrange As Range, piclength As Integer, PicNr As
Long, Counter As Long
PicNr = 0
'Dim MyField As Field
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find '"C:\\[A-z 0-9\\]{1,}.[A-z]{3}"
Do While .Execute(FindText:="<(C:\\)(*)(\\*)(.jpg)
", MatchWildcards:=True, Wrap:=wdFindStop, Forward:=True)
= True
Set picrange = Selection.Range
PicNr = PicNr + 1
picrange.Select
If i = 0 Then
Selection.Collapse wdCollapseEnd
Selection.MoveRight wdCharacter, 1
End If
piclength = Len(picrange)
For i = piclength To 1 Step -1
If Mid(picrange, i, 1) = "\" Then
picrange = Left(picrange, i - 1) & "\"
& Mid(picrange, i)
i = i - 2
End If
Next i
ActiveDocument.Fields.Add Range:=picrange,
Type:=wdFieldEmpty, Text:= _
"INCLUDEPICTURE " & Chr(34) & picrange & Chr(34),
PreserveFormatting:=False

'Scale the picture
ActiveDocument.InlineShapes(PicNr).ScaleHeight = 30
ActiveDocument.InlineShapes(PicNr).ScaleWidth = 30

Loop

End With
'covert, place the picture
For Counter = 1 To PicNr - 2
ActiveDocument.InlineShapes(Counter).ConvertToShape

With ActiveDocument.Shapes(Counter)
.RelativeVerticalPosition =
wdRelativeVerticalPositionPage
.Top = CentimetersToPoints(4)
.Left = CentimetersToPoints(15)
.LockAnchor = False
.WrapFormat.AllowOverlap = True
.WrapFormat.Side = wdWrapBoth
.WrapFormat.Type = wdWrapSquare

End With
Next Counter


End Sub

Regards,
Marc Franssen.
-----Original Message-----
Philip,

To add a JPG at a specific position:

ActiveDocument.Shapes.AddPicture
FileName:="C:\path\filename.jpg", _
 
M

Mark Tangard

Hi Marc,

The problem is with your last loop. Each time you convert
an InlineShape to a Shape, the InlineShapes *collection*
(which is what your loops iterates through) changes -- it
gets smaller. So at about the halfway point the loop will
blow up. That is, if you're looping through 100 pictures
as InlineShapes and converting each one during the loop,
after you convert the 50th one, there's only 50 left, so
so the "next" one (InlineShape #51) doesn't exist.

(It's actually even worse than that, because when you take
away InlineShape #1, the old #3 is the new #2, and so on;
so the loop would skip every other picture and convert
only those that were originally odd-numbered. Let's not
even go there!)

The usual way we fix something like that, something that
*removes* members of a collection while you loop through
them, is by iterating backward:

For i = SomeCollection.Count To 1 Step -1

But that doesn't fix it all here. In your loop, when you
set out to change the properties of the resulting Shape,
you address it by the loop counter. We can't do that now
because we're counting backwards to avoid having the loop
bite off its own toes; the Shapes collection is growing
while the counter is shrinking.

To fix that, we could diddle with the icky subtraction to
still use the loop counter get the right subscripts for
the newly produced Shapes. But why? There's no reason
to address the evolving collection of Shapes just to tweak
the attributes of each member. So I'd just set an object
variable to each new Shape as it's created, use *it* to
adjust the attributes, and reuse it each time the loop
repeats, as shown below:

Dim sh As Shape
:
:
:
For Counter = PicNr - 2 To 1 Step -1
Set sh = ActiveDocument.InlineShapes(Counter).ConvertToShape
With sh
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = CentimetersToPoints(4)
.Left = CentimetersToPoints(15)
.LockAnchor = False
.WrapFormat.AllowOverlap = True
.WrapFormat.Side = wdWrapBoth
.WrapFormat.Type = wdWrapSquare
End With
Next Counter
End Sub

Another advantage to this is that the shape-tweaking in this
section would be done only to the converted pictures and not
to any other Shapes that also happened to be in the document
originally.

(You'll want to edit the 'For' line to accommodate whatever
it is you were doing with the "-2" there, which I couldn't
discern.)

Two other things:

1. Don't add a new question to an existing thread, especially
one that's resolved or nearly so. It increases the chance
it'll be missed.

2. When you show your code, if you distill it to just the
relevant portion rather than just shoveling the whole macro
into the post, you'll get a faster answer because whoever
looks at it won't have to spend the extra time sifting out
the irrelevant sections (and will also be less likely to
say, well, gee that's too big a mess to bother untangling
just now, I'll go find a simpler, neater question...).

--
Mark Tangard <[email protected]>, Microsoft Word MVP
Please reply only to the newsgroup, not by private mail.
Note well: MVPs do not work for Microsoft.
"Life is nothing if you're not obsessed." --John Waters



Hey,
I'm allso have some problems with pictures in Word. I have
the path (it can be more than one) in the textdocument.
Then I change this path with the picture as an
Inlineshape. But then my problem: how can i change this
pictures to a position and that the text is wraped around.
I have tryed to covert to a Shape but he only takes the
first picture. Maybe Mark can help!
My code:
Sub FindPicAndInsert()
Dim picrange As Range, piclength As Integer, PicNr As
Long, Counter As Long
PicNr = 0
'Dim MyField As Field
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find '"C:\\[A-z 0-9\\]{1,}.[A-z]{3}"
Do While .Execute(FindText:="<(C:\\)(*)(\\*)(.jpg)
", MatchWildcards:=True, Wrap:=wdFindStop, Forward:=True)
= True
Set picrange = Selection.Range
PicNr = PicNr + 1
picrange.Select
If i = 0 Then
Selection.Collapse wdCollapseEnd
Selection.MoveRight wdCharacter, 1
End If
piclength = Len(picrange)
For i = piclength To 1 Step -1
If Mid(picrange, i, 1) = "\" Then
picrange = Left(picrange, i - 1) & "\"
& Mid(picrange, i)
i = i - 2
End If
Next i
ActiveDocument.Fields.Add Range:=picrange,
Type:=wdFieldEmpty, Text:= _
"INCLUDEPICTURE " & Chr(34) & picrange & Chr(34),
PreserveFormatting:=False

'Scale the picture
ActiveDocument.InlineShapes(PicNr).ScaleHeight = 30
ActiveDocument.InlineShapes(PicNr).ScaleWidth = 30

Loop

End With
'covert, place the picture
For Counter = 1 To PicNr - 2
ActiveDocument.InlineShapes(Counter).ConvertToShape

With ActiveDocument.Shapes(Counter)
.RelativeVerticalPosition =
wdRelativeVerticalPositionPage
.Top = CentimetersToPoints(4)
.Left = CentimetersToPoints(15)
.LockAnchor = False
.WrapFormat.AllowOverlap = True
.WrapFormat.Side = wdWrapBoth
.WrapFormat.Type = wdWrapSquare

End With
Next Counter

End Sub

Regards,
Marc Franssen.
-----Original Message-----
Philip,

To add a JPG at a specific position:

ActiveDocument.Shapes.AddPicture
FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22

To select the last one added:

ActiveDocument.Shapes(ActiveDocument.Shapes.Count).Select

But to add one and select it then OR later (most convenient),

Dim s as Shape, picname as String
Set s = ActiveDocument.Shapes. _
AddPicture(FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22)
picname = s.Name

(Note the slightly different syntax in the AddPicture, with the
parentheses in this scenario.)

To locate a specific image without it being recently added or
selected, you need to know something about it that VBA can grab,
for example, its anchor. You can test the range of the anchor
to see if it matches a range VBA knows about. This can get
complicated, so post back with more details on exactly what
will be known about the picture you need to replace.

--
Mark Tangard <[email protected]>, Microsoft Word MVP
Please reply only to the newsgroup, not by private email.
Note well: MVPs do not work for Microsoft.
"Life is nothing if you're not obsessed." --John Waters




.
 
F

fedum

Hi Mark
Thanks for your professional explonation. I will try this
out. I have learned and understand now why it went wrong.
Thanks.

-----Original Message-----

Hi Marc,

The problem is with your last loop. Each time you convert
an InlineShape to a Shape, the InlineShapes *collection*
(which is what your loops iterates through) changes -- it
gets smaller. So at about the halfway point the loop will
blow up. That is, if you're looping through 100 pictures
as InlineShapes and converting each one during the loop,
after you convert the 50th one, there's only 50 left, so
so the "next" one (InlineShape #51) doesn't exist.

(It's actually even worse than that, because when you take
away InlineShape #1, the old #3 is the new #2, and so on;
so the loop would skip every other picture and convert
only those that were originally odd-numbered. Let's not
even go there!)

The usual way we fix something like that, something that
*removes* members of a collection while you loop through
them, is by iterating backward:

For i = SomeCollection.Count To 1 Step -1

But that doesn't fix it all here. In your loop, when you
set out to change the properties of the resulting Shape,
you address it by the loop counter. We can't do that now
because we're counting backwards to avoid having the loop
bite off its own toes; the Shapes collection is growing
while the counter is shrinking.

To fix that, we could diddle with the icky subtraction to
still use the loop counter get the right subscripts for
the newly produced Shapes. But why? There's no reason
to address the evolving collection of Shapes just to tweak
the attributes of each member. So I'd just set an object
variable to each new Shape as it's created, use *it* to
adjust the attributes, and reuse it each time the loop
repeats, as shown below:

Dim sh As Shape
:
:
:
For Counter = PicNr - 2 To 1 Step -1
Set sh = ActiveDocument.InlineShapes (Counter).ConvertToShape
With sh
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = CentimetersToPoints(4)
.Left = CentimetersToPoints(15)
.LockAnchor = False
.WrapFormat.AllowOverlap = True
.WrapFormat.Side = wdWrapBoth
.WrapFormat.Type = wdWrapSquare
End With
Next Counter
End Sub

Another advantage to this is that the shape-tweaking in this
section would be done only to the converted pictures and not
to any other Shapes that also happened to be in the document
originally.

(You'll want to edit the 'For' line to accommodate whatever
it is you were doing with the "-2" there, which I couldn't
discern.)

Two other things:

1. Don't add a new question to an existing thread, especially
one that's resolved or nearly so. It increases the chance
it'll be missed.

2. When you show your code, if you distill it to just the
relevant portion rather than just shoveling the whole macro
into the post, you'll get a faster answer because whoever
looks at it won't have to spend the extra time sifting out
the irrelevant sections (and will also be less likely to
say, well, gee that's too big a mess to bother untangling
just now, I'll go find a simpler, neater question...).

--
Mark Tangard <[email protected]>, Microsoft Word MVP
Please reply only to the newsgroup, not by private mail.
Note well: MVPs do not work for Microsoft.
"Life is nothing if you're not obsessed." --John Waters



Hey,
I'm allso have some problems with pictures in Word. I have
the path (it can be more than one) in the textdocument.
Then I change this path with the picture as an
Inlineshape. But then my problem: how can i change this
pictures to a position and that the text is wraped around.
I have tryed to covert to a Shape but he only takes the
first picture. Maybe Mark can help!
My code:
Sub FindPicAndInsert()
Dim picrange As Range, piclength As Integer, PicNr As
Long, Counter As Long
PicNr = 0
'Dim MyField As Field
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find '"C:\\[A-z 0-9\\]{1,}.[A-z]{3}"
Do While .Execute(FindText:="<(C:\\)(*)(\\*) (.jpg)
", MatchWildcards:=True, Wrap:=wdFindStop,
Forward:=True)
= True
Set picrange = Selection.Range
PicNr = PicNr + 1
picrange.Select
If i = 0 Then
Selection.Collapse wdCollapseEnd
Selection.MoveRight wdCharacter, 1
End If
piclength = Len(picrange)
For i = piclength To 1 Step -1
If Mid(picrange, i, 1) = "\" Then
picrange = Left(picrange, i - 1) & "\"
& Mid(picrange, i)
i = i - 2
End If
Next i
ActiveDocument.Fields.Add Range:=picrange,
Type:=wdFieldEmpty, Text:= _
"INCLUDEPICTURE " & Chr(34) & picrange & Chr (34),
PreserveFormatting:=False

'Scale the picture
ActiveDocument.InlineShapes(PicNr).ScaleHeight = 30
ActiveDocument.InlineShapes(PicNr).ScaleWidth = 30

Loop

End With
'covert, place the picture
For Counter = 1 To PicNr - 2
ActiveDocument.InlineShapes (Counter).ConvertToShape

With ActiveDocument.Shapes(Counter)
.RelativeVerticalPosition =
wdRelativeVerticalPositionPage
.Top = CentimetersToPoints(4)
.Left = CentimetersToPoints(15)
.LockAnchor = False
.WrapFormat.AllowOverlap = True
.WrapFormat.Side = wdWrapBoth
.WrapFormat.Type = wdWrapSquare

End With
Next Counter

End Sub

Regards,
Marc Franssen.
-----Original Message-----
Philip,

To add a JPG at a specific position:

ActiveDocument.Shapes.AddPicture
FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22

To select the last one added:

ActiveDocument.Shapes (ActiveDocument.Shapes.Count).Select

But to add one and select it then OR later (most convenient),

Dim s as Shape, picname as String
Set s = ActiveDocument.Shapes. _
AddPicture(FileName:="C:\path\filename.jpg", _
Left:=22, Top:=22)
picname = s.Name

(Note the slightly different syntax in the AddPicture, with the
parentheses in this scenario.)

To locate a specific image without it being recently added or
selected, you need to know something about it that VBA can grab,
for example, its anchor. You can test the range of the anchor
to see if it matches a range VBA knows about. This can get
complicated, so post back with more details on exactly what
will be known about the picture you need to replace.

--
Mark Tangard <[email protected]>, Microsoft Word MVP
Please reply only to the newsgroup, not by private email.
Note well: MVPs do not work for Microsoft.
"Life is nothing if you're not obsessed." --John Waters




Philip De Vos wrote:

How can I add a jpg image to a word document on a predifined position
and how can I select images in a word document

I would like to replace the image in a document by an
automatically generated jpg
How can I do this ?

thank for you assistance
.
.
 
W

Word Heretic

G'day "Philip De Vos" <[email protected]>,

stick a bookmark where you want the picture. replace that range with a
document.inlineshapes.add ...


Philip De Vos said:
How can I add a jpg image to a word document on a predifined position
and how can I select images in a word document

I would like to replace the image in a document by an
automatically generated jpg
How can I do this ?

thank for you assistance

Steve Hudson

Word Heretic, Sydney, Australia
Tricky stuff with Word or words for you.
Email (e-mail address removed)
Products http://www.geocities.com/word_heretic/products.html

Replies offlist may require payment.
 

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