Pastespecial problem

P

Piou2fois

Hi all

I was looking for a script able to decrease the word file size with a
lot of pictures.
I found the possibility to use cut and pastespecial as jpg
here is the script i use :

Function cut_paste_as_jpg(image As InlineShape) As Boolean
image.Select
question = (MsgBox("Do you want toconvert this picture?",
vbYesNoCancel, "Convert to jpg"))
Select Case question
Case vbYes
Selection.CopyAsPicture
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True
Case vbNo
cut_paste_as_jpg = True
Exit Function
Case vbCancel
cut_paste_as_jpg = False
End Select
End Function

Sub jpg_mass_convert()
Dim image As InlineShape
For Each image In ActiveDocument.InlineShapes
If Not cut_paste_as_jpg(image) Then Exit Sub
Next image
End Sub

This script is great for all inlineshape and you can win size

Big problem is that with this method, each picture has 2 problems
-a 1px black border below and right of the picture
-paste as something which is not inlineshape (picture is in edit mode)

do you think there is something to do avoid these two problems, because
for the first point it is horrible to see that, and for the second one,
I cannot put border on the picture with macro.

Thank you in advance for your attention

Regards
Guillaume MASSART (FRANCE)
 
J

Jean-Guy Marcil

Piou2fois was telling us:
Piou2fois nous racontait que :
Hi all

I was looking for a script able to decrease the word file size with a
lot of pictures.
I found the possibility to use cut and pastespecial as jpg
here is the script i use :

Function cut_paste_as_jpg(image As InlineShape) As Boolean
image.Select
question = (MsgBox("Do you want toconvert this picture?",
vbYesNoCancel, "Convert to jpg"))
Select Case question
Case vbYes
Selection.CopyAsPicture
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True
Case vbNo
cut_paste_as_jpg = True
Exit Function
Case vbCancel
cut_paste_as_jpg = False
End Select
End Function

Sub jpg_mass_convert()
Dim image As InlineShape
For Each image In ActiveDocument.InlineShapes
If Not cut_paste_as_jpg(image) Then Exit Sub
Next image
End Sub

This script is great for all inlineshape and you can win size

Big problem is that with this method, each picture has 2 problems
-a 1px black border below and right of the picture
-paste as something which is not inlineshape (picture is in edit mode)

do you think there is something to do avoid these two problems,
because for the first point it is horrible to see that, and for the
second one, I cannot put border on the picture with macro.

I do not get the border problem you described (Word 2003). Maybe it has to
do with your pictures themselves.

Try the following code for handling both inline and floating pictures. Make
sure that you handle floating pictures first because even though the jpg are
pasted as inline and will behave as such, Word will see them as floating
shapes (They are shape fields). So, if you handle the floating shapes after
the inline ones, the inline that were converted the first time around will
be converted again.

Also, remember that if you convert a floating shape to an inline one, it
will move from its floating position to the first character position in the
paragraph were it will be inline based on the paragraph that used to hold
the floating shape anchor before the conversion.

Finally, I had to delete the inline/floating shapes, otherwise they were all
doubled up...

'_______________________________________
Option Explicit

'_______________________________________
Function cut_paste_as_jpg(image As Object) As Boolean

Dim question As Variant

image.Select
question = (MsgBox("Do you want to convert this picture?", _
vbYesNoCancel, "Convert to jpg"))
Select Case question
Case vbYes
Selection.CopyAsPicture
Selection.Delete
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True
Case vbNo
cut_paste_as_jpg = True
Case vbCancel
cut_paste_as_jpg = False
End Select

End Function
'_______________________________________

'_______________________________________
Sub jpg_mass_convert()
Dim StartRange As Range
Dim image As InlineShape
Dim pix As Shape

Set StartRange = Selection.Range
Selection.Collapse

For Each pix In ActiveDocument.Shapes
If pix.Type = msoPicture Then
If Not cut_paste_as_jpg(pix) Then Exit Sub
End If
Next

For Each image In ActiveDocument.InlineShapes
If Not cut_paste_as_jpg(image) Then Exit Sub
Next

StartRange.Select

End Sub
'_______________________________________

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
P

Piou2fois

Thank for the shape, i do not use shape in my word document, so i did
not transform them :)
Just for copy and delete, you can cut
Selection.CopyAsPicture
Selection.Delete
->
Selection.Cut
I stille have the black border below and right of the picture, inside
the picture, so if i transform the picture 10times i will have big
black border on my pictures...
I do not know what could be the issue for that, if you do not have this
problem, it could be due to my system...
I will see if I can continue to improve this script, to get the
position of shape and give them to the new one (jpg)

Thank you for the StartRange, it is useful
 
J

Jean-Guy Marcil

Piou2fois was telling us:
Piou2fois nous racontait que :
Thank for the shape, i do not use shape in my word document, so i did
not transform them :)

So, in your original post, what did you mean by:

"-paste as something which is not inlineshape (picture is in edit mode)"

Weren't you referring to floating pictures? If so, those are shapes, not
inlineshapes.
If you meant selecting an inline shape and pasting it as a floating one,
then I am sorry, I misunderstood your question.
Change the value of the Placement argument in:

Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine

so as to have:

Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdFloatOverText

