replace picture in content control

A

Alex

Hi all.
How can I replace picture in content control without losing content
control's (picture) format? (MS Word 2007)

Thanx
 
J

Jay Freedman

Alex said:
Hi all.
How can I replace picture in content control without losing content
control's (picture) format? (MS Word 2007)

Thanx

If you just want to trigger the content control's Change Picture command and
let the user choose the picture, use something like this:

Sub x()
Dim cc As ContentControl
Set cc = ActiveDocument.ContentControls(1)
If cc.Type = wdContentControlPicture Then
'Debug.Print cc.Range.InlineShapes.Count
cc.Range.Select
Dialogs(wdDialogInsertPicture).Show
End If
End Sub

If you know what file you want to insert and just want to do the whole thing
in the macro, use something like this:

Sub y()
Dim cc As ContentControl
Set cc = ActiveDocument.ContentControls(1)
If cc.Type = wdContentControlPicture Then
If cc.Range.InlineShapes.Count > 0 Then
cc.Range.InlineShapes(1).Delete
End If
ActiveDocument.InlineShapes.AddPicture _
FileName:="e:\pictures\bunnycakes.jpg", _
linktofile:=False, Range:=cc.Range
End If
End Sub


--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
A

Alex

Thanks for your response, Jay.

I'm using C#, not VBA. Am I in wrong discussion group?

If I write code in C# similar to yours, then all picture format properties
(e.g. rotation, borders, shadows) are lost after shape.Delete() method.
I need to keep all formatting after the picture has been changed.
Thу only way I found is to copy properties from old shape to the new one.
But this method is not very nice. Besides, I can't find some properties (e.g
rotation angle).
 
J

Jay Freedman

Well, this is the word.VBA.general group. Questions about automating
Word from outside VBA are often posted to the word.programming group,
but there's certainly no enforceable rule.

You're correct about losing non-default formatting from the existing
picture, and that would happen in VBA as well -- I thought you were
concerned about losing the content control.

I don't see any alternative to copying the properties. Write it as a
separate subroutine, and once the work is done you just need to call
it as needed.

Getting the rotation of a picture in a content control is unreasonably
difficult. A picture in the control is an InlineShape, and in the
object model that type doesn't include a Rotation member. (This is a
case of VBA's object model lagging behind changes in the user
interface; in earlier versions you couldn't rotate an inline picture.)
VBA won't let you convert the InlineShape to a Shape. You have to copy
the picture and paste it to a place outside the content control, where
it can be converted to a Shape to get its Rotation value. Try this:

Sub z()
Dim oPic As InlineShape
Dim oShp As Shape
Dim oRg1 As Range, oRg2 As Range
Dim rot As Single

Set oPic = ActiveDocument.ContentControls(1) _
.Range.InlineShapes(1)
Set oRg1 = oPic.Range

' get a range outside the content control
Set oRg2 = ActiveDocument.ContentControls(1).Range
oRg2.Collapse wdCollapseEnd
oRg2.Move wdCharacter, 1

' copy the picture from the control and
' paste it outside the control
oRg1.Copy
oRg2.Paste

' make it a shape and find its rotation
Set oShp = oRg2.InlineShapes(1).ConvertToShape
rot = oShp.Rotation

' get rid of the leftovers
oShp.Delete
oPic.Delete

' put the new picture in the control
' and rotate it
Set oShp = ActiveDocument.Shapes.AddPicture _
(FileName:="c:\temp\jay headshot.jpg", _
Anchor:=oRg1)
oShp.Rotation = rot
End Sub
 
A

Alex

Thank you, Jay.
This code works perfect.

Jay Freedman said:
Well, this is the word.VBA.general group. Questions about automating
Word from outside VBA are often posted to the word.programming group,
but there's certainly no enforceable rule.

You're correct about losing non-default formatting from the existing
picture, and that would happen in VBA as well -- I thought you were
concerned about losing the content control.

I don't see any alternative to copying the properties. Write it as a
separate subroutine, and once the work is done you just need to call
it as needed.

Getting the rotation of a picture in a content control is unreasonably
difficult. A picture in the control is an InlineShape, and in the
object model that type doesn't include a Rotation member. (This is a
case of VBA's object model lagging behind changes in the user
interface; in earlier versions you couldn't rotate an inline picture.)
VBA won't let you convert the InlineShape to a Shape. You have to copy
the picture and paste it to a place outside the content control, where
it can be converted to a Shape to get its Rotation value. Try this:

