Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / October 2007

Tip: Looking for answers? Try searching our database.

Skipping in a loop

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Bear - 09 Oct 2007 18:22 GMT
Does anyone know a way to loop through all instances in a collection,
but *skip* doing something to unqualified members?

I know I could go

For Each objPara in Selection.Paragraphs
   If [Disqualifier] = False Then
       Do the stuff for qualified members
   Endif
Next objPara

But I'm looking for something more like

For Each objPara in Selection.Paragraphs
   If [Disqualifier] = True Then
       GoTo Skip
   Endif
   Do the stuff for qualified members
Skip:
Next objPara

Bear

Signature

Windows XP, Word 2000

NZ VBA Developer - 09 Oct 2007 22:01 GMT
Bear,

One of the tools I use regularly can't work with individual table rows
because Word doesn't recognise/advertise the selection of a row or rows
within a table as having something selected. Consequently, I have to break
the table up into several smaller tables and select the line before the table
as well before the Word "tells" the tool that something is selected. Of
course the end result is that the final document ends up with a bunch small
tables in it rather than a one or more larger tables. To get around this I
apply a specific style to the line before the "split" tables (usually 1pt and
hidden - just to be safe) and then use a bit of VBA to go through the
document and delete out all of the paragraphs with that particular style. The
tables then re-concatenate and all is right with the world.

The code I use looks like this:

Sub ConcatenateTables
Dim myPara as Paragraph
  For each myPara in ActiveDocument.Paragraphs
     If myPara.Style="1pt Para" Then myPara.Range.Delete
  Next myPara
End Sub

This is very similar to your first example below. In fact it would be almost
exactly the same if I changed "ActiveDocument.Paragraphs" to
"Selection.Paragraphs" and fiddled a bit with the condition evaluated by the
If statement; e.g. "If Not [Condition] Then..." This works just fine (altho
it might be a little slow if my document contains a lot of paragraphs) and
I'll undoubtedly continue to use it.

Is there a specific reason why you want to use the Goto? I can't see how it
would make the code any faster since the stuff inside the If statement
doesn't execute if the related conditions aren't satisfied anyway...

Signature

Cheers!
The Kiwi Koder
So who should I support now? France? Or anybody playing against them? (With
the exception of the Wallabies or ~shudder~ ENGLAND of course...)

> Does anyone know a way to loop through all instances in a collection,
> but *skip* doing something to unqualified members?
[quoted text clipped - 18 lines]
>
> Bear
Helmut Weber - 09 Oct 2007 22:41 GMT
Hi Bear,

there must be more to it than your posting reveals.

For Each objPara in Selection.Paragraphs
   If qualifier Then
       Do the stuff for qualified members
   Endif
Next objPara

For Each objPara in Selection.Paragraphs ' ?
   If not qualifier Then
       ' Do nothing
   else
     Do the stuff for qualified members
   Endif
Next objPara '?

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"

Bear - 10 Oct 2007 00:23 GMT
There's no particular application. (I happen to be working on automating
ListNum fields.) But imagine wanting to work through a collection of
paragraphs, and subjecting each paragraph to three or four tests, any of
which might render the paragraph ineligible for processing. It would be nice
to say:

For Each objPara in Selection.Paragraphs
   If objPara.Range.Font.Hidden = True Then Next
   If objPara.Range.Fields = 0 Then Next
   If objPara.Type <> wdBogonPara Then Next
   objPara.Property = Value
   etc., etc.
   objPara.Method
Next objPara

rather than having all those tests indent and indent.

Another way might be to set the value of a flag.

For Each objPara in Selection.Paragraphs
   flgValid = True
   If objPara.Range.Font.Hidden = True Then flgValid = False
   If objPara.Range.Fields = 0 Then flgValid = False
   If objPara.Type <> wdBogonPara Then flgValid = False
   If flgValid = True Then
       objPara.Property = Value
       etc., etc.
       objPara.Method
   End If
Next objPara
Signature

Windows XP, Word 2000

Shauna Kelly - 10 Oct 2007 04:52 GMT
Hi Bear

If this were mine, I'd use a separate function to perform the test, eg:

Sub One
   For each objPara in selection.paragraphs
       if mPassesMyText (oPara:=objPara) then
           'do stuff
       endif
   next objPara
