Bookmarks inside text box to insert text or pictures

R

RMac

Using Word 2000.

I am building a document that I want to use to generate written
prescriptions for medicines. In order to control the exact placement of some
text and graphics on the page, I would like to use textboxes. However, when
I use the following code to do the insertion, the code can't find the
bookmarks that are inside a textbox.

In the instance of inserting text (for the final version of code, sBoxVal
and sMark are set from controls on a UserForm):

Sub Macro3()
Dim sBoxVal As String, sMark As String

sBoxVal = "SomeDrugName"
sMark = "DrugName"
Call FillMark(sMark, sBoxVal)

End Sub

Sub FillMark(sMark As String, sBoxVal As String)
'Go to bookmark and transfer the data.
Selection.GoTo What:=wdGoToBookmark, Name:=sMark
Selection.Range.Text = sBoxVal
End Sub

In the instance of inserting a graphic (in this case a .bmp of a signature
that will vary depending on what doctor is writing the prescription):

Sub Macro2()

'Go to Signature bookmark
Selection.GoTo What:=wdGoToBookmark, Name:="Signature"
'Insert Signature
Selection.InlineShapes.AddPicture FileName:= _
ThisDocument.Path & "\JPM Signature.bmp" _
, LinkToFile:=False, SaveWithDocument:=True

End Sub

Both of these approaches seem to work if I am using bookmarks in the main
body of the document. I have discovered through fiddling around that if I
click on the desired textbox before running the macro so that it has the
focus before the macro runs the insertion works just fine. So, I think it
might work if I could figure out how to set the focus on the correct textbox
programatically.

Thanks in advance
 
R

RMac

Greg Maxey said:
I wouldn't try to use GoTo. Try something like:

Sub Test()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Bookmarks("sMark").Range
oRng.Text = "Your Text"
ActiveDocument.Bookmarks.Add "sMark", oRng
End Sub


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~...atically. Thanks in advance[/QUOTE] [/QUOTE]
 
S

sparklynic

In the past I have used "advance" to exactly position text on a page when I
needed to fill forms in. Perhaps this could be used instead of text boxes.
Just a suggestion.

Sparklynic
___________________________
 
R

RMac

I thought the same thing. I sense the vibe of a former Wordperfect user.
However, the advance feature in Word 2000 seems only to provide the ability
to advance relative to the current position. WP provided the capability to
advance to a specific position on the page--a much more rigorous solution
that Word apparently did not see fit to include.

For better or worse, a text box appears to be the best way to lock something
in a specific place on the page. My problem was that the selection.goto
method of going to a bookmark couldn't find a bookmark in a text box unless
the bookmark had focus in the document. Actually, I found the solution to
this question in a posted response by Greg Maxey to another question. The
trick is to figure out what Word is calling the text box in question; then
rename it something memorable and finally use code to set the focus on the
desired textbox containing the bookmark of interest before trying to place
the inline graphic or text where you want it.

The following code is adapted from Greg's post:

Go to page view of the document and click on the box you're interested in
and then run the following macro. A message box will pop up with Word's ID
number for the text box: eg. TextBox(20). If you run the macro again the new
name will show up in the Message Box.

Sub ShapeID()

MsgBox Selection.ShapeRange.Name
'Or give it your own name
Selection.ShapeRange.Name = "WhateverYouWant"

End Sub

Finally I put the following line of code immediately before the
selection.goto statement for the bookmark inside the TextBox where I want to
insert text (or inline graphic):

'Set the focus on the "WhateverYouWant" textbox
ActiveDocument.Shapes("WhateverYouWant").Select

This seems to work reliably as far as I can tell, however I am intrigued by
this stuff on "Ranges" Greg was referring to in his post to me. I see that a
post I tried to make in response to him somehow got lost. I will repost.

Anyway, thanks for your response, "sparklynic".
 
G

Greg Maxey

RMac,

I was trying to show you that there is no need to "GoTo" anywhere. You can
achieve your objective by leaving the selection alone by using the range
object. TestBM1 and TestBM2 are located in textboxes:

Sub Macro3()
Dim sBoxVal As String, sMark As String
sBoxVal = "SomeDrugName"
sMark = "TestBM1"
Call FillMark(sMark, sBoxVal)
End Sub

Sub FillMark(sMark As String, sBoxVal As String)
Dim oRng As Range
Set oRng = ActiveDocument.Bookmarks(sMark).Range
oRng.Text = sBoxVal
ActiveDocument.Bookmarks.Add sMark, oRng
End Sub

Sub Macro2()
Dim oRng As Range
Set oRng = ActiveDocument.Bookmarks("TestBM2").Range
ActiveDocument.InlineShapes.AddPicture "C:\Pic.bmp", False, True, oRng
End Sub

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

RMac

Thanks for your response, Greg;

