Do While or While & Selection or Range Object?

J

JB

Hi Folks,
I've written some code to check the character style in paragraphs and
'do stuff' based of the style found. First question: Is it better to
use the 'Do While' clause with this (which I'm thinking it might be).
Second Question: Is it better to use range instead of selection, and if
so how do I convert this to ranges? I've never used ranges before and
don't really know that much about the properties/methods.
Any pointers/improvements gratefully accepted.
Cheers

J

Dim x As Integer, y As Integer, s As Integer
Dim StyleNow As String
Dim test As Variant, test1 As Variant

StyleNow = "Persname"
SavedMemData = _
ActiveDocument.BuiltInDocumentProperties(wdPropertyParas)

For x = 0 To SavedMemData - 1

styletype = Selection.Style

For s = 1 To 6
y = 0
Persname:
test1 = Selection.Paragraphs.Last
test = Selection.Document.Paragraphs.Item(x + 1)
If test <> test1 Then GoTo End1
If Selection.Style = StyleNow Then

StyleNow = Selection.Style

Selection.MoveLeft wdCharacter, 1
Selection.MoveRight Unit:=wdWord, Count:=1, _
Extend:=wdExtend

If StyleNow = "Persname" Then GoTo Pers1
If StyleNow = "Perstitle" Then GoTo perstitle1
If StyleNow = "Persinits" Then GoTo persinits1

If StyleNow = "Office" Then GoTo office1
If StyleNow = "Department" Then GoTo department1
If StyleNow = "Email" Then GoTo email1
Pers1:
While StyleNow = "Persname"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
Wend
perstitle1:
While StyleNow = "Perstitle"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
Wend
persinits1:
While StyleNow = "Persinits"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
Wend
office1:
While StyleNow = "Office"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
Wend
department1:
While StyleNow = "Department"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
Wend
email1:
While StyleNow = "Email"
Selection.MoveRight wdWord, 1, wdExtend
If Right(Selection.Style, 5) = "Entry" Then
Selection.MoveLeft wdWord, 1, wdExtend
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style
GoTo CheckEntry
End If
y = y + 1
If y = 20 Then
Selection.MoveLeft wdCharacter, 2, wdExtend
GoTo CheckEntry
End If
Wend
Selection.MoveLeft Unit:=wdCharacter, Count:=1, _
Extend:=wdExtend

CheckEntry:
If StyleNow = "Persinits" Then
txtInits(x) = Selection.Text
ElseIf StyleNow = "Perstitle" Then
txtTitles(x) = Selection.Text
ElseIf StyleNow = "Persname" Then
txtpersname(x) = Selection.Text
ElseIf StyleNow = "Office" Then
txtOffices(x) = Selection.Text
ElseIf StyleNow = "Department" Then
txtDepartments(x) = Selection.Text
ElseIf StyleNow = "Email" Then
txtEmails(x) = Selection.Text
End If
Selection.MoveRight wdCharacter, 3
Selection.MoveLeft wdCharacter, 1, wdExtend
StyleNow = Selection.Style

If test <> test1 Then
If Right(Selection.Style, 5) = "Entry" Then
ListType(x) = Selection.Style
End If
End If
'GoTo Persname
Else
End1:
End If
If test <> test1 Then s = 6
Next s
Next x
endnow:
 
H

Helmut Weber

Hi JB,
this is really too much code.
Seems not only for me.
Please reduce it to the essentials.
Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
 
J

JB

Helmut said:
Hi JB,
this is really too much code.
Seems not only for me.
Please reduce it to the essentials.
Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
OK Sorry,
New thread or existing?

J
 
H

Helmut Weber

New one, I'd suppose.
---
Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98

Gruss
Helmut Weber
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
 
J

Jonathan West

Hi JB

There are several problems with your code.

1. There is a fantastic amount of unnecessary duplication.

2. You are using the Selection where a Range will probably be much quicker.

3. You are using a lot of Goto statements, which tend to make your code
harder to read and maintain. Using structured branching usually makes the
application easier to understand

4. I don't see how any of the branches of the CheckEntry section can
possibly run, because in every case, just before jimping to CheckEntry, you
have changed the value of StyleNow to something including the word "Entry"

5. In your While loop, extending the selection until it reaches a paragraph
with a different style will cause any attempt to read the Selection.Style
property to throw an error. I suspect that what you are wanting to check is
if the end of the selection has gained a new style.

6. There is no clue as to where the selection is starting, and why you are
moving the Selection around although your outermost loop is going through
every paragraph in the document.


The code below is a rewrite, correcting the fourth & fifth errors and
removing all the duplication. Because of this, its not directly possible to
show you how to rewrite thsi more efficiently. Could you explain what you
are trying to achieve?
 
J

JB

Jonathan said:
Hi JB

There are several problems with your code.

1. There is a fantastic amount of unnecessary duplication.

2. You are using the Selection where a Range will probably be much quicker.

3. You are using a lot of Goto statements, which tend to make your code
harder to read and maintain. Using structured branching usually makes the
application easier to understand

4. I don't see how any of the branches of the CheckEntry section can
possibly run, because in every case, just before jimping to CheckEntry, you
have changed the value of StyleNow to something including the word "Entry"

5. In your While loop, extending the selection until it reaches a paragraph
with a different style will cause any attempt to read the Selection.Style
property to throw an error. I suspect that what you are wanting to check is
if the end of the selection has gained a new style.

6. There is no clue as to where the selection is starting, and why you are
moving the Selection around although your outermost loop is going through
every paragraph in the document.


The code below is a rewrite, correcting the fourth & fifth errors and
removing all the duplication. Because of this, its not directly possible to
show you how to rewrite thsi more efficiently. Could you explain what you
are trying to achieve?
Hi Jonathan,
1. I know there is duplicaiton but I couldn't see any other way of doing
this as it's not Paragraph styles I'm dealing with, it's Character
styles in the paragraph.
2. I know nothing about the Range Object and that's mostly what I was
asking in the first Post, pointer on how to make it better.
3. Goto Statement is fair comment, I should know better than to use
these :)
4. The checkentry section does actually work cos I'm selecting the style
based on the selected text, it's not actually changing the stylenow var
to "Entry" it's just checking if it's past the paragraph mark or not.

