PDA

View Full Version : Changing Paragraph Style



Adamski
05-06-2010, 03:27 AM
I have been using Word 2003 automation to export data from a database. I noticed that sporadically a paragraph would not have the correct formatting. On investigation I ruled out errors in my automation script and ran a test directly in Word VBA.

The paragraph formatting issue occured.

Can anyone see the problem with this sub? I think it is some Word bug, but the style fails at different paragraphs on subsequent execution. I guessed it was due to memory but strangely, it failed at the same paragraps, in the same order on two machines with completely different memory.

Is there a solution?

Sub StyleChangeTest()

Dim StyleToUse As String
Dim StyleUsed As String

Dim Count As Integer
Count = 0

Dim Run As Boolean
Run = True

Dim InsertRange As Range
Set InsertRange = Application.ActiveDocument.Range

While (Run And Count < 1000)

Count = Count + 1

StyleToUse = "Heading 1"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Heading 2"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Heading 3"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Normal"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

InsertRange.Document.UndoClear

Wend

If Run Then
Debug.Print "Reached Iteration Limit"
End If
End Sub

fumei
05-07-2010, 09:02 AM
"Can anyone see the problem with this sub? I think it is some Word bug, but the style fails at different paragraphs on subsequent execution. I guessed it was due to memory but strangely, it failed at the same paragraps, in the same order on two machines with completely different memory.

Is there a solution?"

Perhaps, but you are going to have to tell us the problem is.

"it failed at the same paragraps"
Oh..and what paragraph is that? And, "failed"...failed how?

" I guessed it was due to memory"
I doubt that VERY much.

Adjusting your code to use With statements (e.g.):
With InsertRange
.Style = StyleToUse
.Text = StyleToUse & " : " & Count
.Collapse (wdCollapseEnd)
.InsertParagraph
.Collapse (wdCollapseEnd)
End With
StyleUsed = InsertRange.Style

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & _
StyleToUse & " , Used: " & StyleUsed
End If
I am having a very hard time figuring out what you are trying to do.

mdmackillop
05-07-2010, 11:25 AM
It prints up to Normal 308 with

306, Use: Heading 2 , Used: Normal

in the Immediate window. What should it do?

Adamski
05-07-2010, 11:50 AM
Sorry, I didn't explain very well.

The Sub is just a demo to reproduce the problem. It just sets the style to use and inserts text of the styles name and iteration. It then Checks what style the paragraph is. Obviously it should be the same as what was set. Do this for Heading 1, 2, 3, and Normal styles and repeat.

At some point (306 for you) the style is not set. For you Heading 2 should have been used but it is actually in Normal.

So for you the line "Heading 2 : 306" is in Normal style not Heading 2 style as it should be. Run the Sub again and it will probably not set a Style after a different number of iterations.

fumei
05-07-2010, 12:08 PM
For me, nothing happens. NOTHING shows up in the Immediate window. I get a 5668 error "Formatting is too complex."

In the document it goes up to:

Heading 1 : 413 and it IS Heading 1 style.

If I execute the Sub again it removes the previous pages and pages of inserted text (up to Heading 1 : 413), and leaves:

Heading 1 : 1

That is because your code has:
Set InsertRange = Application.ActiveDocument.Range
so a reiteration starts with the entire document again.

Sorry, I am still not seeing the problem.

TonyJollans
05-10-2010, 03:46 AM
Granted, the code is completely artificial, but I can't explain it at all. Clearly an odd feature!

I (usually) see it stopping at 306 as Malcolm does, which suggests it isn't a simple memory issue. That I sometimes see other outcomes, and that Gerry consistently sees a different one, does suggest, however, that it is, at least partly, environmental in some way.

Tinbendr
05-10-2010, 07:00 AM
Run and Count are Word key words.

As in Application.Run "RunThisMacro"

and

Activedocument.Paragraphs.Count

It could be that Word is having a conflict in resolving the key words VS variables.

Try changing the names of the variables.

Adamski
05-12-2010, 08:12 AM
I still get it failing at 413 after changing the variable names...

TonyJollans
05-12-2010, 09:25 AM
Interestingly, perhaps, in Word 2002 (which I think Gerry is running) I get the same error as he does at the same place, but if I add extra code to save it every hundred or so paragraphs, it runs to completion.

In Word 2003, it normally runs to 7 hundred and something, but in 2007 it only usually makes 306. I don't have 2010 on this machine but will try it later.

Whatever, it seems like 2002 behaves reasonably in telling you to save because it can't do any more, whilst 2003 and 2007 appear to have a little bug.

Adamski
05-13-2010, 02:12 AM
Ah... If it runs ok when periodically saving, could it be caching the styles and running out of space??? Maybe the save clears some sort of style cache so it is not "too complex".

I'll have to experiment

TonyJollans
05-13-2010, 11:12 AM
Just for the record - I have just tried it in 2010 and it appears to work properly.

Paul_Hossler
05-15-2010, 06:08 AM
In 2007 I ran it 3-4 times with a counter of 5000 without a problem

Edit: Before the change, it would be erattic -- 367, all the way, 368, etc.

Only real change was to use


ActiveDocument.UndoClear


instead of

InsertRange.Document.UndoClear


at the top and bottom of the loop.


I'm not a good as I should be (yet ...) with Ranges but I think the InsertRange was the only thing being UnDone





Start
Reached Iteration Limit
Done
Start
Reached Iteration Limit
Done
Start
Reached Iteration Limit
Done






Option Explicit
Sub StyleChangeTest()

Dim StyleToUse As String
Dim StyleUsed As String

Dim Count As Integer
Count = 0

Dim Run As Boolean
Run = True

Dim InsertRange As Range
Set InsertRange = Application.ActiveDocument.Range

Debug.Print "Start"

ActiveDocument.UndoClear '==============================

While (Run And Count < 5000) '================================

Count = Count + 1

StyleToUse = "Heading 1"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Heading 2"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Heading 3"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If

Count = Count + 1

StyleToUse = "Normal"
InsertRange.Style = StyleToUse

InsertRange.Text = StyleToUse & " : " & Count
InsertRange.Collapse (wdCollapseEnd)

StyleUsed = InsertRange.Style

InsertRange.InsertParagraph
InsertRange.Collapse (wdCollapseEnd)

If StyleUsed <> StyleToUse Then
Run = False
Debug.Print Count & ", Use: " & StyleToUse & " , Used: " & StyleUsed
End If


ActiveDocument.UndoClear '=============================

Wend

If Run Then
Debug.Print "Reached Iteration Limit"
End If
Debug.Print "Done"

End Sub

Adamski
05-17-2010, 05:33 AM
ActiveDocument.UndoClear makes no difference in 2003