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 / January 2005

Tip: Looking for answers? Try searching our database.

Riddle me this

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Greg Maxey - 03 Jan 2005 10:08 GMT
Hi,

I have a snippet of code that applies superscript font:

       oWord.SetRange Start:=oWord.Start, End:=oWord.End + 1
       oWord.Select
       'oWord.Font.Superscript = True
       Selection.Font.Superscript = True

I don't understand why I have to select the range and then apply the
formatting to the selection.  In another macro I have this code

ActiveDocument.Range.Font.Superscript = True

which I am using to try to solve this riddle.  Isn't oWord a Range like
ActiveDocument.Range?  Why doesn't oWord.Font.Superscript = True work like
ActiveDocument.Range.Font.Superscript = True

Here is my complete code:

Sub ScratchMacro1()
Dim oPara As Paragraph
Dim oWord As Range
Dim i As Long
Dim myWord As String
Dim mySeq As String

myWord = InputBox("Enter the word to find.")
mySeq = myWord
For Each oPara In ActiveDocument.Paragraphs
 i = 0
 For Each oWord In oPara.Range.Words
     If Right(oWord, 1) = " " Then oWord.MoveEnd Unit:=wdCharacter,
Count:=-1
     If LCase(oWord) = LCase(myWord) Then
       i = i + 1
       oWord.Collapse Direction:=wdCollapseStart
       'insert field, reset sequence to 1 for first occurence in paragraph
       If i = 1 Then
         oWord.Fields.Add Range:=oWord, Type:=wdFieldEmpty, Text:= _
         "SEQ " & mySeq & " \r1", PreserveFormatting:=True
       Else
       'insert field
         oWord.Fields.Add Range:=oWord, Type:=wdFieldEmpty, Text:= _
         "SEQ " & mySeq & "", PreserveFormatting:=True
       End If
       'superscript the sequence number
       oWord.SetRange Start:=oWord.Start, End:=oWord.End + 1
       oWord.Select
       'oWord.Font.Superscript = True
       Selection.Font.Superscript = True
    End If
  Next
Next
End Sub

Thanks
Signature

Greg Maxey/Word MVP
A Peer in Peer to Peer Support

Helmut Weber - 03 Jan 2005 10:33 GMT
Hi Greg,

you are extending the range
into the invisible field code.

Try:
oWord.SetRange Start:=oWord.Start, End:=oWord.End + 20
oWord.Font.Superscript = True
'stop here

