Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Enclosing Bookmarks with VBA

246 views
Skip to first unread message

Rick

unread,
Apr 10, 2003, 11:54:55 AM4/10/03
to
I would like to insert bookmarks using VBA and have them
be enclosing bookmarks so that they could be retrieveable
and text can be changed if necessary through VBA.
According to:
http://www.mvps.org/word/FAQs/MacrosVBA/WorkWithBookmarks.h
tm
you have to use something like what's below to recreate
the bookmark after inserting text because the bookmark is
actually deleted after text insertion
Dim bmRange As Range

Set bmRange = ActiveDocument.Bookmarks("myBookmark").Range
bmRange.Text = "Inserted Text"
ActiveDocument.Bookmarks.Add Name:="myBookmark", _
Range:=bmRange

I've tried doing this without success. My latest try is
below. All I get with this code is the bookmark text added
twice and both bookmarks are deleted.

Please help. Using Word 97 if it matters.

For p = 1 to 10
SampleDesc = "SampleDesc" + Str(p)
'This creates SampleDesc + a space & a number
'Bookmarks can only be 1 word (no spaces)
TextSpace = InStr(SampleDesc, " ")
'Determines length of name up to the space
RightOfSpace = Len(SampleDesc) - TextSpace
TextSpace = TextSpace - 1
SampleDescRight = Right(SampleDesc, RightOfSpace)
SampleDescLeft = Left(SampleDesc, TextSpace)
SampleDesc = SampleDescLeft + SampleDescRight
'******* Create Bookmark in Document ************
ActiveDocument.Bookmarks.Add Name:=SampleDesc
Set bmRange4 = ActiveDocument.Bookmarks
(SampleDesc).Range
With bmRange4
MyVar = "SamDes" + Str(p)
'Sets up MyVar with DocProperty name
Descrip = ActiveDocument.CustomDocumentProperties
(MyVar)
.InsertBefore "Sample ID: " + Descrip
'Inserts Sample ID from loop p
.ParagraphFormat.Alignment =
wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack
.Collapse
Direction:=wdCollapseEnd 'Collapse's field
Selection.EndKey unit:=wdStory, Extend:=wdMove
End With
'***** Try to reset Bookmark *****
Set bmRange4 = ActiveDocument.Bookmarks
(SampleDesc).Range
SampleText = "Sample ID: " + Descrip
bmRange.Text = SampleText
ActiveDocument.Bookmarks.Add Name:=SampleDesc
Next p

Dave Lett

unread,
Apr 10, 2003, 12:12:59 PM4/10/03
to
Hi Rick,

The following routine will add ten paragraphs, text, and enclosing
bookmarks:

Dim iCount As Integer
Dim oRng As Range

For iCount = 1 To 10
Set oRng = ActiveDocument.Range
With oRng
.Collapse Direction:=wdCollapseEnd
.text = "SampleDesc" & iCount
ActiveDocument.Bookmarks.Add Name:="SampleDesc" & iCount,
Range:=oRng
.InsertAfter vbCrLf
End With
Next iCount

The routine that you mentioned (from the MVP site) is excellent for changing
the text of an existing bookmark, but it was not intended to be used as you
want. Perhaps the above routine gives you an idea how you might modify your
approach.

HTH

"Rick" <rgwi...@buckman.com> wrote in message
news:072e01c2ff79$87d1bb30$a601...@phx.gbl...

Rick

unread,
Apr 10, 2003, 2:33:33 PM4/10/03
to
Dave,
Thanks for the quick response. I've tried merging your
code into mine. However, I'm still not quite there. The
loop I have actually sets 3 bookmarks (1. some text, 2.
the SampleDesc and 3. some more text). Then there is
another loop (1 through 10) that goes through these three
items again where only the SampleDesc changes (thus the p
variable in the code). Anyway, during the last loop, the
Bookmark becomes enclosed only at the last entry within
each outside loop. I need it to be enclosed at all of the
SampleDesc bookmarks. Let me know if you need any other
info (or the code) for the outside loops. Thanks again for
any assistance you can provide.

Here's what I have by merging your code with mine:

