View Single Post
  #20   Report Post  
Posted to microsoft.public.word.newusers
Jay Freedman
 
Posts: n/a
Default Random letter colors?

On Tue, 27 Dec 2005 15:28:51 -0800, LurfysMa
wrote:

On Sat, 24 Dec 2005 15:31:21 -0500, Jay Freedman
wrote:

On Sat, 24 Dec 2005 07:41:05 -0800, LurfysMa
wrote:

On Sat, 24 Dec 2005 16:08:20 +0200, "Graham Mayor"
wrote:

Another possibility is the inverse of Jay's code

Sub RandomColors()
Dim oCh As Range
Dim myColor As Word.WdColorIndex
Randomize
For Each oCh In Selection.Characters
Do
myColor = 14 * Rnd() + 1
Loop Until (myColor = wdBlue) Or (myColor = wdRed) Or (myColor =
wdGreen)
oCh.Font.ColorIndex = myColor
Next oCh
End Sub

I was thinking of defining an array to hold the desired list of
colors. I'll have to figure out what the numbers are for red and green
(for Christmas letters). Then I could either select them randomly or
cycle through them.

I'll play with these variations.

Thanks


To find the numbers, go into the VBA editor and press F2 to open the
Object Browser. Type wdColorIndex into the search box and press Enter.
Near the bottom right you'll see a list of "Members of wdColorIndex"
with the names. Click any color name and look at the bottom-most pane
to see its numeric value.

Another way is to open the Immediate window in the editor (shortcut is
Ctrl+G) and type a question mark followed by the color name. When you
press Enter, the value will be printed below (because the question
mark is shorthand for the Print command). For example,

?wdRed

displays the value 6.

Finally, you don't have to know the numbers at all. You can do
something like this:

Dim ColorArray(2) As WdColorIndex ' declares 3 elements 0,1,2
Dim myColor As WdColorIndex

ColorArray(0) = wdBlue
ColorArray(1) = wdRed
ColorArray(2) = wdGreen

and then in the For Each loop select one element from the array this
way:

myColor = ColorArray(Int(3 * Rnd()))

The 3 in this statement is the number of elements in the array -- it
could also be written as

myColor = ColorArray(Int((UBound(ColorArray) + 1) * Rnd()))


Jay,

Thanks for the help. I didn't get time to work on this before I needed
the letters done so I just did it by hand. Now I would like to finish
the macro for next year.

My latest version is show below. I have a few questions:


'============================================== =
' Macro to set individual character colors
'============================================== =
Sub RandCharColors()

Dim oChar As Range
Dim myColor As Word.WdColorIndex
Dim iColors(1) As WdColorIndex

iColors(0) = wdRed
iColors(1) = wdGreen

Randomize
For Each oChar In Selection.Characters
myColor = iColors(Int((UBound(iColors) + 1) * Rnd()))
oChar.Font.ColorIndex = myColor
Next oChar

End Sub


Is there some way to define the list of colors as a list, rather than
an array? I am trying to avoid the inconvenience of numbering the
array elements and declaring the array size. Maybe something like:

Colors = wdRed wdGreen wdBlue ...

I am looking for some construct that gets defined without any literals
and the code adapts accordingly.


Yes, there is a way. First, change the declaration (the Dim statement)
for the array to

Dim iColors As Variant

"Variant" is a special data type that can contain almost any other
kind of variable. Specifically, it can also hold an array of values.
(There's a long discussion of this idea in the thread "Max/Min
Functions" in the microsoft.public.word.vba.general newsgroup, started
by Greg Maxey on 12/2/2005.) Then you can assign an array of values to
this variable this way:

iColors = Array(wdRed, wdGreen, wdBlue)

This replaces the lines

iColors(0) = wdRed
iColors(1) = wdGreen
iColors(2) = wdBlue

and you can simply add more values inside the parentheses, separated
by commas. Nothing else in the macro has to change.


Why "o" prefix or "oChar"?


That variable is declared as a Range object, and the "o" stands for
"object". There's no standard for these prefixes, though, and you're
free to use whatever system you like (or no system).


What's recommended prefix for a color index variable?


This is less clear, and less important, than the object prefix. I use
a prefix on an object variable to remind myself that a Set statement
is necessary to assign a value to it. I also like to use a "str"
prefix on string variables. For a numeric variable, you could use a
prefix of "i" for "index" or "n" for "number", but it doesn't have
much purpose.

The main thing is not to use the name of a built-in type or a property
of an object as the name of a variable, because that can be confusing.
So "iColors" or "myColor" is good because it's obviously different
from the .Color property of a Font object.

--
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.