Run code fails, single-step code works?! GetCrossReferenceItems method

D

dedawson

I have some code that marks the current selection point, finds the
next caption, and inserts a cross-reference to that caption at the
marked selection point. The problem is that it will sometimes fail as
a result of a failure of the GetCrossReferenceItems method to return
the correct number of items.

Here's my lead-in code

ActiveDocument.Bookmarks.Add Range:=Selection.Range,
Name:="PutItHere"
Selection.Find.Style = ActiveDocument.Styles("Caption")
Selection.Find.Execute
cFieldResults = Selection.Fields(1).Result + "-" +
Selection.Fields(2).Result
oCaptions = ActiveDocument.GetCrossReferenceItems(wdCaptionTable)

And here's some code right out of Microsoft Visual Basic Help.

oCaptions = ActiveDocument.GetCrossReferenceItems(wdCaptionTable)
For I = 1 To UBound(oCaptions)
If InStr(LCase$(oCaptions(I)), cFieldResults) Then
iReferenceItem = I
Exit For
End If
Next I

and here's the rest of my code

Selection.GoTo What:=wdGoToBookmark, Name:="PutItHere"
Selection.InsertCrossReference ReferenceType:="Table",
ReferenceKind:= _
wdOnlyLabelAndNumber, ReferenceItem:=iReferenceItem, _
InsertAsHyperlink:=False, _
IncludePosition:=False, SeparateNumbers:=False, SeparatorString:="
"


My document contains 102 entries in wdCaptionTable. If I single step
through this code using F8, it is succesful every time --
UBound(oCaptions) always = 102

If, however, I merely start the code by F5, sometimes the code works,
and other times it fails. When it fails, it is because iReferenceItem
is Empty, which is the result of UBound(oCaptions) having been set to
6 or 7. In this case, the loop never finds the Caption that was found
by Selection.Find.Execute because it terminates before it reaches the
index of the Caption.

I am at a complete loss, and hope someone can clue me in on
a) why this is happening, and
b) how can it be corrected?

Many thanks in advance

david
 
C

Carolin

It sounds like Word is taking a while to get through the find and the macro
has gone ahead without the task being completed. I'm not sure if it will
work, but you could try the DoEvents() function.
 
R

Russ

Inline reply.
I have some code that marks the current selection point, finds the
next caption, and inserts a cross-reference to that caption at the
marked selection point. The problem is that it will sometimes fail as
a result of a failure of the GetCrossReferenceItems method to return
the correct number of items.

Here's my lead-in code

ActiveDocument.Bookmarks.Add Range:=Selection.Range,
Name:="PutItHere"
Selection.Find.Style = ActiveDocument.Styles("Caption")
Selection.Find.Execute
cFieldResults = Selection.Fields(1).Result + "-" +
Selection.Fields(2).Result

Does using '&', instead of '+' to concatenate the above string make a
difference? The help for '&' says that the ampersand forces a string result
to get rid of the ambiguity of the '+' character usage, which is normally
associated with numeric results.
 
D

dedawson

& or +, no difference. The problem is that Word is returning only a
subset of the existing captions, 6 instead of the 102 that are
actually defined.



Further testing only serves to make the problem even more mysterious.

Given that the speed at which the code executes appeared to somehow
effect the results, I inserted a wait immediately in front of the
failing statement, e.g.,

MsgBox ("Wait Here")
oCaptions = ActiveDocument.GetCrossReferenceItems(wdCaptionFigure)

This is no help at all. If the code is single-stepped, no errors
occur. If it is simply Run, only a subset of the available captions
are returned by the GetCrossReferenceItems method.
 
S

Shauna Kelly

Hi Greg

I'm interested in following this up because I've had trouble over the years
using .GetCrossReferenceItems. It doesn't always pick up all items, and I
had to roll my own routine, which runs much slower than the built-in one.

I can't see that
Set myRange = ActiveDocument.Range(Start:=0, End:=0)
is related to
oCaptions = _
ActiveDocument.GetCrossReferenceItems(wdCaptionTable)

But are you saying that setting a range variable to a more or less random
range immediately before running .GetCrossReferenceItems causes it to work
reliably? Stranger things have happened in Word, so nothing would surprise
me!

Shauna

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

Russ

Shauna et al.,

Here's what VBA help says about .GetCrossReferenceItems in my version of
Word. The asterisks were added by me for emphasis.

Although it says "for which box", it later only gives 5 types. Because
wdCaptionTable is not a wdRefCaptionTable type, maybe it is unreliable?
Maybe everything in the "for which box" has not been fully integrated or
debugged to work with that method yet?

===Quote
Returns an array of items that can be cross-referenced based on the
specified cross-reference type. The array corresponds to the items listed in
the **For which box** in the Cross-reference dialog box (Insert menu).
Note An item returned by this method can be used as the ReferenceWhich
argument for the InsertCrossReference method.
Syntax
expression.GetCrossReferenceItems(ReferenceType)
expression Required. An expression that returns a Document object.
ReferenceType Required Variant. The type of item you want to insert a
cross-reference to. Can be one of the following WdReferenceType constants:
**wdRefTypeBookmark, wdRefTypeEndnote, wdRefTypeFootnote, wdRefTypeHeading,
or wdRefTypeNumberedItem**.
====UnQuote
 
S

Shauna Kelly

Hi Russ

I think it's a bit more complicated than that and the documentation in VBA
help is, shall we say, incomplete.

The array that you get back from GetCrossReferenceItems is equivalent to the
"For which" box. The Reference Type you must give it is equivalent to the
"Reference Type" box in the dialog.

The "Reference Type" box includes caption labels. But none of the
wdReferenceType constants cope with caption labels. And obviously you can
create a cross-reference to, eg, a Table or Figure or Equation caption. So
you can use a string, eg:

Dim va As Variant
va = ActiveDocument.GetCrossReferenceItems("Table")

Or, you may have created your own label so you could use
Dim va As Variant
va = ActiveDocument.GetCrossReferenceItems("MyLabel")

Unlike "MyLabel", the Table, Figure and Equation labels are built-in. And
they have their own wdCaptionLabelID constants, wdCaptionTable,
wdCaptionFigure, wdCaptionEquation.

In an English install,
va = ActiveDocument.GetCrossReferenceItems("Table")
should produce the same results as
va = ActiveDocument.GetCrossReferenceItems(wdCaptionTable)

But since "Table" isn't "Table" except in English, it's safer to use the
constants.

But I have found in a large document with many tables, that
GetCrossReferenceItems does not always return an array containing an element
for all the tables in the document. It will do the first 100 or so tables,
but not the rest. It's not reproducible, and it seems to depend on document
complexity rather than sheer size. And, I don't think it's related to
hardware grunt, since giving it more processor speed and memory doesn't
solve the problem.

So I'm wondering if Greg found some mysterious way to solve that problem.

Shauna

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

Erik Larson

I found that adding DoEvents immediately prior to the ActiveDocument.GetCrossReferenceItems seems to resolve the issue in Word 2010.
 

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