and remove the first loop.

Just for copy and delete, you can cut
Selection.CopyAsPicture
Selection.Delete
->
Selection.Cut

I am a bit confused by that.
In your original post, you posted the following code:

Selection.CopyAsPicture
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True

I just pointed out that on my machine, this code left the original picture
in the document, which seemed to go against your intention with the code
(This same code did not leave the original picture in the document on your
machine?).
So I suggested the following code just to stay as close as possible to your
original post:

Selection.CopyAsPicture
Selection.Delete
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True

If you knew all along that:

Selection.CopyAsPicture
Selection.Delete

can be replaced by

Selection.Cut

why did you not use it?
I stille have the black border below and right of the picture, inside
the picture, so if i transform the picture 10times i will have big
black border on my pictures...

Remember also that by forcing the jpg format on the picture, Word as to
convert it from whatever format it was before. For example, if I run your
code with a GIF that had a transparent background, the resulting picture
will look very different as the JPG format does not support the
transparency. In fact, chances are that the background will become black. So
you maybe running into something like this.
Finally, keep in mind that by using 15 as a datatype (JPG) your are forcing
Word to insert a jpg, which it does not normally do. Word is not a good
picture handler. To see what I mean, run your code and then do ALT-F9 in
your document. You will see a bunch of {SHAPE \* MERGEFORMAT} in lieu of
the pictures. This is a very difficult beast to handle that leads to all
kinds of problems. One problem is that as a field it will not be pasted
"floating", so the "wdFloatOverText " I suggested earlier will not work with
15 as a datatype. If you manually convert the picture to floating, it will
work.

So, you could try using this

For Each pix In ActiveDocument.Shapes
pix.WrapFormat.Type = wdWrapNone
Next

at the end of the code, just before the

StartRange.Select

line.

But you will have the positioning problem instead....

So, there might be a better approach that is altogether very different to
the one you are attempting now.

If you want to ask about that, I would suggest that you start a new thread
explaining your goal, the type of content in the document, what you have
tried so far and the problems you have encountered.

Good luck!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
P

Piou2fois

Hello
Concerning the ".cut" it was a mistake, i wanted to use .cut
I finally find that shapes can be converted to inlineshape with
For Each pix In ActiveDocument.Shapes
pix.ConvertToInlineShape
Next
I always use inlineshape in my documents, because it is easier for
presentation (caption add) so i want to finally have inlineshape
So with that solution i have inline shape (but with black border
problem anyway) but i have something crazy, new pictures appeared.
here is the script i use
########
Function cut_paste_as_jpg(image As Object, all As Integer) As Boolean
Select Case all
Case vbYes
image.Select
Selection.CopyAsPicture
Selection.Delete
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True
Case vbNo
Dim question As Variant
image.Select
question = (MsgBox("Do you want to convert this picture?", _
vbYesNoCancel, "Convert to jpg"))
Select Case question
Case vbYes
Selection.CopyAsPicture
Selection.Delete
Selection.PasteSpecial Link:=False, _
DataType:=15, _
Placement:=wdInLine
cut_paste_as_jpg = True
Case vbNo
cut_paste_as_jpg = True
Case vbCancel
cut_paste_as_jpg = False
End Select
End Select
End Function
Sub jpg_mass_convert()
Dim StartRange As Range
Dim image As InlineShape
Dim pix As Shape
Dim choice As Integer
Set StartRange = Selection.Range
Selection.Collapse
choice = (MsgBox("Do you want to convert all pictures?", vbYesNo,
"Massive convertion"))
For Each pix In ActiveDocument.Shapes
If pix.Type = msoPicture Then
If Not cut_paste_as_jpg(pix, choice) Then Exit Sub
End If
Next
For Each image In ActiveDocument.InlineShapes
If Not cut_paste_as_jpg(image, choice) Then Exit Sub
Next
For Each pix In ActiveDocument.Shapes
pix.ConvertToInlineShape
Next
StartRange.Select
End Sub
########
Each time it creates some kind of double from original pictures, but
grey...
Do you have the same problem ?
 
J

Jean-Guy Marcil

Piou2fois was telling us:
Piou2fois nous racontait que :
Each time it creates some kind of double from original pictures, but
grey...
Do you have the same problem ?

Yes, I have seen that. This is caused by what I mentionned in my last post:

<quote>
Finally, keep in mind that by using 15 as a datatype (JPG) your are forcing
Word to insert a jpg, which it does not normally do. Word is not a good
picture handler. To see what I mean, run your code and then do ALT-F9 in
your document. You will see a bunch of {SHAPE \* MERGEFORMAT} in lieu of
the pictures. This is a very difficult beast to handle that leads to all
kinds of problems. One problem is that as a field it will not be pasted
"floating", so the "wdFloatOverText " I suggested earlier will not work with
15 as a datatype. If you manually convert the picture to floating, it will
work.
<end quote>

Another problem is that "doubling", which can be especially troublesome if
the picture is in table or if the document is opened in an earlier version
of Word.
The only way out is not to past as jpg, but as metafile.(or something
equivalent). I do not know if it will help with size reducing though..

Let us know!

Another solution would be to export all the picture and batch treat them
with a picture software like IrfanView, not in Word.
--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 

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