If you read my response to "sparklynic" you'll see that, by using a
suggestion you posted to another question, I was able to identify and rename
the textbox containing the sought for bookmark. I then programatically
select the textbox; and using the selection.goto method, place the text or
graphic where I need them.

Having said that, I'm wondering if there is some inherent weakenss in the
approach I used, which is:

1. Giving the document user a UserForm with a bunch of comboboxes and text
entry controls that they manipulate to get the selections they want, then;

2. Taking those selections piece by piece--control by control, and using
the I-Beam, placeholder type bookmarks and the selection.goto method,
inserting the bits into the document.

I have to say that it was a little annoying to find that the bookmarks
inside the textboxes were invisible to my program until I set focus on the
textbox. Since the textboxes are the last things that get filled, I haven't
had to try to go back into the main document. Maybe that would be a problem.
I'm not sure.

Anyway, if you think the approach you suggest below would be more robust, I
am interested in learning more about it. Can you suggest some MVP papers or
other sources that discuss the basics of using .range in the way you are
suggesting?

By the way, I've seen oRng used as a variable in other bits of code
examples. What does the 'o' stand for?

One question on the code you sent below: In my usage, sMark is a string
variable that carries the name of a bookmark that marks an insertion point in
the document. "sBoxVal" is another string variable that contains the choice
the user has selected from a UserForm control. sMark and sBoxVal change with
each new bookmark to be filled and get passed to my subroutine "FillMark"
(from my original post) to do the actual insertion. If I understand
correctly, your code would look for a bookmark in the document literally
called "sMark". In my case, should sMark and sBoxVal, having previously been
dimensioned as string variables, be used without the quotes as follows?

Sub Test()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Bookmarks(sMark).Range
oRng.Text = sBoxVal
ActiveDocument.Bookmarks.Add sMark, oRng
End Sub

One other question: If the bookmark I'm trying to access is inside a
textbox, would your code below be able to find it if the textbox does not
have focus?

Thanks again for your help.

Bob


Greg Maxey said:
I wouldn't try to use GoTo. Try something like:

Sub Test()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Bookmarks("sMark").Range
oRng.Text = "Your Text"
ActiveDocument.Bookmarks.Add "sMark", oRng
End Sub


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~...atically. Thanks in advance[/QUOTE] [/QUOTE]
 
R

RMac

Thanks again Greg,

Our posts crossed in the ether or somewhere, you've addressed here most the
issues I asked in my post of a few minutes ago. One burning question
remains: What does the 'o' in oRng stand for? :)

Also do you have any suggestions for reading (MVP papers etc) on the basics
of using the range object?

Greg Maxey said:
RMac,

I was trying to show you that there is no need to "GoTo" anywhere. You can
achieve your objective by leaving the selection alone by using the range
object. TestBM1 and TestBM2 are located in textboxes:

Sub Macro3()
Dim sBoxVal As String, sMark As String
sBoxVal = "SomeDrugName"
sMark = "TestBM1"
Call FillMark(sMark, sBoxVal)
End Sub

Sub FillMark(sMark As String, sBoxVal As String)
Dim oRng As Range
Set oRng = ActiveDocument.Bookmarks(sMark).Range
oRng.Text = sBoxVal
ActiveDocument.Bookmarks.Add sMark, oRng
End Sub

Sub Macro2()
Dim oRng As Range
Set oRng = ActiveDocument.Bookmarks("TestBM2").Range
ActiveDocument.InlineShapes.AddPicture "C:\Pic.bmp", False, True, oRng
End Sub

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~...our response, "sparklynic". [/QUOTE] [/QUOTE]
 
G

Greg Maxey

RMac,

There is an apparent time lag between our postings and I hope my previous
post clears up some of your quesitons.

As for "oRng." I am a novice VBA user without any formal training and some
of my code probably appalls the purists. I pick up bits and pieces of what
the masters use but I can never keep it all straight. I do know that
"range" is an object and I often use a camelback convention in defining
variables (e..g, oRng as Range, strText as String, bGate as Boolean). You
might look up something like "VBA variable naming convention" in Google to
get more scoop on this.

I think in most intances using a range rather than a selection is more
efficient. I can't give you the technical reasons, but I generally feel
there is no reason to move the selection if you don't need to.

Say you have a bookmark in a Textbox called "TestBM"

You could write text after that bookmark simply with:

Sub ScratchMacro()
ActiveDocument.Bookmarks("TestBM").Range.InsertAfter "Your Text Here"
End Sub

That works, but if you run the code again you will have "Your Text HereYour
Text Here" in the textbox.

If you use this instead then you write your text "in" or enclosed by the
bookmark range. If you run the same code a second time the the text won't
repeat.

Sub ScratchMacro()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Bookmarks("TestBM").Range
oRng.Text = "Your Text Here"
ActiveDocument.Bookmarks.Add "TextBM", oRng
End Sub


Yes, as I illustrated in my last post since "TestBM" and "Your Text Here"
are passed as varibles in your code then they would be entered without the
"".