and switch "field codes on" or whatever
it is called in English.

Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word 2002, Windows 2000
Greg Maxey - 03 Jan 2005 10:33 GMT
Hmm,  I now know why I am riddled.  oWord.Font.Superscript is in fact
superscripting the { in my field { SEQ ... } just not the whole field.
Apparently oWord.Select is selecting the whole field string.  Can anyone
offer an explanation?

Thanks.

Signature

Greg Maxey/Word MVP
A Peer in Peer to Peer Support

> Hi,
>
[quoted text clipped - 53 lines]
>
> Thanks
Jonathan West - 03 Jan 2005 10:46 GMT
> Hmm,  I now know why I am riddled.  oWord.Font.Superscript is in fact
> superscripting the { in my field { SEQ ... } just not the whole field.
> Apparently oWord.Select is selecting the whole field string.  Can anyone
> offer an explanation?

Yes, a Selection cannot select just the opening field brace, so when you
attempt to select a range that is defined as an opening field brace, it
selects the entire field.

Signature

Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup

Greg - 03 Jan 2005 12:07 GMT
Jonathan,

Thanks.  So I could do this by adding *\ Charformat to my field code
construction, Changing PreserveFormatting to False and  extending the
range three characters

oWord.SetRange Start:=oWord.Start, End:=oWord.End + 3

to include the S in SEQ then using

oWord.Font.Superscript = True followed by a
ActiveDocument.Fields.Update at the end of the code

In my application (I don't really have one I was just playing around) I
could use either method. The only reason that I am asking is for futher
knowledge regarding efficiency.

Which method if either is more efficient?  I mean is it inefficient to
physically select a range vice redefining the range?  Thanks
Jonathan West - 03 Jan 2005 12:28 GMT
> Jonathan,
>
[quoted text clipped - 15 lines]
> Which method if either is more efficient?  I mean is it inefficient to
> physically select a range vice redefining the range?  Thanks

Hi Greg,

It depends on what you mean by "efficient"...

The primary aim is to have the program do the required task reliably. The
secondary aim is to do this as fast as possible. The reason that speed is
only the secondary aim is because it is usless for a program to do the wrong
thing very quickly!

Based on your description, it appears that you have two methionds of
achieving the same effect. In Word, this is a very common situation, and it
often happens that there are even more than two ways of doing many things.
In such a situation, the following considerations are worth considering

1. Which method runs faster?
2. Do any methods result in additional side-effects?
3. Will one method work correctly in a wider range of conditions?
4. Is any method easier to code than the others?

These points are not listed in order of importance, because the order of
importance will change from case to case.

Regarding speed, it might or might not be important depending on what you
are doing and how often it is repeated. A routine that takes 0.1s to run is
not going to benefit greatly from optimisation unless it is run repeately
inside a loop.

Side-effects are hard to discuss generally, byt the most obvious one in the
example you have given is that one method moves the selection point while
the other does not. Only you can decide whether that is an important
side-effect. If it is, and you still decide for other reasons that using the
Selection is a good idea, you can always restore the selection to its
original position by using code like this

Dim oStart as Range
Set oStart = Selection.Range

' your code here

oStart.Select

Wider ranges of conditions are also hard to talk about, and in many cases
there is no different between methods.

Ease of coding is entirely subjective, and depends on your familiarity with
different objects and methods and coding styles. If you have code that
works, whether written by you or someone else, it is usually easier to use
it than to go in for wheel-reinvention.

Signature

Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup

Greg - 03 Jan 2005 13:39 GMT
Jonathan,

Thanks for the time you spent with this explanation.  You were right.
Helmut provided a third solution much simpler and probably faster.
Helmut Weber - 03 Jan 2005 13:10 GMT
Hi Greg,

if it comes to speed, how about this one?

Of course, I have omitted some stuff,
and the variable names are really very short, ;-)
as I am just playing around, too.

Sub SpeedSpeed()
Dim p As Paragraph ' object paragraph
Dim r As Range     ' range of word
Dim i As Integer   ' counter of words
Dim s As String    ' string of word
s = "let "
For Each p In ActiveDocument.Paragraphs
 i = 0
 For Each r In p.Range.Words
  If s = r Then
     i = i + 1
     r.Collapse Direction:=wdCollapseStart
     r.Text = CStr(i)
     r.Font.Superscript = True
  End If
  Next
Next
End Sub

Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word 2002, Windows 2000
Greg - 03 Jan 2005 13:38 GMT
Helmut,

It misses something like "To let."  Changed to this is works great:

Sub SpeedSpeed()
Dim p As Paragraph ' object paragraph
Dim r As Range     ' range of word
Dim i As Integer   ' counter of words
Dim s As String    ' string of word
s = "let"
For Each p In ActiveDocument.Paragraphs
i = 0
For Each r In p.Range.Words
If Right(r, 1) = " " Then r.MoveEnd Unit:=wdCharacter, Count:=-1
If s = r Then
i = i + 1
r.Collapse Direction:=wdCollapseStart
r.Text = CStr(i)
r.Font.Superscript = True
 End If
 Next
Next
End Sub

Thanks.
Jonathan West - 03 Jan 2005 14:35 GMT
> Helmut,
>
[quoted text clipped - 21 lines]
>
> Thanks.

Hi Greg,

I would strongly recommend that you indent the code inside loops so that you
can easily see where loops & branches begin & end. It makes code much easier
to understand and follow when you are trying to debug it.

You can read more about this in the following article

The art of defensive programming
http://word.mvps.org/FAQs/MacrosVBA/MaintainableCode.htm

Also, Stephen Bullen has written a wonderful free add-in called Smart
Indenter which automatically applies a consistent indenting style to all the
lines in a routine, module or project. You can find it here

http://www.oaltd.co.uk/Indenter/Default.htm

Signature

Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup

Greg - 03 Jan 2005 14:52 GMT
Jonathan,

I usually do.  I did here but it doesn't seem to appear that way when I
cut and pasted in the message window.  I have read your article
repeatedly :-)  I will have a look at the addin.  Thanks for all of
your help and patience when I sometimes ask the same question 2 or 3
times.
Greg Maxey - 04 Jan 2005 01:20 GMT
Helmut,

As the two of us are just playing around, I thought I would try to expand
your suggestion a bit.  It is a fast and simple way to process the
paragraph, but if the user then edits the paragraph (adds or removes counted
words) then there is a mess.  I cobbled together the following code which
appears to do a decent job reproccessing the document if the macro is run a
second time using the same search word.  You are welcome to try to break it
or offer suggestions for improvement.  I don't really know what it is good
for, but it was good mental exercise:

Sub FindAndNumberWords()
'Sequentially numbers each occurance of a specified word
'Resets numbering at the start of each paragraph

Dim oPara As Paragraph
Dim oWord As Range
Dim i As Integer
Dim FindStr As String
Dim RedoChk
FindStr = InputBox("Type word to find")
For Each oPara In ActiveDocument.Paragraphs
 i = 0
 For Each oWord In oPara.Range.Words
   If Right(oWord, 1) = " " Then oWord.MoveEnd Unit:=wdCharacter, Count:=-1
     If LCase(FindStr) = LCase(oWord) Then
       i = i + 1
     oWord.Collapse Direction:=wdCollapseStart
     oWord.Text = CStr(i)
     oWord.Font.Superscript = True
   End If
   RedoChk = LCase(oWord) Like LCase("#*" & FindStr & "")
   If RedoChk Then
     i = i + 1
     oWord.MoveEnd Unit:=wdCharacter, Count:=-Len(FindStr)
     oWord.Text = CStr(i)
     oWord.Font.Superscript = True
     End If
   Next
Next
End Sub

Signature

Greg Maxey/Word MVP
A Peer in Peer to Peer Support

> Hi Greg,
>
[quoted text clipped - 27 lines]
> "red.sys" & chr(64) & "t-online.de"
> Word 2002, Windows 2000
Helmut Weber - 04 Jan 2005 09:56 GMT
Hi Greg,
not much to add, though I'd love to do so.
The only marginal thing could be, to convert
"findstr" to lowercase only once,
at the very start of the sub.

Then
  If LCase(FindStr) = LCase(oWord) Then
would become
  If FindStr = LCase(oWord)
and
  RedoChk = LCase(oWord) Like LCase("#*" & FindStr & "")
would become
  RedoChk = LCase(oWord) Like "#*" & FindStr

But I could not see any change in performance,
about 20 seconds, with more then 12000 numbers
to add in a 100 pages doc, containing just text only,
and no tables! As to operate on ranges in tables
is sometimes much slower (10 to 20 times) than using
selection.

See the posting:
Processing paragraphs with find
by Conny Roloff.

Have a nice day.

Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word 2002, Windows 2000
Greg Maxey - 04 Jan 2005 11:01 GMT
Helmut.

Thanks.

Signature

Greg Maxey/Word MVP
A Peer in Peer to Peer Support

> Hi Greg,
> not much to add, though I'd love to do so.
[quoted text clipped - 28 lines]
> "red.sys" & chr(64) & "t-online.de"
> Word 2002, Windows 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.