Set bmRange4 = ActiveDocument.Range
With bmRange4


.Collapse
Direction:=wdCollapseEnd 'Collapse's field

MyVar = "SamDes" + Str(p) 'Sets up MyVar
with DocProperty name
Descrip =
ActiveDocument.CustomDocumentProperties(MyVar)

SampleText = "Sample ID: " + Descrip

bmRange4.Text = SampleText


.ParagraphFormat.Alignment =
wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack
.Collapse
Direction:=wdCollapseEnd 'Collapse's field

ActiveDocument.Bookmarks.Add SampleDesc,
bmRange4
.InsertAfter vbCrLf


Selection.EndKey unit:=wdStory, Extend:=wdMove
End With

>.
>

Dave Lett

unread,
Apr 10, 2003, 3:27:03 PM4/10/03
to
Hi Rick,

Let's take a step back to see if we can figure out 1) what you're trying to
do and 2) why the routine you have isn't working. Let's start with a plain
English description of what you want to accomplish. Are you trying the
following:

For iLoop = 1 to 3
Set a bookmark.
Next iLoop

For iLoop 1 to 10
Change a value in the bookmark SampleDesc.
Next iLoop

OR are you trying the following:

For iOuterLoop = 1 to 3
set a bookmark
For iInnerLoop = 1 to 10
Change a value in the bookmark SampleDesc.
Next iInnerLoop
Next iOuterLoop

As you can see, I don't quite get your goal. Also, you mention an inner and
outer loop, but I haven't seen one in your routine.

"Rick" <rgwi...@buckman.com> wrote in message

news:056901c2ff8f$b0ef6380$a001...@phx.gbl...

Rick

unread,
Apr 10, 2003, 5:26:10 PM4/10/03
to
The code is below. As you can see, I am setting up each
sample for 10 tests each. The sample description gets
printed between the HeadText and the TextParagraph.

Is there a better way to accomplish this?
Here are the loops.


For p = 1 To SampleNum 'SampleNum is the number of samples
For i = 1 To 10 '10 is the number of separate
tests we can do per sample.
45 Selection.TypeParagraph
ActiveDocument.Bookmarks.Add Name:="HeadText"
'HeadText is test type
Set bmRange3 = ActiveDocument.Bookmarks
("HeadText").Range
With bmRange3
.InsertAfter HeadText(i) 'Inserts
Header Text
.ParagraphFormat.Alignment =
wdAlignParagraphCenter


.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack
.Collapse
Direction:=wdCollapseEnd 'Collapse's field
Selection.EndKey unit:=wdStory, Extend:=wdMove
End With

Selection.TypeParagraph
Selection.TypeParagraph
'***** Next section I'm trying to get Enclosing bookmarks
so that if necessary
'***** I can change sample descriptions at a later time.


SampleDesc = "SampleDesc" + Str(p) 'This creates
SampleDesc + a space & a number
'Bookmarks can
only be 1 word (no spaces)
TextSpace = InStr(SampleDesc, " ") 'Determines length
of name up to the space
RightOfSpace = Len(SampleDesc) - TextSpace
TextSpace = TextSpace - 1
SampleDescRight = Right(SampleDesc, RightOfSpace)
SampleDescLeft = Left(SampleDesc, TextSpace)
SampleDesc = SampleDescLeft + SampleDescRight

Set bmRange4 = ActiveDocument.Range
With bmRange4
.Collapse
Direction:=wdCollapseEnd 'Collapse's field
MyVar = "SamDes" + Str(p) 'Sets up MyVar
with DocProperty name
Descrip =
ActiveDocument.CustomDocumentProperties(MyVar)
SampleText = "Sample ID: " + Descrip
bmRange4.Text = SampleText
.ParagraphFormat.Alignment =
wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack
.Collapse
Direction:=wdCollapseEnd 'Collapse's field
ActiveDocument.Bookmarks.Add SampleDesc,
bmRange4
.InsertAfter vbCrLf
Selection.EndKey unit:=wdStory, Extend:=wdMove
End With

