How to change Font color and force the user to use it

J

JuanManuel

I’m working on a small project to incorporate some vba functionality to a
template in Microsoft Word. It is a fairly long template (over 30 pages) with
extensive use of tables. We would like to be able to collapse and expand rows
as needed, so that the printed document only shows what is really relevant.

I have found VBA code that seems to be useful in achieving this.
Nevertheless, I'm having trouble trying to figure out how to implement
another requirement, and don’t know whether it’s even feasible:

1. Once the user has selected one out of four radio buttons, the Word
document should automatically switch its current font color to a specific
color (corresponding to the appropriate alternative), so that the text that
the user inputs thereafter is of that color. We want to avoid the user having
to change font colors manually upon selecting one of the initial 4
alternatives. Although I found code to change the font color from the
“formatting toolbarâ€, I was quickly discouraged when testing the code.

The problem is that as soon as the user positions the cursor in the cell
where he wants to type, the font color switches back to automatic (it doesn’t
show a font color change at the “formatting toolâ€, but if you click on it,
you see that the automatic color has been selected). As it is, the code would
serve its purpose if the document didn’t use tables and you moved from line
to line by using enter. Only in this case does the font color change holds.

Any suggestion as to how could I accomplish this task is greatly appreciated?
 
G

Greg Maxey

You would need to set the font color of the entire table to the
desired color:

Sub ScratchMacro()
Dim oTbl As Table
Set oTbl = Selection.Tables(1)
oTbl.Range.Font.Color = wdColorRed
End Sub
 
T

Tony Jollans

Or the font colour of the styles used in table cells.

Depending on how you have set up your tables and whether or not you are
using table styles this could be quite a lot of things to change.

If you are using Word 2007 you might be able to make it simpler with some
imaginative use of themes.

--
Enjoy,
Tony

You would need to set the font color of the entire table to the
desired color:

Sub ScratchMacro()
Dim oTbl As Table
Set oTbl = Selection.Tables(1)
oTbl.Range.Font.Color = wdColorRed
End Sub
 
J

JuanManuel

Greg Maxey said:
You would need to set the font color of the entire table to the
desired color:

Sub ScratchMacro()
Dim oTbl As Table
Set oTbl = Selection.Tables(1)
oTbl.Range.Font.Color = wdColorRed
End Sub

Hi Greg,
Thanks for your help but I wish the problem was that simple. The problem
with your code is that it instantly changes everything in the table to a
particular color. My intent is to force the user to use a particular color
for the modifications he makes depending on which radiobutton is chosen.

For example, picture a 3 x 3 table with its first column and first row
filled in with text in black (this must stay the same). If today I were to
select the "radiobutton 1", I wouldn't want to change the whole table to a
single font color, but I'd like to force the user to write in red as long as
"radiobutton 1" is kept selected. Let's suppose he writes in all of the
remaining cells (excluding row 1 and column 1). Then, the table should have
black text in row 1 and column 1 but red text in every other cell.

He saves the document and opens it tomorrow. He selects "radiobutton 2". Now
I'd like to force the user to write in blue as long as "radiobutton 2" is
kept selected. Since every cell in the table has text in it already, he has
to add additional text to, let's say, cell (2, 2). Since this cell has text
already, he writes after the period of the last word that was written in this
cell in red. Whatever he adds needs to be blue. Then, the table should have
black text in row 1 and column 1 but red text in every other cell, except in
cell (2, 2). This cell should have both red and blue text.

I hope this clarifies my intentions.

Is there any way to accomplish this?

As far as any ideas, I've thought that it might be possible to intercept an
event like save or print, that goes through each cell of every table in the
activedocument and changes the font color of the text that has been written
during that specific session.

let's consider the same example as above with the 3x3 table. Let's suppose
this table was created and saved 5 days ago with row 1 and column 1
completely filled in. If today I were to select the "radiobutton 1", I would
write in whichever color was selected, but upon saving or printing the
document, I'd like to have some code that goes through each cell of every
table in the activedocument and changes the font color of the text that has
been written during that specific session to red. In this way, I'd make sure
that everything that the user inputs during a specific session gets saved in
the same color. Furthermore, since the users would only select one of the
four radiobuttons per session, this ensures that everything written while one
particular radiobutton is selected gets saved in a particular color.

Is there any way to accomplish this: To set up a condition for the "changing
font color event" based on how long ago was the text written?.
 
T

Tony Jollans

