Using DocVariables

G

Greg Maxey

I am monkeying around with a template that will let me make documents to
show/hide details, instructions, etc.

I am using an IF field (e.g., {IF {DOCPROPERTY ShowHide1} = "Show"{Autotext
Event1}}

It is working OK, but I need some advice on the macros. The basic problem
is that as I add events I need to define the docvariables on first use. My
first stab was the following without the amplifying directions and the
result of course was an error indicating the Object (ShowHide3) had been
deleted. The real truth is that it had never been created. The solution
was to create it once using hte immediate window as incidcated: (Please
read on)

Sub ShowHideEvent3()

Dim Toggle As String

'This macro is simplified. Create the initial document variable by using
the following code
'in the immediate window:
'ActiveDocument.Variables.Add Name:="ShowHide3", Value:="Hide"

Toggle = ActiveDocument.Variables("ShowHide3").Value
If Toggle = "Show" Then
ActiveDocument.Variables("ShowHide3").Value = "Hide"
Else
ActiveDocument.Variables("ShowHide3").Value = "Show"
End If
ActiveDocument.Fields.Update

End Sub

Next, with some earlier help from Dave Lett, I adapted the above to use an
error handler:

Sub ShowHideEvent1()

Dim Toggle As String

'This macro uses a error handler and resume command to create the variable
on first use.

Dim err_handler

On Error GoTo err_handler
Toggle = ActiveDocument.Variables("ShowHide1").Value
If Toggle = "Show" Then
ActiveDocument.Variables("ShowHide1").Value = "Hide"
Else
ActiveDocument.Variables("ShowHide1").Value = "Show"
End If
ActiveDocument.Fields.Update
End

err_handler:
ActiveDocument.Variables.Add Name:="ShowHide1", Value:="Hide"
Resume

End Sub

Dave Lett not to settle for such an ugly solution suggested something like:

Sub ShowHideEvent2()

'This macro searches for the variable name and if not found creates it.

Dim bExists As Boolean
Dim Toggle As String
Dim oVar As Variable

For Each oVar In ActiveDocument.Variables
If oVar.Name = "ShowHide2" Then
bExists = True
End If
Next oVar
If bExists = False Then
ActiveDocument.Variables.Add Name:="ShowHide2", Value:="Hide"
End If

Toggle = ActiveDocument.Variables("ShowHide2").Value
If Toggle = "Show" Then
ActiveDocument.Variables("ShowHide2").Value = "Hide"
Else
ActiveDocument.Variables("ShowHide2").Value = "Show"
End If
ActiveDocument.Fields.Update
End Sub

Each method seems to work, but doesn't feel right. Am I looking for
something that just isn't there?Please advise.
 
J

Jezebel

As I understand it, the task is this: If ShowHide1 is present and equal to
"Hide" then set it to "Show", otherwise set it to "Hide".


Const pVarName = "ShowHide1"
Const pValue_1 = "Hide"
Const pValue_2 = "Show"

Dim pValue as string

'Retrieve the existing value if any, and delete the variable
On error resume next
pValue = ActiveDocument.Variables(pVarName)
ActiveDocument.Variables(pVarName).Delete
On error goto 0

'Set the new value
if pValue = pValue_1 then 'Set to Show if currently Hide
pValue = pValue_2
else 'Set to Hide if anything
else
pValue = pValue_1
end if

'Add the value
ActiveDocument.Variables.Add Name:=pVarName, Value:=pValue


If you have a number of these variables to deal with you might want to
replace the constants with function arguments; but in any case, as a matter
of good programming avoid literal strings in your code as much as possible.
They are a source of bugs.

Separately, perhaps it's just a typo but your IF field is using a
DocProperty while the rest of your post is about DocVariables. Also your
UpdateFields instruction will update fields only in the body of the
document, not in headers and footers. Is that a problem in this case?
 
G

Greg Maxey

Jezebel,

It is late and I will have to recharge batteries before attempting to
understand what you have provided here. Thanks.

Yes, the IF field has a typo. In use it is a DOCVARIABLE. Copy all wrt to
the update fields. Use is limited to main story text.
 
G

Greg Maxey

Jezebel,

The objective was (or I thought was) if the variable ShowHide1 isn't present
the first time the macro is run then make it present and set to Hide.
Thereafter toggle between Hide and Show.

Curiosity exhausted the cat and I applied you code tonight. I have only
applied it to one event and it seems like the best solution yet :).