Selection.TypeParagraph
'****** End of Sample Description Bookmark entry
ActiveDocument.Bookmarks.Add Name:="TextParagraph"
'Predetermined text about test
Set bmRange5 = ActiveDocument.Bookmarks
("TextParagraph").Range
With bmRange5
.InsertBefore ParaText(i) 'Inserts
Paragraph Text


.ParagraphFormat.Alignment =
wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10

.Font.Bold = False


.Font.ColorIndex = wdBlack
.Collapse
Direction:=wdCollapseEnd 'Collapse's field
Selection.EndKey unit:=wdStory, Extend:=wdMove
End With

Selection.TypeParagraph
Next i
Next p

>.
>

Dave Lett

unread,
Apr 11, 2003, 9:15:18 AM4/11/03
to
Hi Rick,

This modified routine creates a document that looks something like the
following:


Heading1

Sample ID: SamDes1

1

Heading2

Sample ID: SamDes2

2

Where "Sample ID: SamDes1" and "Sample ID: SamDes1" have enclosing bookmarks
named "SamDes1" and "SamDes2", respectively. To get it working as you want,
you will need to uncomment the lines where you get information from your
custom document properties.

SampleNum = 2
HeadText = "Heading"

For p = 1 To SampleNum 'SampleNum is the number of samples
For i = 1 To 10 '10 is the number of separate tests we can do
per sample.

Selection.TypeParagraph
Set bmRange3 = Selection.Range
With bmRange3
.InsertAfter HeadText & i 'Inserts Header text


.ParagraphFormat.Alignment = wdAlignParagraphCenter
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack

.Collapse Direction:=wdCollapseEnd 'Collapses range
End With
With Selection
.EndKey unit:=wdStory, Extend:=wdMove
.TypeParagraph
.TypeParagraph
End With


'***** Next section I'm trying to get Enclosing bookmarks

'***** so that if necessary


'***** I can change sample descriptions at a later time.

SampleDesc = "SampleDesc" + Trim(Str(p)) 'This creates SampleDesc &
a number

Set bmRange4 = ActiveDocument.Range
With bmRange4

.Collapse Direction:=wdCollapseEnd 'Collapses range
' I changed this to "i" so that the sample
' description would provide a unique bookmark name
myVar = "SamDes" + Trim(Str(i)) 'Sets up MyVar with