End Sub

Function mPassesMyTest (oPara as word.paragraph) as boolean

  if oPara.range.font.size = 12 and _
   oPara.etc etc etc then
       mPassesMyTest = True
   end if

End Function

In real life you might have several layers deep of the testing process.

By the way, if issues like this interest you, I would recommend Code
Complete (2nd ed.) by Steve McConnell (http://www.cc2e.com/).

Hope this helps.

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

> There's no particular application. (I happen to be working on automating
> ListNum fields.) But imagine wanting to work through a collection of
[quoted text clipped - 27 lines]
>    End If
> Next objPara
Bear - 10 Oct 2007 13:58 GMT
Shauna:

That's something like what I ended up doing. But I was trying to pass a
range to a function, and couldn't make it work. In the end I defined a
module-level range object and had the subroutine work on that.

Can one pass a range to a function or subroutine in other ways?

Bear
Signature

Windows XP, Word 2000

> Hi Bear
>
[quoted text clipped - 58 lines]
> >    End If
> > Next objPara
Shauna Kelly - 10 Oct 2007 14:30 GMT
Hi Bear

Sure. Here's a little example which shows using a range as a parameter to a
Sub and a Function.

Option Explicit

Sub StartHere()

Dim rngSelection As Word.Range
Dim sStyleName As String

   'Get a reference to the selected range
   '(in real life you need error checking here in
   'case the user has selected, eg, an image)
   Set rngSelection = Selection.Range

   'Send our selection off to the mGetRangeStyle function
   'to be processed, and get back the name of the style
   sStyleName = mGetFirstParaStyle(oRange:=rngSelection)

   'Use the return value to tell the user what's happening
   MsgBox "The first paragraph in the selection is in style " & sStyleName

   'Send our range off to the mMakeRangePink sub that
   'will format the font of our range as pink
   mMakeRangePink oRange:=rngSelection

End Sub

Private Function mGetFirstParaStyle(ByRef oRange As Word.Range) As String

Dim sRetval As String

   'Make sure we have a range to play with..
   If Not oRange Is Nothing Then

       'Get the name of the style of the first
       'paragraph of our range
       '(in real life you need error checking here in case
       'we're in a protected document or something'
       sRetval = oRange.Paragraphs(1).Style

   End If

   'Set the return value
   mGetFirstParaStyle = sRetval

End Function

Private Sub mMakeRangePink(ByRef oRange As Word.Range)

   'Make sure we have a range to play with
   If Not oRange Is Nothing Then

       'make it pink
       oRange.Font.Color = wdColorRose

   End If

   'This is a Sub so it doesn't have a return value
   'But it has actually *changed* the oRange.

End Sub

I explicitly put in "ByRef" in the arguments of the Sub and Function to
remind us that an object is, by default, passed "By reference". That means
that the lower-level routine receives a reference to the object, and
anything you do to the object (eg, make it pink) actually changes the
object.

Hope this helps.

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

> Shauna:
>
[quoted text clipped - 70 lines]
>> >    End If
>> > Next objPara
Bear - 10 Oct 2007 14:59 GMT
You bet it helps, and thanks a bunch!

Bear

Signature

Windows XP, Word 2000

Bear - 12 Oct 2007 17:28 GMT
Many thanks to all who helped me along with this project.

After many twists and turns, I think I found the structure best suited
to my application, and that's the ElseIf of the If - Then - Else
statement. I used it like this:

For Each objPara In rngWork.Paragraphs

    Set rngPara = objPara.Range
    Set rngCollapse = rngPara
    rngCollapse.Collapse

    If rngPara.Font.Hidden = True Then
        ' No action for hidden paras
    ElseIf rngCollapse.Information(wdAtEndOfRowMarker) = True Then
        ' No action for end of row marker
    ElseIf rngPara.text = Chr(13) & Chr(7) Then
        ' No action for empty cells
    Else
        Select Case strAction
            Case "Number"
            etc.
            Case Else
        End Select
    End If

Next objPara

As you can see, the each objPara runs a "gauntlet of tests" in the If
and ElseIf statements. If it fails any test, it isn't acted on, but the
Select Case structure (that does the work on valid paras) is skipped
over and the next objPara is selected for testing.

Bear

Signature

Windows XP, Word 2000

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.