I'm trying to get data from a document based on the Character style type
it is, each para will have a series of six entries for Name, initials,
Surname, Office, Dept, Email and I would like to place the data into
variables for output to a form for editing and re-insertion.
What I've been trying to do up to now is crawl through the document one
line at a time checking the style and selecting the text as appropriate.

Below is a sample of what the document would look like.

mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress

Hope this makes things clearer

Regards
J
 
J

Jonathan West

JB said:
Jonathan West wrote:
Hi Jonathan,
1. I know there is duplicaiton but I couldn't see any other way of doing
this as it's not Paragraph styles I'm dealing with, it's Character
styles in the paragraph.

It helps if you provide those little details :)
2. I know nothing about the Range Object and that's mostly what I was
asking in the first Post, pointer on how to make it better.

OK, I can describe that, see the code sample below
3. Goto Statement is fair comment, I should know better than to use
these :)

I'm not averse to using a Goto occasionally, but if you can use structured
branching, then it makes the code easier to understand and maintain. It's
not a religious thing with me (though it is for some coders!) but simply a
matter of keeping myself as productive as possible.
4. The checkentry section does actually work cos I'm selecting the style
based on the selected text, it's not actually changing the stylenow var
to "Entry" it's just checking if it's past the paragraph mark or not.

Ah, there's a much simpler way of doing that :)
I'm trying to get data from a document based on the Character style type
it is, each para will have a series of six entries for Name, initials,
Surname, Office, Dept, Email and I would like to place the data into
variables for output to a form for editing and re-insertion.
What I've been trying to do up to now is crawl through the document one
line at a time checking the style and selecting the text as appropriate.