--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~~~~~~~~~~~~
 
G

Greg Maxey

RMac,

Yes we are in a time warp ;-)

The "o" in my crude and often inconsistent coding represents an "object"
data type.

Here are some notes someone sent to me a few years ago:

First of all, learn to love Ranges. You can only have one Selection at
atime, but as many Ranges defined as you like, in as many different
documentsas you have open. A Range has many of the attributes of the
Selection. Mostof the methods that can be applied to the Selection can also
be applied to aRange variable. To start out on this, take a relatively small
macro that you have writtenusing the Selection. Put the following line at
the start Dim MyRange as RangeSet MyRange = Selection.Range That defines a
range object variable called MyRange, and sets it so that itis located at
the same position as the current selection. Then, wherever you have a line
of code that says Selection.something,replace it with MyRange.something. You
may get some compile errors when you first run the macro, so take a lookand
see what the problem is. Most likely you have used the Homekey method tomove
you to the top of the document, or something like that which can't bedone
with a Range. There is almost always a way of doing the same thing. Inthis
case, this has the same effect MyRange.Move Unit:=wdStory, Count:=-1 Once
you have got used to the idea of using one Range variable instead ofthe
Selection, you can start getting more ambitious. If you need aplaceholder
that you will go back to later in the macro, define a Range forit. If you
want to transfer unformatted text between two places (or evenbetween two
documents), then you can find out that the text is at one placeby using the
Text property of the Range, and insert it at the destinationusing the
InsertAfter method of the destination range. Something like thiswould
achieve that effect MyNewRange.InsertAfter Text:=MyOldRange.Text Almost
everything within a document has a Range, so you don't necessarilyneed to
define a Range variable. If you know that you want to set thecontents of the
second cell of the third row of the first table in thedocument, then you can
do it this way ActiveDocument.Tables(1).Cell(3, 2).Range.Text = "My new
text" Finally, you can copy *formatted* text within and between documents
withoutthe clipboard, by making use of the FormattedText property. This
example copies the text and formatting from the selection into a
newdocument. Set myRange =
Selection.FormattedTextDocuments.Add.Content.FormattedText = myRange Ranges
have a number of advantages over the Selection. 1. They are usually faster
to work with. When you move a Range variable, thescreen doesn't update in
order to display where the Range has moved to. Thissaves time. Also, when
you start working on a Range in a different document,you don't have to
activate that document first. 2. You can have many of them scattered among
several open documents, and itseasy to keep track of things using them.
There are a few occasions there the Selection has an advantage, where aRange
won't really do. 1. If you want to use the predefined bookmarks such as
/Page or/HeadingLevel. These are always defined relative to the Selection.
2. If you want to move up or down one line (as apposed to one paragraph)
orwant to identify the current line of text. 3. If you want to use some
items returned by the Information property.Getting the position of some text
on the page seems to work a bit morereliably with the Selection than with a
Range. 4. In Word 97, using the Selection to do a Find is noticeably faster
thanusing a Range variable. In Word 2000, the speed is about the same. I
haven'tyet checked Word 2002 to see what the relative performance is.

You might try a Google Search in the Word VBA support group "Range vs
Selection" or Selection vs Range" for some more discusion.



--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

RMac

Thanks again (again),

I see now the logic behind your suggestion. Thanks for taking the time to
illuminate. I'll keep on the trail of the illusive 'o'.

Bob
_______________________________

Greg Maxey said:
RMac,

There is an apparent time lag between our postings and I hope my previous
post clears up some of your quesitons.

As for "oRng." I am a novice VBA user without any formal training and some
of my code probably appalls the purists. I pick up bits and pieces of what
the masters use but I can never keep it all straight. I do know that
"range" is an object and I often use a camelback convention in defining
variables (e..g, oRng as Range, strText as String, bGate as Boolean). You
might look up something like "VBA variable naming convention" in Google to
get more scoop on this.

I think in most intances using a range rather than a selection is more
efficient. I can't give you the technical reasons, but I generally feel
there is no reason to move the selection if you don't need to.

Say you have a bookmark in a Textbox called "TestBM"

You could write text after that bookmark simply with:

Sub ScratchMacro()
ActiveDocument.Bookmarks("TestBM").Range.InsertAfter "Your Text Here"
End Sub

That works, but if you run the code again you will have "Your Text HereYour
Text Here" in the textbox.

If you use this instead then you write your text "in" or enclosed by the
bookmark range. If you run the same code a second time the the text won't
repeat.

Sub ScratchMacro()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Bookmarks("TestBM").Range
oRng.Text = "Your Text Here"
ActiveDocument.Bookmarks.Add "TextBM", oRng
End Sub


Yes, as I illustrated in my last post since "TestBM" and "Your Text Here"
are passed as varibles in your code then they would be entered without the
"".




--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~...s again for your help. Bob [/QUOTE] [/QUOTE]
 

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