PDA

View Full Version : [SLEEPER:] VBA Word msoBringToFront problem with inserting image at cursor's position



pedegascogne
02-08-2011, 07:39 AM
Hi.

I've got this problem.

I've done vba script which is supposed to insert an image at the position of the cursor AND bring this image to front.

That's my solutions.

If I do this :


Sub Macro1()
Selection.InlineShapes.AddPicture FileName:="C:\wetude\s.png", LinkToFile:=False, SaveWithDocument:=True
End Sub

The image is inserted at the current cursor's position


And when I do this :


Sub Macro2()
With ActiveDocument.Shapes.AddPicture(FileName:="C:\wetude\f.png", LinkToFile:=False)
.ZOrder msoBringToFront
End With
End Sub

The image is brang in front, but at the top of the page.


How can I mix those two ? I tried everything my noob brain can do. Each time, it's not working.

Please help :)

Tinbendr
02-08-2011, 05:52 PM
Welcome to VBA Express!

You're adding two different shapes.

Inlineshapes are on the Text layer while Shapes are on the Drawing layer.

From my research, you can't Zorder a InlineShape; only Shapes. But you can change from one shape to the other.

So, having stuck my neck out...


Sub Macro1()
With Selection.InlineShapes
.AddPicture FileName:="C:\wetude\s.png", LinkToFile:=False, _
SaveWithDocument:=True, Range:=Selection.Range
End With
With ActiveDocument
.InlineShapes(.InlineShapes.Count).ConvertToShape
With .Shapes(.Shapes.Count)
.ZOrder msoBringToFront
End With
End With
End Sub

David

pedegascogne
02-09-2011, 12:39 AM
Thank you very much for such a quick answer, you really helped me understanding the problem.

However, it persists. Indeed, the vba script works very weel when there is no image in the document... if they are some, that's what I get :

Error of execution '-2147467259 (80004005)'
The method 'ConvertToShape' of the 'Inline Shape' object have failed

In fact, the script tries to convert every shape in the document, instead of converting the one inserted...

Would you know what to do ?

Tinbendr
02-09-2011, 05:31 AM
Can you explain you are trying to accomplish? I know you're trying to put in a shape, but maybe describe the logic a little.

If you need a shape, then put a shape in and don't bother with Inlineshapes. I just wrote it that way to demonstrate options.

Can you post a small sample file?

pedegascogne
02-13-2011, 04:21 PM
Hey !

Thankyou for answer.

In fact, it's much simpler than what you're asking.

I'm just trying to write a macro, that insert an image at the cursor's position, and bring it to front.

As I told you, and I don't know how to put those actions together.

The code you wrote (and god, I'm thankful !) works fine, but if an image is already inserted somewhere in the word document, an error message appears.

pedegascogne
02-17-2011, 02:17 AM
Any answer ? Anybody have an idea ?

Frosty
02-17-2011, 10:58 AM
I'll take a crack at explaining:

Macro 1 is inserting the picture into the text layer (where all the words are)

Macro 2 is inserting the picture into the drawing layer (where most of the pictures are).

You don't need to "bring to front" for macro 1... no more than you need to tell a word you've just typed to be "in front" of the word you typed just before that word.

Macro 2 is totally different, as it does insert the picture into the drawing layer (which exists above and below the words), however, once you have a floating picture... it's no longer associated with some spot in between the words (i.e., your "cursor"). So you need to define where it is on the page.

Which, without getting really complicated for all the possibilities... kind of requires one of two things

1) you uploading some attachments so that we can figure out why you think the picture inserted from Macro 1 needs to be "brought to the front" (my guess is there is a *different* picture which needs to be "sent to back")

2) you giving a more full description of what you're really trying to accomplish.

Hope that helps.

Tinbendr
02-19-2011, 07:44 AM
Sorry for the delay. Just had to add the range for the shape.


Sub AddaPix()
With Selection.InlineShapes
.AddPicture FileName:="C:\wetude\s.png", LinkToFile:=False, _
SaveWithDocument:=True, Range:=Selection.Range
End With
With ActiveDocument
.InlineShapes(.InlineShapes.Count).ConvertToShape
With .Shapes.Range(.Shapes.Count)
.ZOrder msoBringToFront
End With
End With
End Sub

Frosty
02-19-2011, 12:53 PM
I think your code is going to cause problems if your cursor isn't at the end of the document, David.

You insert at the selection (which can be anywhere), and then convert whatever the last picture in the ActiveDocument.Shapes index is.

There are a number of scenarios where that code will break. It will work in a blank new document, but that's about the only guaranteed location.

I think the OP needs to give more info, or have a better understanding of coding to be able to use your solution.

pedegascogne
02-21-2011, 03:38 AM
Thank you for those replies, you're really spending some time explaining me and I can only appreciate your efforts.

I choose the second requierement, explaining in details.

It's not so complicated. In fact, I'm using Word everyday at the office. And I have to sign each document which is sent to me. Hundreds of them.

I just scanned my signature, erased the background, and now I'm trying to write this macro, that inserts it at the cursors position, and bring it to front, placing it above the text, and no next to it.

I hope it's not too hard, I understand what you exaplained it it seems complicated.

Thanks !

Tinbendr
02-21-2011, 05:56 AM
I have to do the very same thing, but I have four signature blocks.

What I did was create a table, fixed the table row height, then inserted the inlineshape. The nice thing about the fixed height is that the graphic automatically resizes to fit the cell.

Frosty
02-21-2011, 11:06 AM
Ah. You don't need something "in front" of something else... you need it above.

So you want it to look like this:

Sincerely,
[My Signature]
John Smith

Instead of...

Sincerely,
[My Signature]John Smith

Correct? I understand not wanting to upload an example document with your electronic signature for everyone to see.

