Glitch in GetCrossReferenceItems

B

Bear

I hope Shauna reads this. Just one more oddity about GetCrossReferenceItems
and InsertCrossReference. But maybe you've found a way around it...

You can test this out yourself fairly easily. Create a document with three
Heading 1 paras in it. Type Before in the first, nothing in the second, and
After in the third.

GetCrossReference items will not include the empty para! (If it's a Heading
2 or 3 etc, it will -- it just skips empty Heading 1 paras.)

This means that if I fill a listbox with GetCrossReference, let the user
pick one, and use the listbox index to specify the InsertCrossReference item,
everything after the blank para will be off by one. You try to insert Title 7
and you get Title 6 etc.

I can't think of any efficient way to stop this, or even warn the user that
something's amiss. (Typically it's because a section break gets styled as
Heading 1.)

Any ideas?

Bear
 
Z

zkid

I did exactly as you said, and didn't have that problem. How are you
generating the items?

This is my code:

Dim myheadings as Variant, i as Integer

myHeadings = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)

For i = 1 To Ubound(myHeadings)
Msgbox myHeadings(i)
Next i
 
B

Bear

Here's the sequence of Heading 1 paras that results in a "skipped" entry in
the getcrossreferenceitems array.

[H1] Before [para mark]
[H1] [para mark -- i.e. an empty para]
[H1] After [para mark]

This gives me an array with only two entries "Before" and "After."

Find and dandy, but when I use insertcrossreference, there are three
indexable items -- which includes the "blank" para.

I'm sorry I don't have the code handy. I will try to post it later. I just
wanted to emphasize that the problem is in the discrepancy between how
getcrossreferenceitems and insertcrossreference handle the blank Heading 1.

I'll post the code later. What version of Word an which OS are you using?

Bear
 
Z

zkid

Hey Bear,

I used Word XP for the code below. I also have an add-in using the code for
2003. Are you using Word 2000? Also, which reference type are you using on
GetReferenceItems? wdRefTypeNumberedItem or wdRefTypeHeading? If you're
using RefTypeHeading, try using RefNumberedItems instead to see what happens.
 
B

Bear

zkid:

Here's some code that will illustrate my issue:

Sub y()

Dim varXrefs As Variant
Dim I As Long

On Error Resume Next

varXrefs = ActiveDocument.GetCrossReferenceItems _
(ReferenceType:=wdRefTypeHeading)
For I = 1 To UBound(varXrefs)
Selection.InsertAfter varXrefs(I) & vbNewLine
Next I

For I = 1 To UBound(varXrefs)
Selection.Range.InsertCrossReference _
ReferenceType:=wdRefTypeHeading, _
ReferenceKind:=wdContentText, _
ReferenceItem:=I, _
InsertAsHyperlink:=False, _
IncludePosition:=False
Selection.EndKey Unit:=wdLine
Selection.InsertAfter vbNewLine
Selection.Collapse direction:=wdCollapseEnd
Next I

End Sub


I've been putting a break point at the beginning of the InsertCrossReference
loop. I put the first loop (from printing varXrefs) in the left column of a
two-column table. At the break, I put the insertion point in the right colum
and then continue.

Either with or without the On Error Resume next, varXrefs gets filled by
GetCrossReferenceItems.

However, if you have a Heading 1 para with no content,
GetCrossReferenceItems simply skips that para and keeps on filling the array
at the next non-null para. (Lower-level items never get "skipped" because the
indentation space characters are inserted before Word notices that the para
is empty.)

Without Resume Next, the InsertCrossReference generates an error when it
hits the index number of the empty paras, whether they are Heading 1 or lower.

With Resume Next, the two empty paras get skipped, and more important, the
subsequent items shifted are off from the "correct" index number.

Bear
 
Z

zkid

Bear said:
zkid:

Here's some code that will illustrate my issue:

Sub y()

Dim varXrefs As Variant
Dim I As Long

On Error Resume Next

varXrefs = ActiveDocument.GetCrossReferenceItems _
(ReferenceType:=wdRefTypeHeading)
For I = 1 To UBound(varXrefs)
Selection.InsertAfter varXrefs(I) & vbNewLine
Next I

For I = 1 To UBound(varXrefs)
Selection.Range.InsertCrossReference _
ReferenceType:=wdRefTypeHeading, _
ReferenceKind:=wdContentText, _
ReferenceItem:=I, _
InsertAsHyperlink:=False, _
IncludePosition:=False
Selection.EndKey Unit:=wdLine
Selection.InsertAfter vbNewLine
Selection.Collapse direction:=wdCollapseEnd
Next I

End Sub


I've been putting a break point at the beginning of the InsertCrossReference
loop. I put the first loop (from printing varXrefs) in the left column of a
two-column table. At the break, I put the insertion point in the right colum
and then continue.

Either with or without the On Error Resume next, varXrefs gets filled by
GetCrossReferenceItems.

However, if you have a Heading 1 para with no content,
GetCrossReferenceItems simply skips that para and keeps on filling the array
at the next non-null para. (Lower-level items never get "skipped" because the
indentation space characters are inserted before Word notices that the para
is empty.)

Without Resume Next, the InsertCrossReference generates an error when it
hits the index number of the empty paras, whether they are Heading 1 or lower.

