Word Hacks [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Word Hacks [Electronic resources] - نسخه متنی

Andrew Savikas

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Hack 79 Convert Field Codes to Text and Back Again

When experimenting with fields, or using
example fields culled from the Internet, it's often
helpful to have an easy way to convert field codes to plain text, and
vice versa.

As the other hacks in this chapter show, it can be difficult to
represent field codes outside of Word (such as in a printed book)
because of those special field braces unique to Word. For example,
what if you want to post a particularly troublesome field to a
newsgroup in the hopes of finding some help? (For a list of web sites
with Word-related information and discussion groups, see
Where to Learn More in the Preface.) While
it's relatively simple to convert a
field's result to plain textjust select the
field and press Ctrl-Shift-F9converting the field code to text
is a trickier proposition.


A field's result is the text it
displays after performing its work, such as the current page number
or today's date. The field code
is the special set of instructions a field uses to get that result.
For example, one of the simplest field codes is simply
DATE, which gets the current date. To see a field
code in action, press Ctrl-F9 to insert a pair of empty field braces
in a document. Then with your cursor between those braces, type the
word DATE (you don't need to use
all caps, but it's how field codes are typically
shown). Select the field you just created and press F9 to update it,
displaying today's date.

The macros in this hack use some heavy-duty VBA to quickly and
accurately convert even a complex set of nested fields to plain text
or convert some plain text (with the location of those special field
braces indicated by regular braces) into fields.


8.11.1 Converting Field Codes into Plain Text


Conceptually, you
need to replace each
field with just its code, surrounded by a set of regular text braces
({}). This
is trickier than it sounds, because if a field
has any other fields nested inside it, you need to convert those to
text first.

The code used in this hack to
convert
the fields to text is fairly simple, though it uses
recursionone of VBA's
more advanced features. Recursion means that a function can call
itself, and it's a common feature among programming
languages (see the sidebar
A Recursion Primer
for more information).


A Recursion Primer


If you're not interested
in
how the guts of the macros in this hack work, or if
you're already familiar with recursion, feel free to
skip this sidebar. However, if you've never
encountered recursion before or just aren't sure you
understand it, read on.

Recursion lets you use very simple code to perform complicated tasks.
This is accomplished by breaking the task down into bite-sized pieces
and then writing code that tackles the task, one small bite at a time
until it's all gone.

For example, say you need a macro to add all the digits from 1 to 4.
At face value, it takes just one line:

Sub SumDigits( )
MsgBox 1+2+3+4
End Sub

But how do you write a macro that can sum all the digits from 1 to
1000 as easily as 1 to 10?

Let's say you want your program to add all the
digits from 1 to k, where k
is any whole number. Here's one
possible algorithm for the problem:

If k is 1, then the answer is just
k.

If k is greater than 1, the answer is
k plus the sum of all the digits from 1 to
k - 1.

So how do you calculate the sum of all the digits from 1 to
k -1 in Step 2? Use your macro of course! Sound
like a bit of circular logic? Well, in a way it is, which is the
whole point of recursion. Here's that algorithm as a
VBA procedure, followed by a macro to demonstrate it. Put both in the
template of your choice and step through the code as it runs in Visual Basic Editor

Function SumDigits(k As Long) As Long
If k = 1 Then
SumDigits = k
Else
SumDigits = k + SumDigits(k - 1)
End If
End Function
Sub SumDigitsDemo( )
Dim sInput As String
sInput = InputBox("Add all digits from 1 to ?")
If Len(sInput) = 0 Then Exit Sub
MsgBox SumDigits(CLng(sInput))
End Sub

The following macro converts the field codes of any selected fields
to plain text, and surrounds the code for each field with standard
brace characters, ({}). The code use the
FieldCodeToText function
to recursively examine all the fields in a range (in this case the
range of the current selection). Place both macros in the template of
your choice.

Sub ConvertSelectedFieldsToText( )
Call FieldCodeToText(Selection.Range)
End Sub
Function FieldCodeToText(rngOrig As Range)
Dim rng As Range
Do
If rngOrig.Fields.Count <= 1 Then
' Not more than one field in selection,
' so replace first field in selection
' with its code surrounded by braces
rngOrig.Text = "{" & _
rngOrig.Fields(1).Code.Text & "}"
Else
' More than one field in selection,
' move to next field and check again,
' until there's only one field left
Set rng = rngOrig.Duplicate
rngOrig.Fields(2).Select
Call FieldCodeToText(Selection.Range)
rng.Select
End If
Loop Until rngOrig.Fields.Count = 0
End Function


8.11.2 Converting Plain Text into Fields


For this conversion,
the macro needs to
do the reverse of what happened in the last section. This time
around, any set of standard text braces ({}) and
the text between them, should be replaced with a Word field. The
field code is the text between the braces. The braces should be
discarded.

The following macro converts any plain text surrounded with standard
brace characters ({}) into
"live" Word fields. The code uses
the
TextToFieldCode function to ensure that all fields
are created in the correct order, which can be tricky business when
there are several nested fields. Place both macros in the template of
your choice.

Sub ConvertSelectedTextToFields( )
Call TextToFieldCodes(Selection.Range)
End Sub
Function TextToFieldCodes(rngOrig As Range)
Dim rng As Range
Dim fld As Field
Dim str As String
Do
Set rng = rngOrig.Duplicate
str = rng.Text
' If there are any braces remaining in the range, except
' for the first and last characters, then there's still
' some pseuodo-fields to process, so collapse range to
' next set of braces and check again
If InStr(Mid(str, 2, Len(str) - 2), "}") <> 0 Or _
InStr(Mid(str, 2, Len(str) - 2), "{") <> 0 Then
' Move the beginning of the range forward
' until it's at a left brace
Do While InStr(Right(str, Len(str) - 1), "{") > 0
rng.MoveStart unit:=wdCharacter, Count:=1
rng.MoveStartUntil cset:="{"
str = rng.Text
Loop
' Move the end of the range backward until it's at a right brace
Do While InStr(Left(str, Len(str) - 1), "}") > 0
rng.MoveEnd unit:=wdCharacter, Count:=-1
rng.MoveEndUntil cset:="}", Count:=-Len(str)
str = rng.Text
Loop
' If either end of the range isn't a brace character,
' there's been an error.
If Left(str, 1) <> "{" Or Right(str, 1) <> "}" Then
GoTo ERR_HANDLER
End If
' Continue searching for brace characters in this range
' with a recursive call to this function
Call TextToFieldCodes(rng)
Else
' No brace characters were found between
' the first and last characters
' If either end of the range isn't a brace character,
' there's been an error.
If Left(str, 1) <> "{" Or Right(str, 1) <> "}" Then
GoTo ERR_HANDLER
End If
' Delete the braces on the ends of the range
rng.Characters(1).Delete
rng.Characters(rng.Characters.Count).Delete
' Cut the range and paste it in as the code
' of a new empty field, which preserves any
' codes in the range, as well as formatting
rng.Cut
Set fld = rng.Fields.Add(Range:=rng, _
Type:=wdFieldEmpty, _
Text:=", _
PreserveFormatting:=False)
fld.Code.Paste
End If
' As long as there are braces left in the original range,
' keep trying to turn them into fields
Loop While InStr(rngOrig.Text, "}") <> 0 Or _
InStrRev(rngOrig.Text, "{") <> 0
Exit Function
ERR_HANDLER:
rng.Select
If Left(rng.Text, 1) <> "{" Then
MsgBox "Missing an expected left brace ( { )", vbCritical
ElseIf Right(rng.Text, 1) <> "}" Then
MsgBox "Missing an expected right brace ( } )", vbCritical
Else
MsgBox "An unknown error occurred", vbCritical
End If
End Function


8.11.3 Running the Hack


To see these macros in action, first make sure the template
you've stored them in is open. Then, in a blank
document based on the template in which you've
stored the macros, type Ctrl-F9 twice to insert two sets of field
braces, one nested inside the other (you'll see
actual field braces, not standard text braces):

{ { } }

Type the text QUOTE and DATE
between the field braces as follows:

{ QUOTE { DATE } }

Next, select the fields and press F9. You should see
today's date displayed. Select the fields again,
then right-click and select Toggle Field Codes. Now
you'll see the field codes again. With both fields
selected, run the ConvertSelectedFieldsToText
macro shown earlier, which replaces the fields with their field codes
as plain text, surrounded by standard text braces.

Now select the text from the first brace to the last and run the
ConvertSelectedTextToFields macro shown earlier,
which replaces the plain text with actual fields, bringing you back
to where you started.


/ 162