DocProperty name
''' Descrip = ActiveDocument.CustomDocumentProperties(MyVar)

Descrip = myVar


SampleText = "Sample ID: " + Descrip

.text = SampleText
' I moved this so that we could have a unique
' bookmark name
ActiveDocument.Bookmarks.Add myVar, bmRange4


.ParagraphFormat.Alignment = wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = True
.Font.ColorIndex = wdBlack

.Collapse Direction:=wdCollapseEnd 'Collapses range
.InsertAfter vbCrLf
End With
With Selection
.EndKey unit:=wdStory, Extend:=wdMove
.TypeParagraph
End With


'****** End of Sample Description Bookmark entry
ActiveDocument.Bookmarks.Add Name:="TextParagraph"
'Predetermined text about test

Set bmRange5 = ActiveDocument.Bookmarks("TextParagraph").Range
With bmRange5
.InsertBefore ParaText & i 'Inserts Paragraph text


.ParagraphFormat.Alignment = wdAlignParagraphLeft
.Font.Name = "Arial"
.Font.Size = 10
.Font.Bold = False
.Font.ColorIndex = wdBlack

.Collapse Direction:=wdCollapseEnd 'Collapses range
End With
With Selection
.EndKey unit:=wdStory, Extend:=wdMove
.TypeParagraph
End With
Next i
Next p

You can also make your routine if you create a subroutine/function to format
each of your range objects. That is, a lot of the code to format your range
object is identical, and the part that isn't identical can be passed to a
subroutine so that you don't have to repeat a lot your code. For example,
you might explore something like the following:

For p = 1 To SampleNum 'SampleNum is the number of samples
For i = 1 To 10 '10 is the number of separate tests we can do
per sample.

Selection.TypeParagraph
Set bmRange3 = Selection.Range
fFormatRange _
oRng:=bmRange3, _
sText:=HeadText & i, _
iAlignment:=wdAlignParagraphCenter, _
bBold:=True, _
iTrailParas:=2
................. and so on

Public Function fFormatRange(oRng As Range, sText As String, iAlignment As
Integer, bBold As Boolean, iTrailParas As Integer)
With oRng
.InsertAfter sText 'Inserts Header text
.ParagraphFormat.Alignment = iAlignment


.Font.Name = "Arial"
.Font.Size = 10

.Font.Bold = bBold
.Font.ColorIndex = wdBlack
End With
With Selection
.EndKey unit:=wdStory, Extend:=wdMove
.TypeParagraph
If iTrailParas = 2 Then
.TypeParagraph
End If
End With
End Function

HTH

"Rick" <rgwi...@buckman.com> wrote in message

news:014501c2ffa7$ce61ea60$a601...@phx.gbl...

Rick

unread,
Apr 11, 2003, 10:13:05 AM4/11/03
to
Thanks but it's not quite correct yet. I changed your
myVar = "SamDes" + Trim(Str(i))back to myVar = "SamDes" +
Trim(Str(p))since the p loop is sample specific instead of
test specific. Just to clarify, the Str(i)) you used sets
up different bookmarks 1 through 10 for each sample p. I
was using Str(p) because all of the bookmarks per sample
should be the same. Sample 1 has 10 duplicate bookmark1's,
sample 2 has 10 duplicate bookmark2's, etc.

Here is what I'm after:

Heading1

Sample ID: SamDes1

1

Heading2

Sample ID: SamDes1

2

Heading3

SampleID: SamDes1

3

etc. through Heading10 Then

Heading1

SampleID: SamDes2

1

Heading2

SampleID: SamDes2

2

etc. through Heading10

Can't I have multiple SamDes1's and they are be enclosed
in Bookmarks or do they have to be unique? Currently the
code only makes SamDes10 an enclosed bookmark.

Also, thanks for the concise code:
MyVar = "SamDes" + Trim(Str(p))

It's lots prettier than by parsing <BG>

Rick

>.
>

Dave Lett

unread,
Apr 11, 2003, 10:42:02 AM4/11/03
to
Hi Rick,

Bookmark names _must_ be unique. When you add your bookmark name, you can
concatenate p & i to make it unique.

HTH

"Rick" <rgwi...@buckman.com> wrote in message

news:028201c30034$788705c0$3401...@phx.gbl...

Rick

unread,
Apr 11, 2003, 12:52:37 PM4/11/03
to
I was afraid of that. However, I now have it working -
THANKS!

If I need to change a description in the
CustomDocumentProperty, does it have to be deleted first
and then recreated?

How do I update the SamDes bookmarks after a change is
made to the CustomDocumentProperty? A user may actually
delete one (or more)of the tests for one (or more)samples
so the bookmark count for 1 particular sample may be 9 or
5 or etc.


Rick

>.
>

Dave Lett

unread,
Apr 11, 2003, 12:59:28 PM4/11/03
to
Hi Rick,

No, you don't have to delete a custom doc property to change its value (have
a look at the .Value property in the VBA help file).

Update the SamDes bookmark? Update the contents of the bookmark or change
the name of the bookmark.
To change the contents of the bookmark, use the code from the article
"Inserting text at a bookmark without deleting the bookmark" at
http://www.mvps.org/word/FAQs/MacrosVBA/InsertingTextAtBookmark.htm

To change the name of the bookmark, you can simply use something like the
following:
With ActiveDocument
' add a new bookmark name for an existing bookmark
.Bookmarks.Add Name:="NewBkmk",
Range:=ActiveDocument.Bookmarks("test").Range
' remove the original bookmark
.Bookmarks("test").Delete
End With

HTH

"Rick" <rgwi...@buckman.com> wrote in message

news:045001c3004a$c1abd670$2f01...@phx.gbl...

Rick

unread,
Apr 11, 2003, 2:49:32 PM4/11/03
to
Sorry I wasn't clear about updating the bookmark. I meant
change the contents with the data in the changed
CustomDocumentProperty.

Lets say the document has the following bookmarks:
(SamDes plus the first number is the
CustomDocumentProperty name and the last number is the
bookmark # associated with that variable)

All with data from SamDes1 CustomDocumentProperty
SamDes11
SamDes12
SamDes13
SamDes14

All with data from SamDes2 CustomDocumentProperty
SamDes21
SamDes22
SamDes23


Using input boxes (I can do this part - I Hope!) a user
changes the data in CustomDocumentProperty SamDes2. All
SamDes2 bookmarks need to be changed. I think I can get it
to work with the reference you gave. I'll just loop
through the 10 iterations even though only 3 exist. I'll
need to do this because the 3 used may be SamDes22,
SamDes26 and SamDes210 (or any 3 of the 10). Since any
particular bookmark may or may not exist should I check to
see if it exists in my loop that will go through SamDes21,
SamDes22, SamDes23, ..... SamDes10 before trying to
replace it? How would I check for the existance of a
Bookmark?

For i = 1 to 10

' Part I am unclear about how to do
Check to see if SamDes2(i) exists
If no next i
' End Part

MyVar = SamDes2 'Sets up MyVar with
'CustomDocumentProperty Name
MyVarBK = MyVar + Trim(Str(i))
Set BMRange = ActiveDocument.Bookmarks(MyVarBK).Range

Descrip = ActiveDocument.CustomDocumentProperties(MyVar)
SampleText = "Sample ID: " + Descrip

.Text = SampleText
ActiveDocument.Bookmarks.Add MyVarBK, BMRange
Next i


Sorry to take so much of your time but you're really
helping.

Rick


>-----Original Message-----
>Hi Rick,
>

>.
>

Dave Lett

unread,
Apr 11, 2003, 3:11:02 PM4/11/03
to
Hi Rick,

I'm starting to have serious doubts that you should be using bookmarks at
all. Have you explored simply using the { DocProperty } field and updating
your fields as needed?

"Rick" <rgwi...@buckman.com> wrote in message

news:047801c3005b$1708c320$3401...@phx.gbl...

Rick

unread,
Apr 11, 2003, 5:23:19 PM4/11/03
to
I gave DocProperty fields some thought but didn't know how
to set them programmatically - especially centered, left
paragraph, etc. Any ideas?

I guess I could have the 10 fields with the same name per
sample instead of having 10 unique bookmarks per sample?

It's sad that I've gotten as close as I have with
bookmarks and now may need to shift gears. At any rate,
I've learned a lot.

Looking forward to your response. Thanks again and have a
nice weekend.

Rick

>.
>

Dave Lett

unread,
Apr 14, 2003, 8:05:09 AM4/14/03
to
Hi Rick,

You can set their positioning based on the paragraph that they are in. For
example, instead of setting the range alinment to center, you'd set

oRng.Paragraphs(1).Alignment = wdAlignParagraphCenter

HTH

"Rick" <rgwi...@buckman.com> wrote in message

news:02fc01c30070$92aa3030$a101...@phx.gbl...

Rick

unread,
Apr 14, 2003, 1:04:23 PM4/14/03
to
Thanks for getting back to me. I've run into another snag.

I can not figure out how to pass a variable to DOCPROPERTY
in the Selection.Fields.Add statements below. I need to be
able to loop through the code. It thinks that HeadText and
MyVar are the document properties and doesn't see
HeadText1 or HeadText2. Likewise for the MyVAr. How is
this accomplished? I've tried moving quotes, etc without
any luck.


For the scenario:
CustomDocumentProperty HeadText1 = Hello
CustomDocumentProperty HeadText2 = GoodBye
CustomDocumentProperty SamDes1 = Some Text
CustomDocumentProperty SamDes2 = Some Different Text

For i = 1 To 2
Selection.TypeParagraph
Selection.ParagraphFormat.Alignment =
wdAlignParagraphCenter
HeadText = "HeadText" + Trim(Str(i))
Selection.Fields.Add Range:=Selection.Range,
Type:=wdFieldEmpty, Text:= _
"DOCPROPERTY ""HeadText"" ",
PreserveFormatting:=True
Selection.Collapse Direction:=wdCollapseEnd 'Collapses
range
Selection.TypeParagraph
Selection.TypeParagraph

MyVar = "SamDes" + Trim(Str(i)) 'Sets up MyVar with
'DocProperty Name
Selection.ParagraphFormat.Alignment =
wdAlignParagraphLeft
Selection.TypeText "Sample ID: "
Selection.Fields.Add Range:=Selection.Range,
Type:=wdFieldEmpty, Text:= _
"DOCPROPERTY ""MyVar"" ", PreserveFormatting:=True

Next i

>> >> Descrip = ActiveDocument.CustomDocumentProperties


(MyVar)
>> >> SampleText = "Sample ID: " + Descrip

>> >> >> >> >> ActiveDocument.CustomDocumentProperties
(MyVar)
>> >> >> >> >> SampleText = "Sample ID: " +
>> >> Descrip
>> >> >> >> >> bmRange4.Text = SampleText
>> >> >> >>
>> .ParagraphFormat.Alignment
>> =
>> >> >> >> >> wdAlignParagraphLeft
>> >> >> >> >> .Font.Name = "Arial"
>> >> >> >> >> .Font.Size = 10
>> >> >> >> >> .Font.Bold = True
>> >> >> >> >> .Font.ColorIndex =
wdBlack
>> >> >> >> >> .Collapse
>> >> >> >> >> Direction:=wdCollapseEnd 'Collapse's field
>> >> >> >> >> ActiveDocument.Bookmarks.Add
>> >> >> SampleDesc,
>> >> >> >> >> bmRange4
>> >> >> >> >> .InsertAfter vbCrLf
>> >> >> >> >> Selection.EndKey unit:=wdStory,
>> >> >> >> Extend:=wdMove
>> >> >> >> >> End With

>.
>

Dave Lett

unread,
Apr 14, 2003, 2:32:24 PM4/14/03
to
Hi Rick,

When you put a variable in quotation marks, you pass a string literal, not
the value held by the variable. Try this instead:

HeadText = "HeadText" + Trim(Str(i))

ActiveDocument.Fields.Add _
Range:=Selection.Range, _
Type:=wdFieldDocProperty, _
text:=HeadText, _
preserveformatting:=True

HTH

"Rick" <rgwi...@buckman.com> wrote in message

news:045101c302a7$e611dc30$3301...@phx.gbl...

Rick

unread,
Apr 14, 2003, 2:43:17 PM4/14/03
to
Thanks for helping. I finally fiqured out how to use a
variable (see below). Now I'm off in a different
dirrection than using bookmarks.

Thanks again!


HeadText = "HeadText" + Trim(Str(i))

Set myField = ActiveDocument.Fields.Add
(Range:=Selection.Range, _
Type:=wdFieldDocProperty, Text:=HeadText,
PreserveFormatting:=True)

>> >> Descrip = ActiveDocument.CustomDocumentProperties


(MyVar)
>> >> SampleText = "Sample ID: " + Descrip

>> >> >> >> >> ActiveDocument.CustomDocumentProperties
(MyVar)
>> >> >> >> >> SampleText = "Sample ID: " +
>> >> Descrip
>> >> >> >> >> bmRange4.Text = SampleText
>> >> >> >>
>> .ParagraphFormat.Alignment
>> =
>> >> >> >> >> wdAlignParagraphLeft
>> >> >> >> >> .Font.Name = "Arial"
>> >> >> >> >> .Font.Size = 10
>> >> >> >> >> .Font.Bold = True
>> >> >> >> >> .Font.ColorIndex =
wdBlack
>> >> >> >> >> .Collapse
>> >> >> >> >> Direction:=wdCollapseEnd 'Collapse's field
>> >> >> >> >> ActiveDocument.Bookmarks.Add
>> >> >> SampleDesc,
>> >> >> >> >> bmRange4
>> >> >> >> >> .InsertAfter vbCrLf
>> >> >> >> >> Selection.EndKey unit:=wdStory,
>> >> >> >> Extend:=wdMove
>> >> >> >> >> End With

>.
>

0 new messages