MS Office Forum / Word / Programming / January 2006
Help With Code
|
|
Thread rating:  |
Fred Goldman - 22 Jan 2006 04:05 GMT Ok, I just wrote my first code. I was wondering if anyone could tell me how it could be written better and maybe help me on a few points.
Here's the code:
Set myCharStyle = ActiveDocument.Styles("Drop P'nim") Set myPara = ActiveDocument.Styles("Body Text2") Set myChar = ActiveDocument.Styles("Ha'aros") Do If Selection.Style = myPara Then Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend Selection.Style = myCharStyle Selection.MoveDown Unit:=wdParagraph, Count:=1 Selection.HomeKey Unit:=wdLine Else Selection.MoveDown Unit:=wdParagraph, Count:=1 End If Loop Until Selection.Style = myChar
What it does is find every style that I specify and tag the first word with a character style. I couldn't find a way to tell the loop to exit when it reaches then end of the document so what I did was tag the last paragrah as myChar and set the loop to exit when it reaches the last paragraph.
Is there anyway I can improve this code? How would I set myPara to more than one style?
Thanks in advance!
Greg Maxey - 22 Jan 2006 04:44 GMT Fred,
I suppose there are lots of ways to skin a cat (no offense to cat lovers intended).
Here is one:
Sub Test() Dim oPar As Paragraph Dim myRng As Range For Each oPar In ActiveDocument.Range.Paragraphs If oPar.Style = "Body Text" Then Set myRng = oPar.Range.Words(1) If InStr(myRng.Text, " ") Then myRng.MoveEnd wdCharacter, -1 End If myRng.Style = "TestStyle" End If Next End Sub
Greg Maxey
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Ok, I just wrote my first code. I was wondering if anyone could tell > me how it could be written better and maybe help me on a few points. [quoted text clipped - 25 lines] > > Thanks in advance! Helmut Weber - 22 Jan 2006 11:38 GMT Hi Fred,
try to get used to range-objects. The macro recorder always uses the selection object, which may lead beginners to stick to the selection.
Most often it is not necessary to use selection, it's also slow and needs too much code to control.
Use "Option explicit" see: Tools, Options, Editor, Require Variable Declaration.
>Set myPara = ActiveDocument.Styles("Body Text2") This is probably not what you want. You are creating a style object, IMHO,
>if Selection.Style = myPara will return false if you modified a paragraph directly, by e.g. defining a right indent, as all of the style of the selection is not equal to all of the style of the template.
If you use selection.style like if selection.style = "Normal", then this returns true, even if you modified the paragraph, as it checks only for the name of the style, not for all of it.
>How would I set myPara to more than one style? No way. You have to use "or" or "select case".
if selection.style = "Normal" or selection.style = "Normal2"
or:
Sub test500() Dim oPrg As Paragraph For Each oPrg In ActiveDocument.Paragraphs With oPrg.Range.Words(1) .Select ' for testing using F8, delete after testing! Select Case oPrg.Style Case "Normal": .Style = "ChStyle1" Case "Heading 2": .Style = "ChStyle2" Case "Heading 3": .Style = "ChStyle3" End Select End With Next End Sub
Greg's code takes care in addition of the fact, that an ordinary word in Word may encompass a trailing space, and avoids formatting of the space by setting up a temporary range, moving the end of the range to the left, and applying the formatting to the so shortened range.
Sure, lots of questions left...
HTH
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
Fred Goldman - 22 Jan 2006 15:16 GMT Helmert,
Thank you very much, while Greg gave me working code (thank you, too), you answered a few of the questions I really wanted to know.
Just a couple more questions:
1) I've noticed both you are setting variables with "Dim As", what exactly is the difference between "Set" and "Dim As"?
2) What does "Case" mean?
3) I've noticed a lot of people say that they don't want the space after a word tagged with a character style, what is wrong with that?
> Hi Fred, > [quoted text clipped - 53 lines] > > HTH Greg Maxey - 22 Jan 2006 16:40 GMT Fred,
I am just a novice myself, but I will take a shot at your questions.
Dim As - Is the start of a declaration statement. See: http://word.mvps.org/FAQs/MacrosVBA/DeclareVariables.htm
Set assigns an object reference to a variable or property. (from VBA help)
You can select "Dim" or "Set" in your VB Editor and then press F1 to see the help description.
Case is part of the Select Case statement. Again, select the word Case in your VBE and press F1. It is sort of like saying: I want to look at the color of the wall. Then "if" the color is blue do this, "if" red do that, "if" pink then puke.
Look at this simple example.
Type Fred and Greg in a new blank document and then copy the below code to the VBE. Select Fred in the document and run the code. Then select Greg and run the code again. Finally, don't select anything.
Sub Test() Dim oRng As Range 'Declare oRng as as Range Object Set oRng = Selection.Range 'Make it equal to the Selection.Range Select Case oRng.Text 'We want to look at the oRng.Text Case Is = "Fred" 'If it is Fred, then do this: MsgBox "Hi Fred" Case Is = "Greg" MsgBox "Hi Greg" 'If it is Greg then do this: Case Else MsgBox "The selected isn't ""Fred"" or ""Greg""" End Select Set oRng = Nothing End Sub
HTH
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Helmert, > [quoted text clipped - 68 lines] >> >> HTH Helmut Weber - 22 Jan 2006 21:08 GMT Hi Fred,
>3) I've noticed a lot of people say that they don't want the space after a >word tagged with a character style, what is wrong with that? hmm, well, to Word the space is part of a word, and that's counterintuitive and pointless, and may lead to confusion.
Formatting spaces as red and blue and black, for example, could be a way to drive an ordinary user up the wall, if you would like to do so.
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
Greg Maxey - 22 Jan 2006 21:29 GMT Fred,
Yes, I neglected to answer your last question. There is nothing wrong with it if it is what you want. Say the character style was "underlined." Personally I think it would look odd to underline the space after.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Helmert, > [quoted text clipped - 76 lines] >> Win XP, Office 2003 >> "red.sys" & Chr$(64) & "t-online.de" Fred Goldman - 22 Jan 2006 22:27 GMT Greg and Helmut,
You've both been a great help. Your explanation of "Case" was exceptional. I think I've got Dim down, too, but it's not clear. At first I thought Dim was just to name the Data Type, but then why did you have to be so specific to say it was in the Paragraphs object?
About the spaces, that's a relief because I take care of my own docs anyway. I think I might hit a major problem down the road (BTW when underlining etc. I don't tag the space with a char. style).
> Fred, > [quoted text clipped - 82 lines] > >> Win XP, Office 2003 > >> "red.sys" & Chr$(64) & "t-online.de" Fred Goldman - 23 Jan 2006 02:33 GMT Scratch that last question. Rather, am I correct if I would say you use Dim to name a Object as a variable and Set when you want to use a part of a object (like the name of a paragraph style in your document)?
> Fred, > [quoted text clipped - 82 lines] > >> Win XP, Office 2003 > >> "red.sys" & Chr$(64) & "t-online.de" Greg Maxey - 23 Jan 2006 02:53 GMT Fred,
I am not ignoring you. I simply don't feel comfortable trying to provide a technical explanation to your question. I am a novice and dabbler in VBA with no formal or professional experience.
It is a little like when I want to draw with a black crayon I pick up a black crayon. I don't know why it is black I just know it is black ;-)
Since your question is buried several levels deep in this thread, you might want to post as a new question in a day or so if someone doesn't come in here to answer.
Sorry I couldn't make it all clear. To tell you the truth there is plenty in VBA that is still a mystery to me.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> Scratch that last question. Rather, am I correct if I would say you > use Dim to name a Object as a variable and Set when you want to use a [quoted text clipped - 94 lines] >>>> Win XP, Office 2003 >>>> "red.sys" & Chr$(64) & "t-online.de" Jay Freedman - 23 Jan 2006 04:44 GMT Hi Fred,
The Dim statement has two purposes. First, it says what the data type of the variable is. Second, it causes VBA to allocate memory for the variable (that is, set aside a specific number of bytes at a specific address; the number of bytes depends on the data type).
By default, VBA (like VB) lets you be sloppy about this; if you use a variable name in an assignment statement without naming it in a Dim statement first, VBA will type it as a Variant. This is a very bad practice because it won't warn you when you misspelled the name of an existing variable. To make VBA strict about declarations, include an Option Explicit statement at the top of each module. See http://www.word.mvps.org/FAQs/MacrosVBA/DeclareVariables.htm for discussion.
The Set keyword is a completely different animal. You must use Set at the beginning of any assignment of an object (as opposed to a simple data type). An object variable is one that has properties and/or methods instead of just a value. In Word VBA, simple types are String, Integer, Long, Boolean, etc. while common object types are Document, Selection, Range, Paragraph, Shape, etc.
I don't really understand why the Set keyword is necessary. VBA knows when you need one and when you don't, since it will complain if a required one is missing or if an invalid one is included. Why not just drop it from the language? Dunno -- it's just one of those leftovers from many versions of VB (another one is the insistence on parentheses around parameters in function calls but not subroutine calls, described in http://www.word.mvps.org/FAQs/MacrosVBA/BracketsWithArgmnts.htm).
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
>Scratch that last question. Rather, am I correct if I would say you use Dim >to name a Object as a variable and Set when you want to use a part of a [quoted text clipped - 86 lines] >> >> Win XP, Office 2003 >> >> "red.sys" & Chr$(64) & "t-online.de" Tony Jollans - 23 Jan 2006 11:04 GMT > I don't really understand why the Set keyword is necessary. VBA knows > when you need one and when you don't, since it will complain if a > required one is missing or if an invalid one is included. Why not just > drop it from the language? Dunno -- it's just one of those leftovers > from many versions of VB When neither Let nor Set is specified, VBA assumes Let. If Let is invalid in the circumstances VBA will complain where it could perhaps assume Set.
Even if VBA did that, however, Set would still be required in the language as long as Variant types and/or default Properties are allowed. Consider the statement ...
MyVar = ActiveDocument
When MyVar is (implicitly or explicitly) a Variant, does it mean
Set MyVar = ActiveDocument
Or
Let MyVar = ActiveDocument.Content.Text ' or whatever the default is
Without an explicit Set keyword what should VBA do? You could argue that MyVar should be explicitly typed - and indeed it should - but there are occasions when data have to be Variants and there is much existing code which would fail if Set were dropped from the language.
-- Enjoy, Tony
Jay Freedman - 25 Jan 2006 02:56 GMT >> I don't really understand why the Set keyword is necessary. VBA knows >> when you need one and when you don't, since it will complain if a [quoted text clipped - 23 lines] >occasions when data have to be Variants and there is much existing code >which would fail if Set were dropped from the language. Hi Tony,
I grant you your point, and "dropped from the language" is too strong -- I should have said "made optional whenever possible". It indicates that the developers of the VBA interpreter haven't really done as much as they could do to ease the burden on programmers.
If MyVar *is* explicitly declared as an object type, then the Set keyword should be optional. That is,
Dim MyVar As Document MyVar = ActiveDocument
should not result in an error; the interpreter has all the information it needs to decide what to do. Only in the ambiguous case should it complain -- and then the error message should say there's an "ambiguous reference" and both options (using Set with the object reference or omitting Set and using an explicit property of the object) should be listed.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
Tony Jollans - 25 Jan 2006 12:15 GMT I do agree. Where there is no ambiguity, Set could (and probably should) be assumed.
-- Enjoy, Tony
> >> I don't really understand why the Set keyword is necessary. VBA knows > >> when you need one and when you don't, since it will complain if a [quoted text clipped - 50 lines] > Email cannot be acknowledged; please post all follow-ups to the > newsgroup so all may benefit. Fred Goldman - 23 Jan 2006 19:10 GMT Thank you, Jay, for the info. That is what I thought in the beginning, but then why did Greg and Helmut write "Dim oPrgh As Paragraph" shouldn't they have written Dim oPrgh As Object" since "Paragraph" isn't a data type?
> Hi Fred, > [quoted text clipped - 125 lines] > >> >> Win XP, Office 2003 > >> >> "red.sys" & Chr$(64) & "t-online.de" Jay Freedman - 25 Jan 2006 03:11 GMT Hi Fred,
Actually, Paragraph is a data type, or at least a kind of object. The one called Object with a capital O is only the most general kind of object, but there are dozens of more specialized ones.
The Help topic for the Dim statement says that the "type" parameter is:
"Data type of the variable; may be Byte, Boolean, Integer, Long, Currency, Single, Double, Decimal (not currently supported), Date, String (for variable-length strings), String * length (for fixed-length strings), Object, Variant, a user-defined type, or an object type."
That last item, "an object type", includes any of the more specialized objects -- Document, Paragraph, Sentence, Character; Dialog; Shape, InlineShape; Range; and on and on. Whenever you know exactly what kind of object your variable is, you should put that into the Dim statement. Otherwise you won't have easy access to the properties and methods that belong to the more specialized type.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
>Thank you, Jay, for the info. That is what I thought in the beginning, but >then why did Greg and Helmut write "Dim oPrgh As Paragraph" shouldn't they [quoted text clipped - 38 lines] >> Email cannot be acknowledged; please post all follow-ups to the >> newsgroup so all may benefit. Fred Goldman - 25 Jan 2006 03:30 GMT Thanks Jay, I think I finally have it down now thanks to you and the rest of the gang.
> Hi Fred, > [quoted text clipped - 67 lines] > >> Email cannot be acknowledged; please post all follow-ups to the > >> newsgroup so all may benefit.
|
|
|