I think you'll do just fine with the following:



Sub Macro1()
Selection.InlineShapes.AddPicture FileName:="C:\wetude\s.png", LinkToFile:=False, SaveWithDocument:=True
selection.InsertAfter vbcr
End Sub

Or you could just record the macro, stick with using inline shapes... but hit ENTER after the graphic is inserted, in order to "bring it above" your name.

You're confusing layers with order... the "bring to front" and "send to back" concept have to do with looking *down* at the page, as if you're looking at the top of the building in a satellite image and trying to describe the roof vs. the basement.

If, at this point, this is not what you need... try to upload a document with the signature block and just a fake graphic (scan an image of you writing out "hello", maybe).

The table idea is also great for images, especially since they automatically re-size (as David pointed out).

You can also look up the concept of "Autotext" or "Building Blocks" and look at just saving your electronic signature as that (depending on the version of Word you are using).

Hope that helps.

pedegascogne
02-22-2011, 04:01 AM
No problem I'll send you files by mp.

pedegascogne
02-22-2011, 04:33 AM
I have to post 4 messages to send an mp :)

pedegascogne
02-22-2011, 04:34 AM
Hate flooding, however... have to :banghead:

pedegascogne
02-22-2011, 04:35 AM
Only one post left... :dunno:

pedegascogne
02-22-2011, 04:36 AM
Done.

I'm REALLY SORRY... :aw:

Tinbendr
02-22-2011, 09:51 AM
OK, I fired up my 2003 and this seems to work.

This also corrects the problem Frosty addressed with multiple shapes in the document.


Sub AddaPix()
Dim MyInline As InlineShape
Dim MyShape As Shape
With Selection.InlineShapes
Set MyInline = .AddPicture(FileName:="C:\wetude\s.png", LinkToFile:=False, _
SaveWithDocument:=True, Range:=Selection.Range)
End With
With ActiveDocument
Set MyShape = MyInline.ConvertToShape
With MyShape
.ZOrder msoBringToFront
End With
End With
End Sub

Frosty
02-22-2011, 10:47 AM
Sometimes what seems simple with Microsoft just isn't. This is actually harder in concept than it looks-- you have to insert as an inline shape first in order to get any sort of cursor position information. And I am dubious as to how well this will work, however here is my code (which is really not that much different, substance-wise, than David's).

The difference with my code is that it will move the picture upward and to the right (which is what I think you want), as well as deal with multiple selection scenarios (if you have multiple paragraphs selected and run David's code, I think those paragraphs will get deleted-- something I accidentally ran across while writing the code.



Public Sub InsertImageAtCursor()
Dim sImagePath As String
Dim shp As Shape
Dim shpInline As InlineShape
Dim rngWhere As Range
'where your image is
sImagePath = "F:\Consulting\Development\m.png"
'get the current selection
Set rngWhere = Selection.Range.Duplicate
'collapse the range, to prevent issues with a non-insertion cursor
rngWhere.Collapse wdCollapseEnd
'get our inline shape
Set shpInline = rngWhere.InlineShapes.AddPicture(sImagePath, , , rngWhere)
'convert it to a floating shape
Set shp = shpInline.ConvertToShape
'lock the anchor, so that it stays associated with the paragraph it was inserting with
shp.LockAnchor = True
'adjust to behind text (which I think you want, instead of infront of text)
'you can replace with msoBringInFrontOfText if desired
shp.ZOrder msoSendBehindText
'adjust it up
shp.Top = shp.Top - 55
'and to the right
shp.Left = shp.Left + 25
End Sub

However, I think this could all be simplified and not be a custom macro at all if you were to look up AutoText and QuickParts. And with the added benefit of having it more easily accessible from the User Interface under the Quick Parts gallery.

Learning about autotext will help you with a lot of "macro" problems.

pedegascogne
02-23-2011, 06:10 AM
Thanks for quality replies !

However, still, same error message for your two propositions. And on two different computers. The second time, it never works...

pedegascogne
02-23-2011, 06:49 AM
Tested on 2 computers...

Frosty
02-23-2011, 08:35 AM
As suspected, much more complicated than it seems.

The code would not fail if you inserted anywhere but at the bottom of the page. Word is becoming confused when the *only* reason for a new page is the recently inserted graphic. I get around this by making the graphic very very small, and then restoring the size.

However-- this code can still break in some scenarios.

If the below does not work for you... you need to look up an autotext solution. Autotext would be a trivial solution for this problem, and it is a good skill to have.

Good luck.


Public Sub InsertImageAtCursor()
Dim sImagePath As String
Dim shp As Shape
Dim shpInline As InlineShape
Dim rngWhere As Range
Dim lOrigHeight As Long
Dim lOrigWidth As Long

'where your image is
sImagePath = "C:\wetude\s.png"

'get the current selection
Set rngWhere = Selection.Range.Duplicate
'collapse the range, to prevent issues with a non-insertion cursor
rngWhere.Collapse wdCollapseEnd

'get our inline shape
Set shpInline = rngWhere.InlineShapes.AddPicture(sImagePath, , , rngWhere)

'store the original height/width
lOrigHeight = shpInline.Height
lOrigWidth = shpInline.Width

'make it really really tiny, to prevent page changing before the conversion
shpInline.Height = 0.1
shpInline.Width = 0.1

'convert it to a floating shape
Set shp = shpInline.ConvertToShape

'restore the height/width
shp.Height = lOrigHeight
shp.Width = lOrigWidth

'adjust to behind text (which I think you want, instead of infront of text)
'you can replace with msoBringInFrontOfText if desired
shp.ZOrder msoSendBehindText

'adjust it up (change this to move it around)
shp.Top = shp.Top - 55

'and to the right (move this around as needed)
shp.Left = shp.Left - 100
End Sub