collections order

E

ebct

For all the collections, particularly tables, are the collections
dynamically reordered?

So, if the first table is index number one, and I add a new table in
front of it, does the new one become number one and the rest renumbered
in order from top to bottom?

If we have tables two and three and a new one is put inbetween, will
the new one become three and the one previously three become four?

Is this true for all collections that reflect an order in a document?
Like characters, words, etc?

Thanks.
 
J

Jay Freedman

For all the collections, particularly tables, are the collections
dynamically reordered?

So, if the first table is index number one, and I add a new table in
front of it, does the new one become number one and the rest renumbered
in order from top to bottom?

If we have tables two and three and a new one is put inbetween, will
the new one become three and the one previously three become four?

Is this true for all collections that reflect an order in a document?
Like characters, words, etc?

Thanks.

Collections are *usually* dynamically renumbered, but the
implementation isn't necessarily consistent across all collections,
and I would never depend on this behavior.

If you must have the index of a particular object, see
http://www.word.mvps.org/FAQs/MacrosVBA/GetIndexNoOfPara.htm.

Usually, though, it's better to assign the desired table, paragraph,
or whatever to an object variable of the correct type, and then
operate on that object. Then you never need to know its absolute
index. For example:

Sub AddTable()
Dim oTbl As Table

Set oTbl = ActiveDocument.Tables.Add( _
Range:=Selection.Range, _
numrows:=3, numcolumns:=2)
With oTbl
.Cell(1, 1).Range.Text = "A"
.Cell(1, 2).Range.Text = "B"
.Rows(1).Range.ParagraphFormat.Alignment = _
wdAlignParagraphCenter
End With
End Sub

Be especially wary of using index numbers in a For loop that may
delete one or more of the objects in the collection. You can easily
get into a situation where the indexing of the collection is out of
synch with the loop counter. If you need to delete all the members of
the collection, delete item 1 as many times as the starting size of
the collection:

Sub DeleteAllTables()
Dim idx As Long

For idx = 1 To ActiveDocument.Tables.Count
ActiveDocument.Tables(1).Delete
Next idx
End Sub

To delete only some of the members, assign each one in turn to an
object variable and then call .Delete on that object.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.
 
E

ebct

I am trying to figure out how this would work in my situation.

One method assumes that the documents running the macro from template
are all identical, that the first table is actually in the exact same
place. If true, one could record the keystrokes to get to the table and
then select it. I am not sure that assumption is true and don't want to
rely on it.

Regarding the second method of counting from the beginning of the
document. I am not even sure how one selects the point after the first
table without being able to get into it unless one assumes that they
are numbered in order.

I seem to remember an IsTable function somewhere, though I can't find
it in the help file. Perhaps that is the way to do it, try to keep
stepping down until the IsTable turns true. Maybe that would work.

IMF
 
G

Greg

I am not sure I know what you are actually trying to do. I you want to
know if you are in a table or not and if you are which one and where,
you might use an adaptation of:

Sub Test()
Dim selTest As Boolean
Dim oRng As Range
Dim oTbl As Table
Dim i As Long: i = 1
Dim j As Long
Dim k As Long
selTest = Selection.Information(wdWithInTable)
If Not selTest Then
MsgBox "The selection is not in a table."
Exit Sub
End If
Set oRng = Selection.Range
j = Selection.Information(wdStartOfRangeRowNumber)
k = Selection.Information(wdStartOfRangeColumnNumber)
For Each oTbl In ActiveDocument.Tables
If oRng.InRange(oTbl.Range) Then
MsgBox "The selection is in Table: " & i & ", Row Number: " _
& j & ", Column Number: " & k & "."
Exit Sub
End If
i = i + 1
Next oTbl
End Sub
 
J

Jay Freedman

I have the same question that Greg started with: Exactly what are you trying
to accomplish? Forget about macros and programming for a moment. Just
describe what the document looks like before you start, what you want it to
look like after you finish, and how you decide which changes to put where.
If there are several possible sets of starting and ending points, describe
each of them.

I can say with near certainty that there will be a macro solution that
doesn't use any index numbers. I can guarantee with absolute certainty that
you won't be able to create that solution by recording it.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
E

ebct

Hello you two. Thanks so much for your interest.

The overall task is to pull data out of a table in a source document
and put it into another table in a target document. The target
documents are made on my computer, so I have control over them. The
source documents come from someone else, and though they usually have a
consistent format, I want to write the code so that it is flexible and
doesn't assume an absolute fixed format in the source. The source
documents are made by a script or macro of some sort on the other
user's source machine, so the format is usually stable, but it is
generated by software from a vendor which is proprietary and password
protected, so I cannot see it or alter the appearance or output of the
source documents.

One thing that is fairly constant is that the source table is the first
table in the source documents, and the target table is the table in the
target documents. Again, I want it to be flexible so that the first
table need not be in exactly the same place in either document as they
might change slightly.

That is why I keep coming back to the indexing or numerical order of
the tables. Since I cannot label them or add bookmarks or any of those
nice things in the source, it would be great to know that the first
table in a document is always index number one. I guess another way to
do it is navigate to the beginning of the document and brute force step
down a line at a time until selection.information(wdWithinTable) turns
positive. What do you think?

There you have it. Thanks,

Irwin
 
J

Jay Freedman

Hi Irwin,

Yes, the first table in the source document will always be .Tables(1). I
presume you aren't adding or deleting any tables in the source document --
only in the target document -- so that identification won't change during
the execution of the macro.

As an alternative, if there is some specific word or phrase that occurs only
in the one specific table in the source document, you can use a Find
operation to locate the table regardless of its index.

For efficiency, you should assign the table to a Table object variable, and
thereafter refer to that object instead of .Tables(1). It would go something
like this:

Dim oSrcDoc As Document, oDestDoc As Document
Dim oSrcTbl As Table, oDestTbl As Table

' open source doc and check for at least 1 table
Set oSrcDoc = Documents.Open("c:\temp\theSource.doc")
If oSrcDoc.Tables.Count = 0 Then
MsgBox "No source table", , "Error"
Set oSrcDoc = Nothing
Exit Sub
End If

' make a destination doc
Set oDestDoc = Documents.Add(Template:="myTemplate.dot")

' assign source table 1 to object variable
Set oSrcTbl = oSrcDoc.Tables(1)

' If you just want to copy the whole table from
' source to destination, do this:
Dim oRg As Range
Set oRg = oDestDoc.Range
oRg.Collapse wdCollapseStart
oRg.FormattedText = oSrcTbl.Range.FormattedText

' Otherwise...
' make destination table, same size
Set oDestTbl = oDestDoc.Tables.Add(Range:=oDestDoc.Range, _
numrows:=oSrcTbl.Rows.Count, _
numcolumns:=oSrcTbl.Columns.Count)

' copy some things, or modify along the way...
oDestTbl.Cell(1, 1).Range.Text = oSrcTbl.Cell(2, 2).Range.Text

' clean up
oSrcDoc.Close SaveChanges:=wdDoNotSaveChanges
oDestDoc.Save
Set oRg = Nothing
Set oDestTbl = Nothing
Set oSrcTbl = Nothing
Set oDestDoc = Nothing
Set oSrcDoc = Nothing

Of course, this code needs more work, including error handling, but that
should get you started.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 

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