With Resume Next, the two empty paras get skipped, and more important, the
subsequent items shifted are off from the "correct" index number.

Bear
 
Z

zkid

Ah, okay. Now that I have your code, I understand the issue. I commented
out the two problem lines of your old code and replaced it with the code that
works (you will need to remove both lines of commented out code before
testing it). The bottom line is that it didn't like your reference type.
Silly, I know, but what are you going to do?! For some reason, it will load
the array properly using the heading references, but to get them back out,
you need to state it is a numbered item, not a heading. Go figure. The
other problem was with the ReferenceKind.

For I = 1 To UBound(varXrefs)
Selection.Range.InsertCrossReference _
' ReferenceType:=wdRefTypeHeading, _
ReferenceType:="Numbered item", _
'ReferenceKind:=wdContentText, _
ReferenceKind:=wdNumberRelativeContext, _
ReferenceItem:=I, _
InsertAsHyperlink:=False, _
IncludePosition:=False
 
B

Bear

zkid:

But I don't HAVE any numbered items! I don't get anything but errors from
the modified code:

For I = 1 To UBound(varXrefs)
Selection.Range.InsertCrossReference _
ReferenceType:=wdRefTypeNumberedItem, _
ReferenceKind:=wdNumberRelativeContext, _
ReferenceItem:=I, _
InsertAsHyperlink:=False, _
IncludePosition:=False
If Err.Number = 0 Then
Selection.EndKey Unit:=wdLine
Selection.InsertAfter vbNewLine
Selection.Collapse direction:=wdCollapseEnd
Else
Err.Clear
End If
Next I
 
Z

zkid

I just plugged in your code, and it works perfectly on my computer. I just
re-read what you are doing with it all - you are testing it outside of the
table columns for now, yes?

Anyway, heading styles ARE considered numbered items - you'll just have to
trust me on that one.

This is what I got - I am using Word's heading style feature for the
following:

ARTICLE I
LEVEL ONE HEADING STYLE

1.01 Level Two Heading Style

1.02

1.03 Level Two Heading Style

This is what your code produces (of course, they are actually reference
fields in the doc, not just text):

ARTICLE I
1.01
1.02
1.03

As you can see, not only does it find the headings/numbered items, but the
blank heading also gets cross-referenced.

So, I think the next place we need to look is how you are inserting your
headings. You are using Word's heading styles, yes? Plus, you never did
tell me whcih version of Word you are using.
 
B

Bear

zkid:

Your headings ARE numbered. Try it on a document where Heading 1 etc. are
NOT autonumbered. (PS Please excuse my terseness, I'm in the middle of a
migraine and can't see very well.)

Bear
 
Z

zkid

Bear, as far as I know, this feature can only pick up a reference if there is
some sort of text in it (the number counts as text). I just put in heading
styles without numbering and tried to insert a cross-reference manually
(without the code) on the blank entry, and it stated the requested reference
was empty. I even tried putting in several required spaces, to no avail. I
suspect Word's capture of the headings performs some sort of trim operation.
I even tried hidden text so there'd be something there, but I still received
the empty message.

I seem to recall you said that you COULD do this manually, but I was unable
to do so. So, now I can see why the code won't work in this situation. I'm
a bit perplexed why you need a cross-reference for a blank entry, but it is
your wish to do so.

I don't think there is anything else I can help you with here. Sorry, I
tried.
 
S

Shauna Kelly

Bear

I can repro your problem exactly as you describe it. Give me a little
while (that's deliberately vague, but it probably means a day or two) to
see if I have any code lying around the place that might help.

But I suspect there's no way around this.

Shauna

Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
 
B

Bear

Shauna:

Obviously, I'd appreciate any help you can provide. I'm at the point of
considering if there's any way to perform a test each time the user attempts
to insert a cross-reference, just to warn them that the x-ref they just
inserted was incorrect. But I don't know of a good way to actually examine
the x-ref just inserted.

Bear
 
Z

zkid

Bear, when you load the list box from the cross-reference container, you can
use a for loop to check to determine if each entry is empty, yes? Then, if
so, don't load it into the list box. Will that work?
 
B

Bear

zkid:

Alas, no. The container is returned with no empty elements. For example, if
I had ten headings, but one was blank, the getcrossreferenceitems method
fills my variant (array) with nine items.

Sigh.

Bear

PS: Thanks for trying so hard. I appreciate it.
 
Z

zkid

Okay, how about this? I tweaked your for loop just a bit to show what's in
the container. By using trim, the blank heading came back as 0!

For I = 1 To UBound(varXrefs)
Selection.InsertAfter varXrefs(I) & vbNewLine
MsgBox Len(Trim(varXrefs(I)))
Next I
 
B

Bear

zkid

I don't want to x-ref an empty head. BUT having empty heads thows my x-ref
insertion off by however many empty heads precede the target.

Ten H1 paras in a document. By chance, the 4th H1 is empty (say because the
user inserted a section break that picked up the H1 style.)

Getcrossreferenceitems returns an array of nine H1s, skipping the empty H1
undetectably.

Insertcrossreference works on a collection of all ten H1s.

So the list I build and show the user doesn't match the collection used by
insetcrossreference.

The user picks item 5 from the getcrossreferenceitems but
insertcrossreference inserts the sixth heading.

See the problem?

Bear
 

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