Filling Word Table - Rows & Cells

M

mike

I am maintaining a program that does a fair amount of Range.Text assigments
in newly created Word Tables and am I trying to speed things up if at all
possible.

I added a Progress bar and it really highlights that -as the table gets
larger, things get quite a bit slower.

My first attempt was to create the table at the full size, for instance
create the table at 250 rows and then loop from the begining, setting each
of the cells' Text. That was actually a bit slower than the add-a-row and
fill-the-cells while in a loop approach.

I have tried Clearing the Undo but it doesn't seem to help much.

Was wondering if there were any way to keep things speedy as the latter part
of the table get filled?

Thanks,

- Mike
 
G

Greg Maxey

Mike,

This method may speed things up a bit.

Sub ScratchMacro()
Dim oRng As Word.Range
Dim oTbl As Word.Table
Set oTbl = ActiveDocument.Tables(1)
Set oRng = oTbl.Cell(1, 1).Range
Do
oRng.Text = "Your text"
oRng.Collapse
oRng.Move wdCell, 1
oRng.Expand wdCell
Loop Until oRng.Start = oTbl.Cell(oTbl.Rows.Count,
oTbl.Columns.Count).Range.Start
oRng.Text = "Your text"
End Sub
 
M

mike

That wokrs just great, thank you for the terrific assistance Greg.

Would I be wearing out my welcome if asked about the same problem, only
regarding regular Text in the document?

Thanks again,
 
G

Greg Maxey

Mike,

You are welcome. I don't understand the second problem. The method I
gave you sets the text of every cell in a table to the value "your
text." What is the "unit" in the main text that you want to work with?
 
M

mike

So I am all set with the table, thanks again.

The other area that seems to loose momentum is, a search and replace. The
overall behavior is similar to Merge.

It goes something like...

Within wdMainTextStory .Find.Text (a begin and an end tag) and set MyRange
to include everything between the tags. Within MyRange Find our reference
elements, replacing each with data. Duplicate this for each record. Very
similar to labels.

This also slows down as it progresses.
 
G

Greg Maxey

Mike,

Maybe something like this:

Sub Scratchmacro()
Dim oRng As Range
Dim oRng2 As Range
Set oRng = ActiveDocument.StoryRanges(wdMainTextStory)
With oRng.Find
.Text = "\<*\>"
.Wrap = wdFindStop
.MatchWildcards = True
Do While .Execute
Set oRng2 = oRng.Duplicate
ScratchMacro2 oRng2
oRng.Collapse wdCollapseEnd
Loop
End With
End Sub

Sub ScratchMacro2(ByRef oSubRng As Word.Range)
Dim vFindText As Variant
Dim vReplText As Variant
Dim i As Long
vFindText = Array("RefElement1", "RefElement2")
vReplText = Array("DataElement1", "DataElement2")
With oSubRng.Find
For i = 0 To UBound(vFindText)
.Text = vFindText(i)
.Replacement.Text = vReplText(i)
.Execute Replace:=wdReplaceAll
Next i
End With
End Sub
 
M

mike

Thats definately different from what the author had implemented, cool.

In the oRng.Find, the Text is tags specific to Word? So that Wrap wdFindStop
works? Currently the begin and end tags are self (our app) defined so they
have meaning to the database Table and fields. It'd be beyond the scope to
change.

Might they somehow be used in the Find .Wrap?
 
G

Greg Maxey

Mike,

Again I don't really understand your questions.

The "flags" I used where just arbitrary. I picked < and > and as they
have meaning in wild card searchs the must be preceeded by "\".
Basically I am looking for everything (the wildcard "*") located
between < and >. Since we are not changing the flags in our routine
but only finding and replacing text within the flags we have to use
..Wrap = wdFindStop or the routine would continue to run forever (i.e.,
if .Wrap = wdFindContinue) or until you get tired fo pressing OK (i.e.,
if .Wrap = wdFindAsk).

Here is the code again using "#" as the start and stop flag. I created
some text bounded by those flags. blah, blah #Now is the time for all
good men# blah blah.


Sub Scratchmacro()
Dim oRng As Range
Dim oRng2 As Range
Set oRng = ActiveDocument.StoryRanges(wdMainTextStory)
With oRng.Find
' .Text = "\<*\>"
.Text = "#*#"
.Wrap = wdFindStop 'wdFindContinue 'wdFindAsk
.MatchWildcards = True
Do While .Execute
Set oRng2 = oRng.Duplicate
ScratchMacro2 oRng2
oRng.Collapse wdCollapseEnd
Loop
End With
End Sub


Sub ScratchMacro2(ByRef oSubRng As Word.Range)
Dim vFindText As Variant
Dim vReplText As Variant
Dim i As Long
vFindText = Array("good", "men")
vReplText = Array("bad", "girls")
'vFindText = Array("RefElement1", "RefElement2")
'vReplText = Array("DataElement1", "DataElement2")
With oSubRng.Find
For i = 0 To UBound(vFindText)
.Text = vFindText(i)
.Replacement.Text = vReplText(i)
.Execute Replace:=wdReplaceAll
Next i
End With
End Sub
 
M

mike

Thanks so much, I get it.

I have it implemented and that absolutely keeps it running at the same rate
throughout all of the insertions!

For the duplication of the range, he had been using (so I worked it in) a
single oRng.Copy on the first pass and then oRng.Pastes the remaining
iterations. Does that sound OK?

Dim oRng As Range
..
Do
If fFirstIteration Then
Set oRng = (the routine that sets range between the begin and end tags)
oRng.Copy
oRng2 = oRng.Duplicate
ScratchMacro2(oRng2)
fFirstIteration = False
Else
oRng.Paste
ScratchMacro2(oRng)
End If
Loop

Also, was wondering, this is an executable that invokes Word and the Target
Document, I have noticed that if I don't set the objWord (application) to...

With objWord
.Visible = True
.Activate
End With

until the very end, it processes faster, how ever it will randomly will
finish with more than one document. With performace my goal I hate to let
this one go but the random behavior has me perplexed?

Thanks again, sincerely - Mike
 
G

Greg Maxey

Mike,

As Secretary Rumsfeld once said so eloquently, "...there are some
things that you don't know and you know that you don't know them...".

Your latest questions fall in that category ;-)

Since I don't have a clear picture of your complete code and what it is
that you are doing, I can't say if what you are doing is OK or not.
Fact is "OK" is in a way subjective. I just hack around with VBA and I
wouldn't want to pass an official judgment on a proposed method. As an
opinion, I would say that if it works then it is "OK." However, some
of the real senseis around here that know their stuff might pop their
clogs over it ;-).

I suggest that you create a new thread with a detailed explanation of
what it is that you are trying to do, your current process of doing it,
and then specific questions as to the merits of your process as
applicable.
 
M

mike

Good ol' Rummy

Wll thank you for the time and terrific advice regarding the two items that
you surely helped with.
 

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