Log in

View Full Version : Intermittent failures... slow macro down?



gotmatt
08-12-2011, 08:15 AM
Hi all,

First off, thanks for all your help over the last month. This website and forum has been my classroom, and I've learned a ton! I'm finally done with my macro, but I still have one issue I cannot resolve. It's main function is to place headers and footers throughout the document. Their placement is variable, given different document structures, so two input boxes (StartSection and EndSection) are used to help guide the macro.

My issues is that it has intermittent issues. If I run it once, it may miss 2 headers, but if I start over and run it again, it works fine. Sometimes it misses more than that, and sometimes it comes out perfect. I notice that this is more prevalent with larger documents, and when the active window is in print/page view.

I'm thinking that word is being overloaded by it all. That sounds crazy to me, but if I step through it, it works fine. I've done everything I can think to lessen the processing...
ActiveDocument.Fields.Locked = True
Application.ScreenUpdating = False
Options.Pagination = False
but it still has issues. On a side note, after I declaire Options.pagination = False, and then call a subroutine, it still seems to paginate whether I want it to or not. :think:

Are there any more steps I can take to slow the macro down? Am I crazy to think my macro would work more reliably with less processes running?
Maybe I can close the document momentarily, run the macro, and then reopen it?

The portion that tends to mess up is part of a huge form, but it's called by a button. I'm including a Word document with the exact code that has trouble. It's a bit out of context, but it should give anyone a good idea of what I'm working with.

Thanks guys!

Frosty
08-12-2011, 11:16 AM
Your sample document doesn't run, because you didn't include the Form1. You also don't have the autotext entries necessary to run the code. So it's kind of tough to help troubleshoot, when so many things prevent me from even running the code.

However, in general, I would say that the following applies:
1. Macros (99% of the time) do what you tell them to do. Intermittent results are more likely flaws in your logic, rather than you discovering a word bug.

2. Options.Pagination = False is not going to do you much good. Paginations occur regardless of what you do, in many many cases. This could be a longer discussion, but I won't bore you with all of the details. Suffice to say: Word repaginates when it needs to, especially if you are in page layout view.

3. There is a difference between a For Each... Loop and a For...Loop. It looks like you're confusing the two (which may very well be the fundamental problem here). Don't use a For Each...Loop to cycle through your sections and then use logic in the middle of that for each loop to refer to a counter you are manually incrementing. It's a bad practice and makes troubleshooting a bear. Either...

Dim oSec as Section
For counter = 1 to ActiveDocument.Sections.Count
Set oSec = ActiveDocument.Sections(counter)
Next

OR

Dim oSec As Section
For Each oSec in ActiveDocument.Sections
Next

You should read up on For...Loops to understand the significance.

4. What is the point of your initial For...Loop which simply goes through and sets the hf objects and then doesn't do anything? For your own personal testing?

5. I suspect your problem relates to some confusion of your "counter-StartSection+1" logic. That's pretty convoluted, and if you simply want to iterate through all the sections of your document except the first and last then you can use this basic structure:

Dim oSec as Section
Dim i as Integer
For i = 2 To ActiveDocument.Sections.Count - 1
Set oSec = ActiveDocument.Sections(i)
'do the rest of your stuff with this section
Next


6. Modularize. Any time you find yourself copying and pasting long lines of code, you're begging for a separate function.

'Assumes FromTemplate is attached template, unless otherwise specified
Sub InsertAutoText (sAutoTextName As String, rngWhere As Range, Optional oFromTemplate As Template)
If oFromTemplate Is Nothing Then
'you can make different assumptions here... maybe
'ThisDocument.AttachedTemplate, if you store the AutoText in the same template as this code
Set oFromTemplate = rngWhere.Parent.AttachedTemplate
End If
oFromTemplate.AutoTextEntries(sAutoTextName).Insert rngWhere, True
End Sub

This allows you to simply type
InsertAutoText "HeaderOdd", rngWhere
in your code. When you're sick of copying and pasting that a bunch, you can look at other ways of modularizing (maybe you just pass in the headerfooter object, and take care of setting the rngWhere inside the routine and collapsing there). You'll also start to realize that your AutoTextStr variable is in the wrong place for logical troubleshooting and you may not need my modular function at all... you use your logic to set what the AutoTextStr (which should really be named strAutoText) variable is, and then insert it at the bottom of your loop... a la...
If counter <> StartSection - 1 And counter <> EndSection + 1 Then
strAutoText = "HeaderOdd"
ElseIf 'blah blah other stuff
End If
and then all the way down you take care of...
oTemplate.AutoTextEntries(strAutoText).Insert rngWhere, True

If you're still looking for help... you should either:
a) post a document which shows problems and has code that runs or
b) post just a code block for logic help with.

But posting a document with code in it which doesn't run isn't particularly helpful.

All for now.

Cheers,
Frosty