I only dabble in VBA from time to time. Would you clarify your lines

"On error resume next" Next what?

and

"On error GoTo 0" Where is 0?

By avoiding literal strings do you means strings such as Dim Toggle as
String?

Thanks
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Greg Maxey > écrivait :
In this message, < Greg Maxey > wrote:

|| Jezebel,
||
|| The objective was (or I thought was) if the variable ShowHide1 isn't
present
|| the first time the macro is run then make it present and set to Hide.
|| Thereafter toggle between Hide and Show.
||
|| Curiosity exhausted the cat and I applied you code tonight. I have only
|| applied it to one event and it seems like the best solution yet :).
||
|| I only dabble in VBA from time to time. Would you clarify your lines
||
|| "On error resume next" Next what?

This kind of means:
If there is an error, ignore it and continue on to the next line of code.

||
|| and
||
|| "On error GoTo 0" Where is 0?

This resets error handling to its default behaviour. So, for example, you
may know that a certain line of code will sometimes throw an error that has
no serious impact on the rest of the procedure, or that is even expected, so
you throw in a
On Error Resume Next
But from that point on, all error in the running code will be ignored...
which is not necessarily a good thing!
So as soon as the "Ignore the errors" stage is over, use
On Error GoTo 0
to reset the default behaviour.

So, in Jezebel's code:
'_______________________________________
On Error Resume Next
pValue = ActiveDocument.Variables(pVarName)
ActiveDocument.Variables(pVarName).Delete
On Error GoTo 0
'_______________________________________

pValue = ActiveDocument.Variables(pVarName)
ActiveDocument.Variables(pVarName).Delete
will both throw an error if the variable does not exist...If that is the
case, this error is ignored.
But you do not want to ignore all other errors that could occur later in the
code...
So
On Error GoTo 0
is used to reset the error handling.

Look up the Err and Error key words in the VBA on line help... There are
some good examples.

||
|| By avoiding literal strings do you means strings such as Dim Toggle as
|| String?

Yes, but also, from your code:
'_______________________________________
Toggle = ActiveDocument.Variables("ShowHide3").Value
If Toggle = "Show" Then
ActiveDocument.Variables("ShowHide3").Value = "Hide"
Else
ActiveDocument.Variables("ShowHide3").Value = "Show"
End If
'_______________________________________

You use
"ShowHide3"
three times in that excerpt.
This will eventually lead to typos. If the code grows and you need to
reference this elsewhere, you will have to add that text again in the new
code, more errors are possible... But the worst is when you have to change
the label, you have to track down all the instances and replace them.... If
you forget one, you get unexpected results and it can take you a while to
figure out why... And when you do, you just want to shoot yourself!

So, try something like Jezebel suggested:
'_______________________________________
Const pVarName = "ShowHide3"

Toggle = ActiveDocument.Variables(pVarName).Value
If Toggle = "Show" Then
ActiveDocument.Variables(pVarName).Value = "Hide"
Else
ActiveDocument.Variables(pVarName).Value = "Show"
End If
'_______________________________________

This way, you just type the label once, and if you throw in an
Option Explicit
in the declaration section, typos on variables and constants will be
detected and highlighted by the compiler.

HTH

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Greg Maxey > écrivait :
In this message, < Greg Maxey > wrote:

|| Jezebel/JGM,
||
|| This is better than School of the Boat. Thanks.
||

Just curious.... what is "School of the Boat"?

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
G

Greg