Sub z()
Dim oPic As InlineShape
Dim oShp As Shape
Dim oRg1 As Range, oRg2 As Range
Dim rot As Single

Set oPic = ActiveDocument.ContentControls(1) _
.Range.InlineShapes(1)
Set oRg1 = oPic.Range

' get a range outside the content control
Set oRg2 = ActiveDocument.ContentControls(1).Range
oRg2.Collapse wdCollapseEnd
oRg2.Move wdCharacter, 1

' copy the picture from the control and
' paste it outside the control
oRg1.Copy
oRg2.Paste

' make it a shape and find its rotation
Set oShp = oRg2.InlineShapes(1).ConvertToShape
rot = oShp.Rotation

' get rid of the leftovers
oShp.Delete
oPic.Delete

' put the new picture in the control
' and rotate it
Set oShp = ActiveDocument.Shapes.AddPicture _
(FileName:="c:\temp\jay headshot.jpg", _
Anchor:=oRg1)
oShp.Rotation = rot
End Sub




.
 
A

Alex

Hi, Jay.
It seems that I hastened to the findings.
First of all, this code fails on some end user computers, but it doesn't on
my developer's machine.
I changed it as follows (C#):

InlineShape sh = ctrl.Range.InlineShapes[1];
Range rng1 = sh.Range;
rng2 = ctrl.Range;
object direction = WdCollapseDirection.wdCollapseEnd;
rng2.Collapse(ref direction);
int i = rng2.Move(ref unit, ref cnt);
rng1.Select(); //this line was added
Application.Selection.Copy();
rng2.Select(); //this line was added
rng2.Paste();
Shape shape = rng2.InlineShapes[1].ConvertToShape();

After adding range selection, the code started to work normally on other
computers.

But then I got another error:
If content control is located in the header (footer), then there is an
exception "Index refers beyond end of list." at:
rng2.InlineShapes[1].ConvertToShape();.

Should I use another way to manipulate content controls in header?

Thanks in advance.
 
S

sunil thomas

I was try to replace the picture in the content control. The content control was in the footer of the doc. The code given in the site works when the content control is not in footer.

The below code works even in the footer

ActiveDocument.SelectContentControlsByTag("newfooter").Item(1).Range.InlineShapes.Item(1).Delete
ActiveDocument.InlineShapes.AddPicture _
FileName:="C:\Sunil\Images\logo3.bmp", _
linktofile:=False, Range:=ActiveDocument.SelectContentControlsByTag("newfooter").Item(1).Range


Note: newfooter is the name of the picture content control.




Hi all.
How can I replace picture in content control without losing content
control's (picture) format? (MS Word 2007)

Thanx
If you just want to trigger the content control's Change Picture command and
let the user choose the picture, use something like this:

Sub x()
Dim cc As ContentControl
Set cc = ActiveDocument.ContentControls(1)
If cc.Type = wdContentControlPicture Then
'Debug.Print cc.Range.InlineShapes.Count
cc.Range.Select
Dialogs(wdDialogInsertPicture).Show
End If
End Sub

If you know what file you want to insert and just want to do the whole thing
in the macro, use something like this:

Sub y()
Dim cc As ContentControl
Set cc = ActiveDocument.ContentControls(1)
If cc.Type = wdContentControlPicture Then
If cc.Range.InlineShapes.Count > 0 Then
cc.Range.InlineShapes(1).Delete
End If
ActiveDocument.InlineShapes.AddPicture _
FileName:="e:\pictures\bunnycakes.jpg", _
linktofile:=False, Range:=cc.Range
End If
End Sub


--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
On Friday, February 05, 2010 2:53 AM Alex wrote:
Hi, Jay.
It seems that I hastened to the findings.
First of all, this code fails on some end user computers, but it does not on
my developer's machine.
I changed it as follows (C#):

InlineShape sh = ctrl.Range.InlineShapes[1];
Range rng1 = sh.Range;
rng2 = ctrl.Range;
object direction = WdCollapseDirection.wdCollapseEnd;
rng2.Collapse(ref direction);
int i = rng2.Move(ref unit, ref cnt);
rng1.Select(); //this line was added
Application.Selection.Copy();
rng2.Select(); //this line was added
rng2.Paste();
Shape shape = rng2.InlineShapes[1].ConvertToShape();

After adding range selection, the code started to work normally on other
computers.

But then I got another error:
If content control is located in the header (footer), then there is an
exception "Index refers beyond end of list." at:
rng2.InlineShapes[1].ConvertToShape();.

Should I use another way to manipulate content controls in header?

Thanks in advance.
 

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