This is complex but you may be able to do it by using Track Changes
(assuming you don't also want to use that for something else). Whenever a
radiobutton is pressed (or at any other time you like) you could go through
all the changes, format them permanently with the chosen colour and then
accept them. If you wished you could alter the change tracking options so
that changes appeared in your chosen colour before you made the permanent
change.

There may be an alternate way of processing using the rsids in the xml if
your documents are in Word 2007 format - and even a theoretical equivalent
in earlier versions but that really would be hard work (if possible at all).
 
J

JuanManuel

Tony,
Your idea of using the Tracking Changes feature sounds enticing. I would
code something that formats the changes with a different color depending on
the radiobutton selected. The idea though, would be to never accept the
changes so that the different colours are kept permanently in the document
(This is exactly the purpose of my project).

Nevertheless I am a complete newbie in VBA. My first step is obviously
writing some code that turns on the "tracking changes" feature upon selecting
a radiobutton. I tried to record a macro to do this and it didn't work. I
basically started recording, then went to the toolbar and pressed on "track
changes". Then I assigned this macro to the clicking event of a radiobutton.
Nevertheless, it doesn't work, an error pops out.

Any ideas on how could I accomplish this?

Thank you,

Juan
 
T

Tony Jollans

I was just suggesting (ab)using Track Changes as a means to an end - and it
would only work if you could accept the changes in one colour before moving
on to another.

If you are actually trying to track changes then just use the track changes
option instead of trying to reinvent the wheel. If you want changes by Word
session, you have less control over the colours - the options are one colour
per type of change (insert, delete, etc.) OR one colour per user and if you
use one colour per user, (a) it only works up to 8 users before duplicating
colours and (b) you can't control the colours yourself. You _could_ change
the user id each time if everything else met your requirements but it would
be another abuse :) Alternatively, as changes are timestamped you could go
through them hazarding informed guesses - it really depends on your ultimate
goal, and, maybe, on the type of changes you have (or want to allow).

If you want to have track changes on all the time, you don't really need to
switch it on in code but the code is:

ActiveDocument.TrackRevisions = True
 
J

JuanManuel

Tony,
Before this discussion I didn't even know there was something such as
tracking changes, but now I realize this is pretty much what I'm trying to
do. Nevetheless, I have the following issues:

1. You said: "Whenever a radiobutton is pressed (or at any other time you
like) you could go through all the changes, format them permanently with the
chosen colour and then accept them".

This would accomplish my goal, but how do I refer programatically to the
changes made in order to format them with a specific colour?

It would be great if, upon saving, the "save" event could trigger a
procedure that goes ONLY through the changes made and formats them with a
specific colour (depending on the radiobutton selected) and then accepts them
so that they become permanent, but in a different colour.

What's the code to format ONLY the changes with a different colour?

The only changes that I want to allow are additions, can I code something to
restrict the user to only add to the original document?

Thank you,

Juan
 
J

JuanManuel

Tony,

I am testing the following code:

Sub AcceptOnlyAdditionChanges()
Dim oChg As Revision
For Each oChg In ActiveDocument.Revisions
If oChg.Type = wdRevisionInsert Then
oChg.Accept
oChg.Style = "RedStyle"
Else
'Do nothing
End If

Next oChg
End Sub

Nevertheless, the line: oChg.Style = "RedStyle" shows me an error stating:
Run-time error "5852": requested object is not available.

I am trying to format ONLY the additions with a specific style that I
created ("RedStyle"). The code works fine without the mentioned line of code,
except that it formats the additions in the same color as the rest of the
table upon accepting.

Thanks,

Juan
 
T

Tony Jollans

Looks like you're doing well, but there are a coiuple of things in the code
that need changing.

The object that is not available is the oChg revision becuase you have just
accepted it and thus it is no longer a revision. You need to set the style
before accepting the change. You wil also need to set the style of the Range
of the Change, not the Change itself (a subtle diffference, I know), and ..

.. setting the style is, itself, a revision. You really want to be running
your code with track changes turned off.

Putting it all together you get

Sub AcceptOnlyAdditionChanges()
'===========================
ActiveDocument.TrackRevisions = False
'===========================
Dim oChg As Revision
For Each oChg In ActiveDocument.Revisions
If oChg.Type = wdRevisionInsert Then
'===========================
oChg.Range.Style = "RedStyle"
'===========================
oChg.Accept

Else
'Do nothing
End If

Next oChg
'===========================
ActiveDocument.TrackRevisions = True
'===========================
End Sub
 
J

JuanManuel

Tony,

Thanks for your help and interest.

I tried running the code you provided both with track changes on and then
with track changes off and it gives an error on the line:

"ActiveDocument.TrackRevisions = False"

The message says: Run-time error 4605: this command is not available

What could be going on? I don't see why this command would not be a
available. I am using word 2003.

Thanks
 
T

Tony Jollans

The command is not available tends to mean you are in a state where it can't
be done - in the middle of doing something else. When (and how) are you
running the code and what else is going on - from a toolbar, a userform, in
an event code?
 
J

JuanManuel

Tony,
I did some troubleshooting and noticed that the code does not work only when
triggered by the clicking of a button placed directly in the word document.
When I run the code directly from the vba editor after having placed the
cursor in any line of the word document, it does work.

It seems that the position of the cursor has an effect on whether it works
or not. Since upon clicking the button, the cursor is automatically taken to
the button itself (the cursor leaves the line in the document where it was),
then it doesn,t work.

How can I solve this problem?

Thank you,

Juan
 
T

Tony Jollans

Hi Juan,

Grrr... ActiveX controls :)

Set the TakeFocusOnClick property of the button to False.
 
J

JuanManuel

Hi Tony,
I had not bothered you for a while. Now I am testing the following
code (modified version of the one provided by another MVP) and it is always
going through the "else".

The original purpose was that, upon the selection of a radio button, the
program enables track changes IF and ONLY IF the cursor is placed in a line
with no text.

'==================== CODE ==========================

Private Sub RadBtnTMS1_Click()
Dim rngLine As Range

Set rngLine = Selection.Bookmarks("\Line").Range

If AscW(Trim(rngLine.Text)) = 11 Or AscW(Trim(rngLine.Text)) = 13 Then
'If cursor is placed in an empty line within a cell then
ActiveDocument.TrackRevisions = True
Else
RadBtnTMS1.Value = False
'Unselect the radio button

MsgBox "Cursor needs to be placed in a new line before selecting a
TMS"
Exit Sub
End If

End Sub

'==================== END OF CODE ======================

Even when I place the cursor in a new line of the document, it is displaying
the message box.

What could be going on?

Thank you, Juan
 
T

Tony Jollans

I don't think you can do this because the radio button is the Selection.
Does it need to be a radio button (which you're not really using as a radio
button should be used)? A command button with Take Focus on Click set to
False would work. With a real effort you could almost make it look like a
radio button (not that I would advise it)!
 
J

JuanManuel

Based on the code you provided, I wrote the following:

Sub AcceptOnlyAdditionChanges()
ActiveDocument.TrackRevisions = False
'====================================
Dim oChg As Revision
For Each oChg In ActiveDocument.Revisions
If oChg.Type = wdRevisionInsert Then
'====================================

If RadBtnTMS1.Value = True Then
oChg.Range.Style = "TMS1"
ElseIf RadBtnTMS2.Value = True Then
oChg.Range.Style = "TMS2"
ElseIf RadBtnTMS3.Value = True Then
oChg.Range.Style = "TMS3"
Else: oChg.Range.Style = "TMS4"
End If

'====================================
oChg.Accept

Else
'Do Nothing
End If

Next oChg
'====================================
ActiveDocument.TrackRevisions = True

ActiveDocument.Save

Call ResetAllRadioButtonsAndCheckboxes_TurnTrackChangesOff

End Sub

The code is supposed to format ONLY the addition changes made during the
current session and contingent on the radio button selected. For instance,
let's suppose that today I write "TMS1." in a cell or anywhere in the
document. Based on the radiobutton selected, this text gets formatted in the
style ("TMS1"). Tommorrow, I open the document and select a different
radiobutton than the one selected the day before. I start typing "TMS2."
right after the period in "TMS1"(written yesterday), so that the final text
is "TMS1. TMS2.".

I would like the code to only format only "TMS2." to the style ("TMS2"),
since this was the sole change done in the current session.

Nevertheless the code actually formats the whole text "TMS1. TMS2." to the
style ("TMS2").

Is there any way to accomplish what I'm trying to do?

Thank you again Tony
 
T

Tony Jollans

Are you using Character Styles? It rather sounds like you are using
Paragraph Styles instead.
 
J

JuanManuel

Thanks for the last help Tony. I was actually using Paragraph Styles...

Now, I wanted to bother you once again.

I have this long template which I am protecting by code upon opening. Now,
I'd only like to protect from page 2 onwards (leaving page 1 unprotected).
How can I do this?

Thank you Juan
 
T

Tony Jollans

If you're talking about protection for Forms, put a section break in at the
end of page 1 - and then you can specify which sections are to be protected
when you turn it on.
 

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