Below is a sample of what the document would look like.

mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress
mr H Potter OfficeName DeptName EmailAddress

Hope this makes things clearer

It does. The code can be rewritten into about a third of the length, use
ranges and probably run a good deal faster! Try the following code.

Dim x As Long
Dim oPara As Paragraph
Dim oWord As Range

x = 0
For Each oPara In ActiveDocument.Paragraphs
If Right(oPara.Style, 5) = "Entry" Then
ListType(x) = oPara.Style
For Each oWord In oPara.Range.Words
Select Case oWord.Style
Case "Persinits"
txtInits(x) = txtInits(x) & oWord.Text
Case "Perstitle"
txtTitles(x) = txtTitles(x) & oWord.Text
Case "Persname"
txtpersname(x) = txtpersname(x) & oWord.Text
Case "Office"
txtOffices(x) = txtOffices(x) & oWord.Text
Case "Department"
txtDepartments(x) = txtDepartments(x) & oWord.Text
Case "Email"
txtEmails(x) = txtEmails(x) & oWord.Text
Case Else
End Select
Next oWord
x = x + 1
End If
Next oPara
 
J

JB

Jonathan said:
It helps if you provide those little details :)




OK, I can describe that, see the code sample below




I'm not averse to using a Goto occasionally, but if you can use structured
branching, then it makes the code easier to understand and maintain. It's
not a religious thing with me (though it is for some coders!) but simply a
matter of keeping myself as productive as possible.




Ah, there's a much simpler way of doing that :)




It does. The code can be rewritten into about a third of the length, use
ranges and probably run a good deal faster! Try the following code.

Dim x As Long
Dim oPara As Paragraph
Dim oWord As Range

x = 0
For Each oPara In ActiveDocument.Paragraphs
If Right(oPara.Style, 5) = "Entry" Then
ListType(x) = oPara.Style
For Each oWord In oPara.Range.Words
Select Case oWord.Style
Case "Persinits"
txtInits(x) = txtInits(x) & oWord.Text
Case "Perstitle"
txtTitles(x) = txtTitles(x) & oWord.Text
Case "Persname"
txtpersname(x) = txtpersname(x) & oWord.Text
Case "Office"
txtOffices(x) = txtOffices(x) & oWord.Text
Case "Department"
txtDepartments(x) = txtDepartments(x) & oWord.Text
Case "Email"
txtEmails(x) = txtEmails(x) & oWord.Text
Case Else
End Select
Next oWord
x = x + 1
End If
Next oPara
HI Jonathan,
That's so annoying!! it works really well! Why didn't I think of
that?? :)

Thanks very much.

J
p.s. Anywhere I can find more info on using Ranges instead of selection?
A lot of my code is based on selection but the range looks so much better.
 
J

Jonathan West

JB said:
HI Jonathan,
That's so annoying!! it works really well! Why didn't I think of
that?? :)

Thanks very much.

You're welcome :)
J
p.s. Anywhere I can find more info on using Ranges instead of selection?
A lot of my code is based on selection but the range looks so much
better.

Almost anything that you have that uses the selection can be made to go
faster if you do the following

Put these 2 lines of code at the start of the macro

Dim myRange as Range
Set myRange = Selection.Range

and then do a search in your macro replacing every example of Selection with
myRange.

In addition, you can access the Range property of many objects within the
document and read or manipulate the text directly.

I went into this in more detail in another answer some time ago. Take a look
here

http://groups.google.com/groups?hl=...-8&selm=OjuNz5e3AHA.1880%40tkmsftngp05&rnum=1

There are a few cases where you really need to use the Selection. These
include

1. If you are dealing with lines (as opposed to paragraphs)
2. If you are using the predefined bookmarks such as \Page, which are
defined relative to the selection.

I've been meaning for ages to write a longer article on this topic for the
Word MVP site, but have just not got round to it yet...
 

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