Ah yes, that could need explaining. Submarines are called
boats not ships. Submariners have a lot to learn during
their first six months or so on board. The learning curve
is steep and sometimes said to like drinking from a 2-1/2
pressurized fire hose. Today “School of the Boat” is a
semi-formal training session wherein new personnel are
thought ship operating procedures and systems. In days of
yore (not really that long ago), “School of the Boat” was
more often than not a one-on-one affair and might include
less pleasant instructional sessions. Sessions where the
individual is schooled in a manner so that learning
certainly takes place. School of the Boat is trade school
sort of like Life University.
 
G

Greg

Jezebel, JGM, Dave Lett, and Chad

Thanks for all of the help here. After looking at all of
the suggestions, it seems like a slightly modified version
of Jezebel's method is most appropriate for my purposes.
JGM, could you provide a another gentle nudge wrt
the "options explicit" feature you mentioned?

I am using these sequentially numbered macros, the
resulting docVariables, and IF fields to toggle the
expansion and collaspe of AUTOTEXT (to provide "event"
details, instructions, answers to question, etc.) The
document opens with all "events" collasped. I noticed that
if I added an event to the document on "first use" of
Jezebel's code the expansion would not occur. I had to
fire the macro twice and from there on out everything was
perfect. This was due to the String being initially
empty. Just a nit I know, but I figured I could eliminate
the nit by altering the code slightly with and IF ... OR
and changing the initial values around. The result:

Sub ShowHideEvent4()

Const pVarName = "ShowHide4"
Const pValue_1 = "Show"
Const pValue_2 = "Hide"

Dim pValue As String

On Error Resume Next
pValue = ActiveDocument.Variables(pVarName)
ActiveDocument.Variables(pVarName).Delete
On Error GoTo 0 'GoTo 0

If pValue = pValue_2 Or pValue = "" Then
pValue = pValue_1
Else
pValue = pValue_2
End If

ActiveDocument.Variables.Add Name:=pVarName, Value:=pValue
ActiveDocument.Fields.Update
End Sub
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Greg > écrivait :
In this message, < Greg > wrote:

| Ah yes, that could need explaining. Submarines are called
| boats not ships. Submariners have a lot to learn during
| their first six months or so on board. The learning curve
| is steep and sometimes said to like drinking from a 2-1/2
| pressurized fire hose. Today “School of the Boat” is a
| semi-formal training session wherein new personnel are
| thought ship operating procedures and systems. In days of
| yore (not really that long ago), “School of the Boat” was
| more often than not a one-on-one affair and might include
| less pleasant instructional sessions. Sessions where the
| individual is schooled in a manner so that learning
| certainly takes place. School of the Boat is trade school
| sort of like Life University.
|

I will go to bed more intelligent tonight!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Greg > écrivait :
In this message, < Greg > wrote:

|| Jezebel, JGM, Dave Lett, and Chad
||
|| Thanks for all of the help here. After looking at all of
|| the suggestions, it seems like a slightly modified version
|| of Jezebel's method is most appropriate for my purposes.
|| JGM, could you provide a another gentle nudge wrt
|| the "options explicit" feature you mentioned?
||

Option Explicit at the top of a module just makes the compiler reject (I
mean it stops compiling, throws an error message and highlight the culprit)
undeclared variables constants, methods, functions, etc.
Look it up in the Word VBA help.

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
R

RBM

Maybe...and maybe not. That's a separate issue :) It sounds like th
School of Hard Knocks to me.
 
J

Jezebel

The reference to 'strings' in my final point is to lines like

.....Value = "Hide"

In your code, the values "Hide" and "Show" have special meaning. By entering
the string literally in the line of code, you create a potential problem:
namely that at one point in your code you set the value and at another you
read it and compare it. Now if you make a typo (obviously a little unlikely
in this case, but possible none the less) and misspell the word differently
in the two usages, your code will still run perfectly well, but the
comparison will always fail.

If instead you declare a constant and use that in place of the literal
string then a) there is no possibility of a typo, and b) if you decide to
use different values (such as TRUE and FALSE in place of SHOW and HIDE) you
need only change the constant.
 

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