Chapter 18


This chapter contains helpful tips, tricks, and shortcuts for working with macros. You'll also find the many routines presented in the following pages beneficial when writing your own macros.



Most macros can be terminated by pressing [F1], the Cancel key. Those macros that use the {CANCEL OFF} key, or "trap" the Cancel key using a keyboard loop, may not respond when you press the [F1] key. To stop these macros, press [Ctrl]-[Break] (the Break key is normally located above the cursor or numeric keypad). To make certain that you have terminated the macro, press [Ctrl]-[F10]. If you see the "Define Macro" prompt on the bottom of the screen, all macro execution has been terminated. Press the Cancel key to cancel macro definition.


Any system of more than a few dozen macros cries out for some type of naming and filing scheme. If it takes you a minute or so to locate the macro you need, then your name and storage system needs overhauling. You may wish to adopt some or all of these techniques for easily and quickly locating the macro you need to use.

Alt-Letter Combination Macros

Although it may be obvious, it's worth repeating here: use Alt-letter combinations for those macros you access most often. Whenever possible, choose a letter than mnemonically represents the macro. For example, use [Alt]-S for Save, [Alt]-P for Print, and [Alt]-R for Rewrite screen. Chances are that not all of your Alt-letter names will match the function of your macros. Until you can memorize all of the Alt-keys you have created, keep a list handy by your computer.

It's always a good idea to leave one or two Alt-letter keys open, in case you want to expand your macro system. If you find that you use a regular named macro more often than you used to, you can always rename with an Alt-letter combination. To do so, find the macro you want from the List Files directory. Select it and rename it ALT#.WPM, where # is one of the alphabet keys. For instance, ALTP.WPM is the macro file for [Alt]-P and ALTE.WPM is the macro file for [Alt]-E.

By the same token, Alt-letter macros you no longer use as much can be given file names. To change an Alt-letter macro, find its file in the List file directory and rename it. Remember to add the .WPM file extension or WordPerfect won't know that it's a macro.

IMPORTANT NOTE: Nested and chained macros refer to other macros by name. If you alter the name of a macro that is used in a nested or chained instruction, be sure to modify all other macros that may be affected by the change. You can prevent problems later on by noting the particulars of the construction of the macro in a macro log.


Using Keyboard Layouts

WordPerfect's keyboard layout feature lets you assign any key on the keyboard to a macro function. Most often you'll assign Alt- and Ctrl-key combinations to macros. As with Alt-letter file macros (described above), select letters of the alphabet that mnemonically represent the function of the macro.

If you forget which keys activate which macros, view the Keyboard Layout editing screen (press the Setup key, then press K and E). Descriptions for your keyboard macros (assuming you provided them in the first place) are listed beside each key.

When an Alt-letter combination is duplicated in both keyboard layout and named macro file, WordPerfect will always select the keyboard macro first.

Named Macros

The object of naming macros is to provide a moniker that's short enough to allow you to type it quickly, but long enough so that its function is clear. DOS limits file names to no more than eight characters, which can lead to problems when trying to name your macros. Avoid cryptic names or names that are too similar to others already in use. Borrow the naming techniques of the military and use acronyms and abbreviated forms whenever possible. Some examples:

Some of the macros described in this book include a version number, such as BKPRINT1.WPM and BKPRINT2.WPM. These names were chosen to show you that the macros are similar to one another, but differ in features and capabilities. Once you have decided which of the various versions of the macro you want to use, rename to make it easier for you to remember.

Using Subdirectories

Despite the best naming efforts on your part, a large macro library will become unusable if you don't devise some way to classify the macros according to application. You may want to use DOS subdirectories to sort out your macro collection. Refer to any book on DOS if you are not sure how to make and use subdirectories.

At the very least, you should use one main macros directory on your hard disk, located as a subdirectory under \WP51 (or whatever you call your WordPerfect 5.1 directory). Although the name of your main macros subdirectory is completely up to you, most people use MACRO\ or MACROS\.

With macros in a directory of their own you need to tell WordPerfect where to find them. The most straightforward approach is to use the Location of Files option, under the Setup key.

  1. Press Setup ([Shift]-[F1]).
  2. Press L for Location of Files.
  3. Press K for Keyboard/Macro files.
  4. Enter the subdirectory that contains the files (if the subdirectory is not under the WordPerfect main directory, provide a full path name, such as \SPECIAL\MACROS\NEW. Press [Enter] when done.
  5. Press the Exit key to return to the editing screen.

Now, no matter what directory you make current in WordPerfect (using the List files key), the program will always look for macros in the directory you indicated. If the macro can't be found in the directory you indicated, the program makes one final check in the main WordPerfect directory. If the macro can be found there, it's used. If it can't be found, WordPerfect reports a file not found error.

IMPORTANT NOTE: The location of your macro files is recorded in the WP{WP}.SET file, which also tracks all of the other setup options you make with WordPerfect, including default printer, units of measurement, display adapter, and so forth. If your WP{WP}.SET file is lost, erased, or damaged, WordPerfect will no longer know where to look for macro files. If this occurs, merely re-enter the location of the files (and re-select other setup options). A new WP{WP}.SET file will be made for you. As a precaution, after you've set up WordPerfect the way you want, make a copy of the WP{WP}.SET file and keep the copy in a safe place. You then have a mirror image of the original copy should something happen to it.

You can always access macros located in other directories (or on other disks). At the Macro: prompt, merely provide the directory path. Here's an example of how you'd access a macro named CHAR.WPM (for script character format) in a subdirectory called SCRIPT:

Key Sequence What it Does
1. [Alt]-[F10] Invokes macro playback command.
2. SCRIPT\CHAR Indicates subdirectory path and macro file name (subdirectory and file name separated by a backslash).
3. [Enter] Runs the macro.

Entering the subdirectory name each time you want to use a macro can be tedious, but you can avoid the extra keystrokes by writing short "subdirectory prefix" macros that automatically add the DOS path you want to access. Use Alt-letter names for convenience. For example, use [Alt]-S to start the SCRIPT subdirectory. After [Alt]-S runs, you can enter the name of the macro you want to use.

Key Sequence What it Does
1. [Ctrl]-[F10] Starts macro definition.
2. [Alt]-S Names macro ALTS.WPM.
3. Script subdir. prefix
Describes macro.
4. [Alt]-[F10] Invokes macro playback.
5. script\ Indicates subdirectory to use.
6. [Ctrl]-[F10] Ends macro definition.

When you press [Alt]-S, WordPerfect starts macro playback and adds the "script\" path name for you. Finish the process by typing CHAR and pressing [Enter].

Backup Copies

Any number of disasters can happen to macros while they reside on your computer disks. Most hard disk users have experienced at least one "crash" during the life of their computer where valuable data was lost due to a malfunction or a simple quirk. Too, floppy disks can be accidentally erased or damaged, and their contents lost forever.

Always make at least one backup copy of your macros on a separate MACROS diskette. Store the MACROS diskette in a safe place, preferably away from your regular work area. Then, if something should happen to the original macro, you can replace it with the copy. Be sure to periodically update the MACROS backup diskette so that it contains all the newly created and edited versions of your macros.

If you create many macros, you may need more than one diskette to hold them all. Label them clearly. For ease of use, create a printed copy of the contents of each disk, so that you know which disk contains the macro you want to use. WordPerfect itself provides the capability:

  1. Insert the diskette into drive A: or B:, as needed.
  2. Press the List files key ([F5]).
  3. At the directory prompt, press A: or B: for the A: or B: floppy drive. Press [Enter].
  4. With the directory of the floppy disk on the screen, press [Shift]-[F7]. WordPerfect prints a copy of the directory on your printer.
  5. Press Exit to return to the main editing screen.


Finding Errant Macros

Despite your best efforts in memorizing or cataloging your macros, you are bound -- sooner or later -- to forget the name of a particular macro you want to use. Fortunately, you can have WordPerfect help you locate stray macros by using the List files command. To work properly, your macros must have a description in the Description field (placed there when you created or edited the macro).

Follow these steps to find macros based on text you provided in the Description.

  1. Press the List files key ([F5]).
  2. Press [Enter] to accept the current directory, or select a different directory, and press [Enter].
  3. Press F for Find.
  4. Press P for First Page.
  5. Enter the text you want to look for, then press [Enter].

WordPerfect displays all the files that contain -- on their first page -- the text you indicated. This includes macros, text files, and so forth. You can readily differentiate between macros and other files because macros have a .WPM extension. If WordPerfect can't find a match, it displays a *not found* message and leaves the screen blank.

To reset the directory:




WordPerfect 5.1 lacks a great deal of sophistication when it comes to actually editing a macro. You are limited to WordPerfect's standard editing keys to insert and delete macro code.

One feature missing from the editor is a way to cut-and-paste macro code so you can move it within a macro or share code between macros. This forces you to write each macro from scratch, thereby consuming a great deal of your time and energies and increasing the chance of mistakes. While a cut-and-paste feature is included in the stand-alone ED macro/program editor, this software is not included with WordPerfect and must be purchased at extra cost.

All is not lost. There are a few time-saving techniques you can use to help cut down on your macro development efforts.

Reusing Macro Files

If you are writing a macro that is based, at least in some degree, on another macro, you can use a simple technique to reduce unnecessary work. Before writing the new macro, make a copy of the old one using DOS or the copy command in the List files screen. Edit the copy and alter the macro as required.

Macro Segments in Keyboard Layouts

Another time-saver is to write commonly used macro segments or routines as keyboard layout macros. You then need only to press the proper keys and the entire routine is automatically entered into the macro.

Let's say, for example, that you have defined [Ctrl]-N (using the Keyboard Layout option in the Setup menu) with the following common macro code:


To duplicate this code into a macro, edit the macro as usual and position the cursor where you want the routine to be placed. Type [Ctrl]-V and follow with [Ctrl]-N (DON'T forget the [Ctrl]-V, or the macro code won't be entered properly). You may repeat this process as many times as you wish.

You may even want to dedicate an entire keyboard layout file to commonly used macro segments (some of the code segments described in the rest of this chapter are good candidates). Activate the layout whenever you are writing or editing macros. Keep a list handy that describes the definition of each of your assigned keys.

Macro Segments in Alt-letter macros

You can accomplish the same basic task using Alt-letter macros, as well, but you must specially prepare the segment macros ahead of time. For every command you want to include in the macro, add a {^V} code right before it, as in:

{^V}{END IF}

The {^V} code (created by pressing [Ctrl]-V twice while in the macro editor), tells WordPerfect that you want the actual command that follows. If you omit the {^V} code, WordPerfect will attempt to execute the command.

For example, suppose you want to enter the following commands into your macros:


At the end, you want WordPerfect to sound the bell as an indicator that the commands have just been entered. To do so, format your fragment macro as:


The {^V} codes insert the commands that follow into your macro. Notice the {Enter} commands. These separate the {ASSIGN} and {IF} commands on their own lines in the macro editor. Because a {^V} code doesn't precede {BELL}, WordPerfect executes the command, and rings the bell.

Taking this approach even further, you can write intelligent Alt-letter and keyboard layout macros to enter the specific segment you want, using a combination of macro commands with and without the {^V} code. Those commands that include a {^V} code in front of them will be entered explicitly into your macros. Those that don't will be executed by WordPerfect in the normal way.

Let's say your macro segment selector provides for a number of options.. Select a number from the menu, and the macro prints those commands for you. With this approach, you can combine all the common fragments you use in a single macro. Such a macro is included in the MACTOOLS.WPK keyboard layout described more fully in Chapter 19, "For Pros Only: Advanced Techniques."

Keep these points in mind when using intelligent macros to insert code fragments:

{Macro Commands}{Home}{Home{Up}{Enter}.



WordPerfect imposes no restrictions on the length or characters used to define labels within macros. However, each label should be different from others used in the macro. If two labels share the same name, WordPerfect will use the first one in the macro. The other one will be ignored.

Remember that the longer the label, the greater the chance of writing it incorrectly elsewhere in the macro. If you misspell a label, WordPerfect will ignore it and the macro will not function properly.

While WordPerfect lets you create label names of any length, the program uses only the first 15 characters of the label name to test for uniqueness. As long as the first 15 characters of your labels are different, WordPerfect will be able to differentiate between them. If they differ only after the 15th character, WordPerfect will treat them as the same label, and will use only the first one in the macro file.

For example,

{LABEL}label for check writing~


{LABEL}label for check printing~

will be considered the same label. They are the same for the first 16 characters ("label for check," plus a space).

Long label names also tend to slow down macro execution. Although there's hardly a difference in macro efficiency between a label that's named xit versus exit, there is a big difference between exit and exit macro routine. Plus, each command, function code, and character in a WordPerfect macro consumes two bytes, so the longer the label names, the larger the macro file.

While WordPerfect allows spaces in label names, you may wish to avoid them. In most cases, the macros in this book use the underline character (_) instead of spaces in multi-word label names. The reasons are manifold, the least of which is that it's easier to differentiate between label names and macro text this way. It's also easier to remember how your label names are constructed when you type them repeatedly in a macro. You don't have to worry if the label name is "check writing" or checkwriting."

Label names are not case sensitive. WordPerfect doesn't care if you enter "label," "LABEL," "Label," "LabeL," or any other variation. The program treats them all as the same label name.



The {PAUSE}, {PAUSE KEY}, and {INPUT} commands temporarily suspend macro execution. When the macro encounters one of these commands, it "turns off" and waits for you to press the [Enter] key (or some other key identified with the {PAUSE KEY} command). Until this occurs, the macro is -- for all practical purposes -- no longer running.

This "feature" affects the way you might expect the macro to work:



WordPerfect can accommodate up to 15 levels of nested macros. That is, macro 1 nests to MACRO 2, which nests to MACRO 3, and so forth, all the way to MACRO 15. If you try to add more than 15 levels of nesting, WordPerfect will complete only those macros that it can, and stop. No error message is provided. Each nested macro can chain to one other macro. WordPerfect doesn't allow you to chain off from a nested macro, then chain to another before returning to the main nesting macro.

Nested subroutines are like nested macros, except that the subroutines are run without leaving the main macro. WordPerfect can accommodate up to 30 nested {CALL} or {CASE CALL} instructions per macro. If you try to add more, the macro will perform as many subroutines as it can and stop.

Note that a nested subroutine is not the same as a single subroutine that executes and finishes. When encountering a single subroutine in a macro, WordPerfect drops down to the {CALL} or {CASE CALL} level, executes the subroutine, then goes back to the main macro level. With nested subroutines, WordPerfect drops down each {CALL} or {CASE CALL} level to execute the subroutines in turn. At each {RETURN} instruction, WordPerfect goes back up one level until it is finally back at the main macro level.

Some additional tips, techniques, and caveats using nesting and chaining:




Some of your macros may change one of WordPerfect's standard defaults, such as units of measure, time format, or location of files. These defaults are stored in the WP{WP}.SET file. Such a change may cause problems later on, so get into the habit of resetting the defaults back to normal before the macro finishes. Of course, the definition of "normal" is up to you, so if you like the time format as 1 January, 1980 instead of January 1, 1980, be sure to reset the default accordingly.

Note that if you write macros for others, you should avoid resetting any defaults. The user may not realize that your macro has reset a default, and may think their copy of WordPerfect has gone on the fritz. You can, however, safely reset the date to its original format using the Initial Codes command under the Setup menu:

Key Sequence What it Does
1. Press [Shift]-[F1] Selects Setup key.
2. Press I Chooses Initial Codes command.
3. Press D for Date The original date format is restored.
4. Press Exit two times WordPerfect returns to the main editing screen.

You can easily add this procedure to any of your macros with:


You can also use the same basic procedure to reset printing options (such as graphics and text quality). At the Initial Codes menu, select P for Print Options, then choose the option you want to reset. Press [Enter] to accept the default, then Exit until you get back to the main editing screen.

If you absolutely must change a default, be sure to warn the user about it, preferably before it happens. This gives the user a chance to stop the macro, or at least have the forewarned knowledge that one or more defaults will be altered.



If your macro retrieves a document, be sure to first clear the document or the retrieved file will be appended to previously written text. The exception to this is when you specifically want to add text to an existing document. Be sure to answer Y to the WordPerfect prompt that asks if you want to append the text. To clear the screen, add {Exit}nn at the appropriate point in the macro.

Macros that create temporary scratch pads and menus should include a "clear" instruction at the end. The prevents the extraneous text from interfering with your other work. If the scratch pad or menu is in Doc 2, be sure to switch to it first before clearing it.

Of course, if you run a macro that indiscriminately clears the document, you (or the person running your macro) may loose a lot of work. In WordPerfect 5.1 you can check to see if the document is not clear with the {SYSTEM} variable command. Use the command in an {IF} construction, such as:

<<document is clear>>
<<document is not empty>>

This construction reads "if SYSTEM variable document equals 256, then the document is clear; otherwise it is not." A value of 256 means that the document is "fresh" -- never before used. Enter one character or code, and the document variable number changes, as detailed in Appendix C, "Macro Codes."



One of the most common macros WordPerfect users create is one that clears the current document and starts with a new, fresh display. The macro is simple:


Because the macro includes the answers to the fail-safe prompts issued by WordPerfect (the first asks if you want to save the document and the second asks if you want to quit WordPerfect), there is no way to reverse the action of the macro once you have started it. To prevent any mishap, always use full names for potentially dangerous macros, and be sure the name isn't similar to any other macro you use. Avoid naming the macro with an Alt-letter combination unless you add a fail-safe mechanism of your own, such as:


{CHAR}0~{^R}Sure you want to clear the current document? (y/n}  ~ 
{IF}"{VAR 0}"="y"~
{IF}"{VAR 0}"="Y"~

This example macro (named CLS.WPM for clear screen) quits if you press any key other than y or Y.



Some macro applications require you to search for some of WordPerfect unique codes. Or, you may wish to instruct WordPerfect to conduct a more thorough search of the document, including any footers, headers, footnotes, and endnotes. Add these instructions to search codes in your macros as needed:

To Search for Soft Returns -- [SRt]

Keys to Press 	Appearance in Macro Editor
[F2] 		{Search}
[Ctrl]-V  	{^V}
[Ctrl]-M  	{^M}  
[F2] 		{Search}

To Search for Invisible Soft Returns -- [ISRt]

Keys to Press  	Appearance in Macro Editor
[F2] 		{Search}
[Ctrl]-H  	{Home}
[Ctrl]-J  	{Enter}
[F2] 		{Search}

To Search the Entire Document (Extended Search)

Keys to Press  	Appearance in Macro Editor
[Home]    	{Home}
[F2] {Search} of search string.

To Search Backwards Through Document

Keys to Press  	Appearance in Macro Editor
[Shift]-[F2]   	{Left Search} of search string
[F2] 		{Search}
[Up] 		{Up} of search string

With the exception of [Shift]-[F2] (Search Left), you may use the same techniques with the Replace command. Other useful techniques:



As you know, WordPerfect macros use the tilde or "sign" character (~) as a command delimiter. Whenever a macro encounters a tilde, it knows that the argument for the command is finished. One of the difficulties in using a printable character for a delimiter is what to do when you want a macro to print a tilde character into your document.

As an example, the {IF} construction

{IF}"{VAR 1}~"="~"~

will not work, because the first tilde the macro comes to (on the right of the equal sign) will delimit the {IF} command. Even if you press the tilde key, the macro will always insist the {IF} construction is FALSE.

Fortunately, WordPerfect 5.1 offers a "hard tilde" character you can use when you need to test for or print the tilde character. To enter a hard-tilde character into a macro:

  1. Press [Ctrl]-V.
  2. Press the tilde key.

WordPerfect prints an odd looking {~} code in the macro. This is the hard tilde code; WordPerfect differentiates between it and the regular tilde character used for delimiting macro command arguments.



The WordPerfect macro language is all the richer because of its various loop commands. These include {FOR}, {FOR EACH}, and {WHILE}. You can also create your own loops using {GO} and {LABEL} commands, as a means to repeat routines over and over again.

The advantage of the {FOR}, {FOR EACH}, and {WHILE} commands is that they each have a built-in "loop counter" that determines the proper number of iterations that are required before the loop is finished. Loops you create with {GO} and {LABEL} must include their own counting and testing mechanism to ensure that the macro is not locked in an "endless loop."

Here are some handy tips and techniques you'll want to keep in mind when using WordPerfect macro loops. Feel free to experiment and try your own variations.

Using {FOR}

The {FOR} command takes four arguments:

Here's an example of a typical {FOR} construction:


The count variable is named count. The starting and ending values are 1 and 10, respectively, and the {FOR} loop counts by 1s.

This is only half of a {FOR} loop. You also need an {END FOR} command to indicate the end of the {FOR} loop. The routine you include between the {FOR} and {END FOR} commands is repeated the desired number of times. If the {FOR} loop repeats 10 times, the routine is repeated 10 times, as in

This is an example of a {FOR} loop{Enter}

The macro will print "This is an example of a {FOR} loop" in the document a total of 10 times, ending each line with a hard return.

The {FOR} command is most often used to repeat some procedure a set number of times, but you don't always have to use it to print a line of text over and over again. For example, you might use it to move a message from one edge of the screen to another (this technique is outlined later in this chapter). Or, you might use it limit the number of times a user presses a certain key in response to a computer-aided-instruction quiz.

The {FOR} command is fairly straightforward, and your experimentation with it (plus study of the macros in this book that use the command) will explain to you just about everything you need to know about it. But here are some tips and techniques you'll want to consider.

The equivalent of the {FOR} command is:

<<repeating routine>>

In this {IF} construction, the macro repeats the <<repeating routine>> every time the variable count is not greater than number x. The variable count is incremented with each iteration. When the {IF} statement is TRUE, then the macro breaks out of the loop.

From this, you can see that you can always write the equivalent of a {FOR} loop using other WordPerfect commands. This helps if you need to write a macro for version 5.0 of WordPerfect, which lacks a {FOR} command. Interestingly, enough, however, a macro you write in 5.1 will display the {FOR} and {END FOR} commands when viewed in version 5.0 of WordPerfect. These macro command names are included in the program, but are not active. They do nothing when run in 5.0.

You can also see, using the {IF} analogy, that the macro always loops back to the beginning to test if count is equal to number x. In a {FOR} loop, the same thing happens. On the last round of the loop, the {FOR} command tests that the value in its counting variable is greater than the ending number you've provided. When the test is true, the macro breaks out of the loop. That's why -- after a {FOR} loop is complete, the count variable contains a number one higher than the ending value (assuming a step value of 1). With the statement {FOR}count~1~10~1~, the count variable will contain the number 11 after the macro has executed the {FOR} command.

The {FOR} command can count down as well as it can count up. Consider the statement:


Instead of starting at 1 and counting to 10, this statement starts at 10 and counts down to 1. The count-down feature has some interesting uses, particularly when manipulating the screen display.

The {NEXT} command is not absolutely required in a {FOR} loop. Normally, the macro will repeat the routine between the {FOR} and {END FOR} commands, incrementing the counter with each iteration. The {NEXT} command lets you restart the loop before it gets all the way to the {END FOR} command. For example, you can use {NEXT} to skip a number in the counting sequence:


This macro prints the numbers 1 through 10, except 5. The number 5 is not printed out because the {FOR} loop was restarted before it got to the {VARIABLE}test~{Enter} routine.

A handy application for the {FOR} loop command is to "load" or clear a set of similarly named variables. For example, you may need to pre-load values in a set of variables. Or, you may need clear variables for re-use, or to free up memory before the macro quits. Consider these examples:


...writes "test" in {VAR 0} through {VAR 9}.


...clears {VAR 0} through {VAR 9}.

{ASSIGN}test{VARIABLE}test~~This is a test~

...writes "This is a test" in variables test1 through test10.


...clears variables test1 through test10.

Using {FOR EACH}

The {FOR EACH} command doesn't really do counting -- at least not like the {FOR} command, but rather takes a series of arguments, evaluates them, and inserts the answer in a "group variable." The main application of the {FOR EACH} command is a time- and space-saver. Although there are many ways to build a {FOR EACH} loop, here's one of the most helpful methods:

{FOR EACH}group~ 
value #1~
value #2~
value #3~
<repeating expression>

The macro inserts each of the values into the group variable, then uses a repeating expression to perform some action. The values can actually be numbers, variables, macro commands, and so forth, and the repeating expression can be most any macro routine you like. Most often, you'll use an {IF} statement to test for some value. For instance:

{FOR EACH}group~
{VARIABLE}var3~~ {IF}{VARIABLE}group~<3~
{PROMPT}Value is under 3~

This example starts by loading the contents of var1 into the group variable, and tests if the value is less than 3. If it is, the prompt message is displayed and the macro beeps. The cycle is repeated for var2 and var3. You can see how the {FOR EACH} command is used to save space in a macro. The same {IF} construction is used for as many values as are included in the {FOR EACH} structure.

Using {WHILE}

Those familiar with programming languages such as BASIC will recognize the application of the {WHILE} command. With {WHILE}, the loop continues until some condition is met. That is, as long as the condition is TRUE, the {WHILE} loop cycles over and over. When the condition is FALSE, the loop is broken, and continues after the {END WHILE} command.

The "condition" you use to test TRUE or FALSE is exactly the same construction you use with the {IF} command.

{WHILE}{VARIABLE}test~=100~ <<repeating part>>

As long as variable test does not equal 100, the "repeating part" is executed over and over again. The recurring routine usually involves user feedback, through a {CHAR} or {TEXT} command.

A handy application of the {WHILE} loop is to test that a particular key has been struck on the keyboard. Because you're looking for just one key, you're better off writing the expression in negative logic: if A does not equal B. For instance:


Here, the macro repeats the {LOOK} and {VARIABLE} instructions within the {WHILE} loop until you press the Exit key ("if variable key does not equal Exit"). The moment you press Exit, the {WHILE} statement is FALSE, and the macro branches off to the point after the {END WHILE} command.



Throughout this book, I have reused certain basic routines -- some to the point of exhaustion! These routines include Yes/No or TRUE/FALSE questions within {IF} statements, key redefinitions, and counting loops. The various routines form a framework that allows you to more easily construct other macros. Once you have a handful of basic routines in your tool box, you need only reach in and use it in the next macro you are building.

Following are a number of the more useful routines developed for this book. In most cases, they can be used as is in your own macros, but some may need to be modified to avoid conflicting with labels, variables, and subroutines you have already written. If a routine calls for placing a value into variable 1, for instance, and you are already using that variable in your macro, change the routine so that it uses another variable instead.

Testing For Keyboard Entry

WordPerfect contains a {LOOK} instruction that lets you assign any single character you type to a variable. The problem with the {LOOK} statement is that it doesn't pause for user input. When the macro comes across the {LOOK} statement, it checks briefly to see if a key has been pressed, and if so, it assigns the key to the indicated variable. But unless you press a key only moments before the macro encounters the {LOOK} statement (not likely), nothing will happen.

The solution is to place the {LOOK} statement in a keyboard loop. These loops are used countless times throughout this book and are among the most useful of all macro routines. As detailed in the previous section, there are many ways to develop loops with the WordPerfect macro language. Here are some of them:

{VAR 1}
{IF}"{VAR 1}"="{Enter}"~
do something

In this routine the macro is waiting for you to press the [Enter] key. When you press the [Enter] key, the macro processes the "do something" instruction (exactly what that is isn't important here).

At the beginning of the routine is an {ASSIGN} statement, which enters a null (nothing) into variable 1. This keeps any value previously placed in variable 1 from being printed the first time the macro goes through the loop. The "loop" label allows the routine to loop back onto itself, but without encountering the {ASSIGN} instruction again. The {VAR 1} instruction passes any keys -- except [Enter] -- through to the document. Without the {VAR 1} instruction, the keyboard entry will not show up on the screen.

The {LOOK}1~ instruction checks the last key you pressed and places it into variable 1. The {IF} statement that follows compares the value of variable 1 against the "{Enter}" string. If it matches, the macro executes the "do something" instruction; If it doesn't match, the macro loops back to the "loop" label.

Notice that the "{Enter}" string and "{VAR 1}" are both in quotes. This is necessary when comparing non-numeric strings.

When you press the [Enter] key, the routine "captures" it and the hard return doesn't get passed through to the document. If you want the hard return, and you will not repeat the loop, add an {Enter} code after the {IF} instruction. Another way to tackle the problem is to add the {VAR 1} statement after the {ELSE} instruction.

You can always look for more than one key in a keyboard loop. As an example, you might test for the [Enter], [Tab], and [Home] keys, as illustrated with the routine below. Remember to add an {ELSE} and an {END IF} for every {IF} statement. The {GO}loop~ instruction should be placed after the last {ELSE}.

{VAR 1}
{IF}"{VAR 1}"="{Enter}"~
    do enter
{IF}"{VAR 1}"="{Tab}"~
    do tab
{IF}"{VAR 1}"="{Home}"~
    do home

Notice that the {GO}loop~ instruction doesn't occur until all three {IF} statements have been evaluated. If you have many keys to check (say, over five or six), you can use a {CASE} construction instead. Merely replace the {IF} statements with one {CASE} construction. Of course, add all of the {LABEL}ed routines that go with the {CASE}.

If you need to test for just one key, use a {WHILE} loop, as detailed previously in this chapter, as in:


This {WHILE} loop evaluates as FALSE if you press a key other than [Ctrl]-[Enter] (hard page). The keys you do press are captured with the {LOOK} command, and passed along to the document with the {VARIABLE}key~ instruction. When you press [Ctrl]-[Enter], the loop is broken.

Single keys can also be detected with the {PAUSE KEY}. Add the desired key code after the {PAUSE KEY} command:


The macro will pause when it reaches the instruction, and won't "re-awaken" until you press [Ctrl]-[Enter].

Redefining Keys

While WordPerfect has a key remapping feature that lets you change the definition of any key -- even make a key behave like a macro -- you may also wish to temporarily redefine a key during the execution of a macro. Recall earlier that the key the macro is looking for in a standard keyboard loop routine is not normally passed through to the document. You can press any other key and it prints on the screen, but the one you want is captured and not executed (this all depends on how you have written the loop).

You can use this feature to redefine the key. Instead of printing a hard return when you press [Enter], for instance, the macro may produce a hard page, a tab, a space, or any other character you want.

{LABEL}loop~ {VAR 1}
{IF}"{VAR 1}"="{Enter}"~

This example shows how the [Enter] key is redefined as [Ctrl]-[Enter] (hard page). Whenever you press [Enter], the macro prints a [HPg] code in the document, then returns to the beginning of the loop. If you plan on re-entering the loop after the [Enter] key is pressed, place the {VAR 1} code after the {ELSE} statement. That way, the keys you press are only passed on to the document when the {IF} statement is false (that is, you press keys other than [Enter]).

The real benefit of redefining keys using {IF} is that you can make the keys behave in any manner you choose, even within the same macro. At the beginning of the macro, the [Tab] key may act like an ordinary [Tab] key, but later on may act like the [Indent] key. You can use this feature to simplify tough formatting jobs or to temporarily re-assign some of WordPerfect's functions to those that are more comfortable for you.

The other types of keyboard loops, especially {WHILE}, can also be constructed to provide the same temporary key remapping capability. If you want to remap many keys, use a {CASE} instruction for all the possibilities. One advantage of {CASE} is that you don't need to but quote marks around all the keys. For instance,

    {Enter}~  enter~
    {Tab}~    tab~
    {HPg}~    hard-page~
    {ELSE}~   loop~

This segment branches off to the "enter," "tab," or "hard-page" labels if any of these respective keys are pressed. Otherwise, the loop repeats. Notice the {ELSE} command used as the last branch-point in the {CASE} construction. If you don't press one of the three keys, the {ELSE} command sends the macro back to the "loop" label.

Accepting Upper and Lower Case

WordPerfect variables are case sensitive. If you construct an {IF} statement that looks for "y", the macro will ignore Y along with all other keys. To accept both upper and lower case versions of a letter, include both in their own {IF} statements. You can also use a {CASE} structure or call on WordPerfect's OR connector operator.

In the following example, pressing either n or N has the same result. Be sure to separate the {IF} instructions with an {ELSE} command, and to provide two {END IF}s at the end.

{IF}"{VAR 1}"="n"~
{IF}"{VAR 1}"="N"~

Using a {CASE} structure, you'd write:

{CASE}{VAR 1}~
<<this is the no routine>>

The macro quits if you press a key other than N or n. Because {CASE} structures don't save space until you test for many keys, you'll probably reserve them for those instances when you need to test for a number of keys -- in upper and lower case combinations. The most practical application of this is in multi-choice menus, as described in Chapter 9, "Creating Menu Systems."

Finally, you can combine upper and lower case characters in the same {IF} statement if you use the OR operator, represented by the | character.

{IF}"{VAR 1}"="y"|"{VAR 1}"="Y"~

The OR connector separates {VAR 1}=y and {VAR 1}=Y, allowing the macro to test for either key. The {IF} instruction still uses one tilde at the end and one closing {END IF} command.

Waiting for Any Key Press

Sometimes, you just want the user to respond to a prompt or message and not press any particular key. For example, you may display the message "Press any key to continue." Rather than writing an {IF} instruction for every key on the keyboard, use a {CHAR} command and message. The idea is that the {CHAR} statement stops the macro long enough so that you can press a key. Once the key is pressed, it goes on.

{CHAR}key~Press any key to continue.~

Ignore whatever key was entered into the key variable.

Separating Macro Routines

Labels allow you to specify different routines within a macro. Often, the labeled routines are not executed in sequence. The macro first executes routine 1, then 3, then 2. The jumps from routine to routine are accomplished with the use of {GO} instructions.

Notice, however, that if you are not careful, the macro will execute routines 1, 3, 2, then 3 again. Why? Because the macro is not stopped after routine 2. Get into the habit of adding {QUIT} statements at the end of each routine to keep the macro from proceeding to a step it isn't supposed to normally execute. Depending on the application, you may also use {BREAK}, {CHAIN}, {NEST}, {RETURN}, and other statements to forcibly terminate or re-direct macro execution.

Placement of Routines and Subroutines

The layout of your macro will depend on the application and your programming habits. Some programmers like to stuff all of the routines and subroutines away from the "main" or working portion of the macro. That makes analyzing problems (called "debugging" in programming lingo) easier. If the routine is part of the normal execution of the macro, insert it so that WordPerfect performs it in sequence with the rest of the instructions. If the macro jumps to special routines (when an {IF} instruction is TRUE, for example), you may want to place these routines toward the end. Do the same for subroutines, which are used by the {CALL} and {CASE CALL} instructions.

Displaying a Prompt In the Status Line

The {PROMPT} statement is used to provide explanatory text or instructions for the user. The statement does not expect a response, and so does not cause the macro to temporarily stop. If you enter text into the keyboard following a {PROMPT} message, the text is passed through to the document and not entered into a variable.

Unlike a message you include in a {CHAR} or {TEXT} instruction, a prompt message typically stays in the status line only until the next macro instruction that writes text on the screen or turns the display off. Keeping the prompt message on the screen long enough so that it can be read can be a tough problem, but there are several solutions.


The easiest method is to delay the action of the next instruction. You may do so with the {WAIT} statement. I regularly include a 1.5 second delay after the {PROMPT} statement to give the user time to read the message (longer messages require longer delays).


{PROMPT}Press y or n only.~

The 15~ argument after the {WAIT} statement pauses the macro for 1.5 seconds (15/10ths of a second). After the specified delay, the macro will continue with the next instruction after the {WAIT} statement.

Keyboard Looping

A keyboard loop keeps the macro busy scanning the keyboard. The {PROMPT} message remains on the screen until you press a key. Note that the message itself should NOT be part of the loop, or the message will flicker on the screen. Rather, place the {PROMPT} message immediately before the loop. For more information on keyboard loops, see the section above on "Testing For Keyboard Entry."


Placing a {PAUSE} instruction immediately after the {PROMPT} message keeps the message on the screen until you press [Enter].

{PROMPT}Not a legal response.  Press Enter to continue.~ {PAUSE}

If you want to make sure that the {PROMPT} message doesn't remain in the status line after you press [Enter], add a {DISPLAY OFF}{DISPLAY ON} after the {PAUSE}.

Note that the {PROMPT} and {PAUSE} pair are functionally the same as the {INPUT} command.

When used in a keyboard loop, the {PROMPT} message will remain on the screen only until WordPerfect rewrites the screen. Exactly when this happens depends entirely on what you (and WordPerfect) are doing at the time. In most cases, the prompt is erased when the text scrolls or you press one of the vertical movement cursor keys (up, down, page up, etc.).

Normally, there is no great difficulty imposed when the prompt message is erased by a WordPerfect macro unless the message is long or spans more than one line. If you notice that the macro erases only a portion of the {PROMPT} message, or leaves lines of a multi-line message, you need to provide a means to clean up after WordPerfect. The easiest way is to add a {DISPLAY OFF}{DISPLAY ON} code pair after the {PROMPT} and loop (or {PAUSE}). You can also use {Screen}{Screen} to rewrite the display.

User Entry Using the {TEXT} and {CHAR} Commands

The {CHAR} and {TEXT} commands which specifically ask for user input, capturing the answer in a variable. If you want to pass the input to the document, you must print the contents of the variable used with the {CHAR} or {TEXT} instruction to the document.

{CHAR}0~Enter today's date.  ~
{VAR 0}

If you want the answer to appear directly in the document at the current location of the cursor, use the {PROMPT} instruction. You can also force the cursor to any position in the document window, as discussed in the next section.

Enhancing Message Strings

Message strings are printed in the status line using the {TEXT}, {CHAR}, {PROMPT}, {INPUT}, and {STATUS PROMPT} commands. You can improve the appearance of messages by adding one or two blank spaces after the text and before the tilde, such as (the character denotes a space):

{TEXT}1~Enter the name and address  ~

With the extra spaces added, the cursor will be positioned away from the text, and text you write won't be jammed up against the message.

Control characters can be embedded in {TEXT}, {CHAR}, {PROMPT}, {INPUT}, and {STATUS PROMPT} messages to enhance the appearance of the message. Among the most useful are bold, underline, reverse video, and blink. Use these display attributes when you wish to get the user's attention.



Reverse Video:




Ringing the Bell

Another way to call attention to a message is to add a {BELL} instruction. When the macro encounters the {BELL} statement, the computer emits a short warning tone. You can link {BELL} statements to produce a cadence of tones to warn against impending danger. Place the {BELL} instruction before or after a {PAUSE}; the {BELL} must be placed in front of a {CHAR} or {TEXT} message.

{PROMPT}This is a warning.~{BELL}
{BELL}{CHAR}1~Are you sure you want to erase the file?~
{BELL}{BELL}{TEXT}1~Are you really, really sure?~ 

Messages Longer Than One Line

WordPerfect allows you to display {TEXT}, {CHAR}, {PROMPT}, {INPUT}, and {STATUS PROMPT} messages of nearly any length, although you should try to confine the message to one line or less. If the message must span more than one line, add {Enter} codes in the message string. The {CHAR} string:

{CHAR}1~Press a key to continue{Enter}
1 New File  2 Old File  3 Spell Check  ~

appears as

Press any key to continue:
1 New File; 2 Old File; 3 Spell Check 

at the bottom of the screen.

WordPerfect normally erases any message but a remnant from the top line may appear in the text of the document. Although the remnant is not a part of the document -- it will disappear after a while -- it cab be distracting. To prevent remnants from drifting through your documents, clear the screen by adding {DISPLAY OFF}{DISPLAY ON} (or {Screen}{Screen}) as the next instruction after the message. The screen will flash off very quickly, then turn back on again, this time without the message or any remnants. You can use this technique to safely build even large multiple-line menu displays.

Adding Mnemonics in Menus

WordPerfect uses mnemonics as an aid in remember menu commands and selections. You can provide mnemonics in your macros in much the same way, highlighting the keys you press to select the command by letter or number. Use the {^]} and {^\} bold on/off codes surround the keys the user is expected to push in response to a menu, as in:

{CHAR}1~{^]}1 N{^\}ew File  {^]}2 O{^\}ld File  
{^]}3 S{^\}pell Check  ~

On the screen, this menu appears as:

1 New File  2 Old File  3 Spell Check

You know which keys to press because they are highlighted in the menu. To supplement this menu line, you'd provide a {CASE} structure that tests for each of the highlighted keys (including upper and lower case.

{CASE}{VAR 1}~
   1~new~    N~new~    n~new~
   2~old~    O~old~    o~old~
   3~spell~  S~spell~  s~spell~

WordPerfect offers a default selection for most all of its menus choices. This default is shown at the far right of the menu line. The flashing cursor rests under the default, showing you that by pressing the [Enter] key you activate the indicated menu choice.

To accomplish the same thing in a macro:

{CHAR}1~{^]}1 N{^]}ew File  {^]}2 O{^\}ld File   
{^]}3 S{^\}pell Check  {^]}1{^\}{Left}~

This appears on the screen as

1 New File  2 Old File  3 Spell Check  1

To enable the macro to respond to the Enter key, add an extra branch-point in the {CASE} structure:

{Enter}~  new~

Pressing the [Enter] key has the same effect as pressing 1, N, or n.

Recovering From Failed Searches and Errors

When a search in macro ends with a *not found* message, the macro is abruptly ended. If you don't want the macro to finish prematurely when a search fails, add a {ON NOT FOUND} instruction before the {Search} code. This tells the macro to perform some standard routine when the search ends up empty-handed. The most common use of {ON NOT FOUND} is to branch to a "not found" label.

{ON NOT FOUND}{CALL}notfound~~ of macro
{PROMPT}Sorry, the search failed.~{BELL}{WAIT}15~ 

The same technique can be used to recover from an error. Most errors in macros occur because WordPerfect cannot find some file it needs (although this sounds like it should be a not-found condition, the error happens outside of a normal WordPerfect search). The following routine is especially helpful if you regularly keep your macros on another disk or in different directories. It lets you re-enter the macro file name, drive, or directory after an error has occurred. The example assumes that you wish to chain to a macro called INVOICE.WPM.

{ON ERROR}{CALL}error~~
{CHAIN}INVOICE.WPM{Enter} of macro

{TEXT}1~Can't find that file.  Enter a new name, drive, or directory. 
{CHAIN}{VAR 1}{Enter}

When the macro can't find the file, it calls the "error" subroutine as indicated after the {ON ERROR} instruction. The "error" subroutine asks you to enter a new name, drive, or directory. Your response is recorded in variable 1, and is used the next {CHAIN} instruction. Assuming that WordPerfect can find the proper file, the macro returns to where it left off.

IMPORTANT NOTE: Your macro WILL NOT WORK if you forget to add two tildes when using the {GO} and {CALL} commands after {ON NOT FOUND} and {ON ERROR}. Your macro also WILL NOW WORK if you attempt to {GO} or {CALL} to a label that doesn't exist.

If you wish merely to have WordPerfect ignore error and not-found conditions, enter {ON ERROR}~ and {ON NOT FOUND}~ statements by themselves (don't forget the tildes). This effectively prevents errors and not-found conditions from affecting macros, but also prevents macros from detecting that an error or not found condition has occurred. Use them with care.

To return to the normal defaults for {ON ERROR} and {ON NOT FOUND}, enter {ON ERROR}{RETURN ERROR}~ and {ON NOT FOUND}{RETURN NOT FOUND}~.

Trapping the Cancel Key

Normally, pressing the Cancel key during macro execution stops the macro. You can prevent this by turning cancel off with the {CANCEL OFF} key. This inhibits the Cancel key from terminating a macro, yet retains the use of the Cancel key for its normal WordPerfect functions (such as undo).

Users are accustomed to pressing the Cancel key to quit some WordPerfect function, and advanced macros should be given this feature. Not all macros can (or should) be halted mid-way through execution. Rather, you'll want the macro to detect when the Cancel key has been struck, then branch off to a "cancel" routine.

For this purpose, the macro language includes {ON CANCEL}. You use it in the same way as {ON ERROR} and {ON NOT FOUND}. The most common application is {GO}ing or {CALL}ing a routine, as in:

{ON CANCEL}{GO}cancel~~
... rest of macro

{PROMPT}You pressed cancel...terminating macro~

As with {ON ERROR} and {ON NOT FOUND}, be sure to include two tildes after the {ON CANCEL} command when using {GO} and {CALL} (one tilde is for the {ON CANCEL} command; the other is for the {GO} or {CALL} command).


A counter is a routine that starts with a number in a variable, then either adds a digit to it subjects a digit from it. Counter routines are often used to keep track of the number of times the macro has completed an operation.

A good example of using counters can be found in the quiz game presented in Chapter 17. Actually, two counters are used: one to monitor the current question number, and another to keep score. The basic counter consists of an {ASSIGN} instruction that loads a starting number (usually 1 or 0) into a variable, and a loop that forces the macro to repeat some operation. Within the loop is an instruction to add a digit to the assigned variable.

...repeating routine
{ASSIGN}1~{VAR 1}+1~

This example first assigns the value 0 to variable 1. The macro then enters the repeating routine segment. At the end of the segment, the macro adds 1 to variable 1, then goes back to the start of the routine. You might use the value is variable 1 to test for some condition. Suppose you want to count the number of times you press the [Enter] key during a certain operation. After the second time, you want the macro to branch off and do something special.


The macro starts by loading 0 into variable count. It then begins a keyboard loop routine that tests for the [Enter] key. An additional {IF} instruction tests to see if the value in variable count is equal to a certain number (in this case 2). Each time you press [Enter], the macro adds 1 to variable count. As long as variable count is less than 2, the macro will skip the first {IF} statement and go on. But the moment you press the [Enter] key a second time, the first {IF} statement is TRUE, and the macro branches off to the "print" routine.

You can also construct counter using {FOR} and {WHILE} commands. As you saw earlier in this chapter, the {FOR} command incorporates its own internal counter that is incremented with each iteration of the loop. The starting and ending values provide the initial and checking numbers (start at 1 and go to five, for instance), and the step value provides the number to count by.

The construction of the {WHILE} loop readily lends itself to use in counting iterations.

    {CHAR}key~What next?~

This segments waits for you to press the [Tab] key. With each iteration of the loop, you are asked "What next?" Press a key and if it's not the Tab key, the counter is incremented by 1, and the loop starts all over again.

Moving Data Between Documents

Doc 2 provides a handy scratch pad area for performing sundry tasks during macro execution. For example, Doc 2 might be used to set up a temporary math definition for calculating the numbers entered into Doc 1. A number of macro applications require you to transfer data from one document screen to another.

The macro routines for doing this can be quite complex, depending on the nature of the data and what you need to do with it. Yet the macro merely consists of the same steps you'd take if you manually copied text from one document and inserted it into another. You can use:

To transfer data from Doc 2 to Doc 1 using the Move command, first switch to Doc 2 (if you are not already there), then locate the data you want to move. Locating it can be tricky unless the data is always in the same spot on the document, or unless you use a place marker that serves as a search string. Turn block on and select all of the data you want to transfer. Then choose [Ctrl]-[F4] (Move), and either:

WordPerfect lets you then automatically paste the copied or cut data by moving the cursor to the insertion point and pressing [Enter]. If your macro cannot be written so that the transferred data can't be directly pasted into place, add a {Cancel} command immediately after cutting or copying.

With the data stored in the WordPerfect buffer, switch back to Doc 1, locate the spot you want the data to go, and press [Ctrl]-[F4], followed by RB (for Retrieve Block). As long as you don't cut or copy anything else, you can continue to paste the same data any number of places within the document.

The {Block Move} and {Block Copy} copy macros commands, accessible within the pop-up commands window while using the macro editor, perform the same functions. Substitute the Move commands with {Block Move} or {Block Copy}, as needed.

The {Macro Commands} assign feature works similarly to the Move command except that you have nearly an unlimited number of buffers to place the text. You can only copy text using the assign feature. If you want to actually move (and therefore delete the original) text from the document, you must do so in a separate step using the editing keys.

The process for transferring text using {Macro Commands} begins the same as the procedures outlined above. Switch to Doc 2, locate the data, and block it. Then, choose [Ctrl]-[Page Up], press A (for Assign), and enter a variable number or name. Press [Enter] to accept the name, and record the text into the variable.

For example, to paste data into variable 4, press:

[Ctrl]-[Page Up] A4 [Enter]

In a macro, this appears as:

{Macro Commands}A4{Enter}

To enter the {Macro Commands} code from within the macro editor, press [Ctrl]-V, then press [Ctrl]-[Page Up].

To retrieve the data, return to Doc 1 and press [Alt]-4 (or other variable number you used). The same data can be pasted indefinitely until you change the contents of the variable.

Regardless of the transferring method you use, you must be sure that the macro knows exactly where to copy the data and exactly to paste it. You may need to manually go through the steps of cutting and pasting the data and jot down the keys you press. Duplicate them in a macro and test it to be sure that it works the way you want.

Note that WordPerfect variables can contain text only. With the exception of indent, hard page, hard return, and require hyphens, all formatting codes are encountered in the document are ignored when the text is pasted into the variable.

Using Footnote Windows as Scratch pads

Many WordPerfect users prefer to use the alternate document window to store snippets of manuscript, lists of names and addresses, and other tidbits of regular word processing work. You can approximate a "dedicated" scratch pad with the footnote feature. Instead of switching to Doc 2, just create a new footnote. In a macro, enter:


The {Footnote}FC instructions tell WordPerfect to create a new footnote. The {Backspace}y instructions tell WordPerfect to delete the footnote number that automatically appears in the window.

To exit the footnote window, press Exit. Upon leaving the footnote, WordPerfect appends the footnote number in the text. You probably don't want it, so add another {Backspace}y to get rid of it.

Tip: While in the footnote editing window, you can test for the Exit key so the macro knows when to leave. Use a keyboard loop, or a {PAUSE KEY}{Exit}~ instruction. For an example of using a keyboard loop and the footnote window as a temporary scratch pad, see WHILEOUT.WPM in Chapter 17. Several other macros presented in this book use the same technique.

Variable Repeating Keystrokes

You already know that the [Esc] key can be used to repeat an alphanumeric key or cursor key by the number of times you specify. You can use the {Esc} code in your macros to define the number of times that another key is repeated. You may also construct the macro in such a way that you can specify the exact number of repeats while the macro is executing.

A good example is drawing a vertical line using the Line Draw feature of WordPerfect. By asking for the length of line, and storing the length in a variable, you can control the number of times the [Down] key is pressed.


{TEXT}1~Enter the length of the line; press Enter when done.~
{Esc}{VAR 1}{Down}

Using Macros with Name Searches

Macros are primarily used to duplicate your keystrokes. If you record a macro that selects a document from among the List files directory, it may not be the same document that's selected when the macro is run some other time. Instead of using the cursor keys to indicate a document to use, use the name search feature. Press N (for name search), type the name of the document you want, then hit [Enter]. Finally, select the option you want to use from the menu.

The technique also works when selecting a:

and any other screen that displays a list of variable choices (the choices vary depending on your files, your computer, and so forth).

Tip: You can also press [F2] instead of N to initiate a name search in a WordPerfect list.

Here's a practical example. Suppose you want to select a style named SPACER from the Style menu. Here's the actual keystrokes for the macro:

Key Sequence What it Does
1. [Alt]-[F8] Chooses Style menu.
2. n Defines name search.
Indicates style to use.
4. O Turns style on.


Constructing AND and OR Logic Using IF...ELSE Instructions

Here's a bit of technical mumbo-jumbo that will either mean nothing to you or mean a lot. {IF} instructions are typically built to test for one of several conditions. When at least one of the conditions is TRUE, that portion of the macro is complete and WordPerfect proceeds to the next. An example:

{IF}{VAR 1}=100~
{IF}{VAR 1}=200~
{IF}{VAR 1}=300~

The structure of the the macro routine is referred to as OR logic. If variable 1 is equal to 100 OR 200 OR 300, the macro jumps to the "true" routine. Any other condition causes the macro to jump to the "false" routine. Most of the macros in this book revolve around OR logic for {IF} instructions.

What if you want to build an {IF} instruction that jumps to the "true" routine only if ALL of the conditions are met? This structure is more commonly called AND logic, and it can be easily done in macros by moving the instructions around a bit.

Following are two test macros that you can write yourself to experiment with the operation of AND and OR logic.

Chapter 4, "Learning the Macro Programming Language," touched on the topic of AND and OR logic. You can predict what either macro will do in a given situation by referring to the truth tables.

AND -- Separate {IF} Statements

{IF}{VAR 0}=1~
{IF}{VAR 1}=1~

OR -- Separate {IF} Statements

{IF}{VAR 0}=1~
{IF}{VAR 1}=1~

Another way to accomplish the same goal is to use the OR and AND operator symbols within one {IF} instruction. This approach saves some space in the macro, particularly if you need to check more than two or three conditions.

OR -- Single {IF} Statement

{IF}{VAR 0}=1|{VAR 1}=1~

AND -- Single {IF} Statement

{IF}{VAR 0}=1&{VAR 1}=1~

As you can see, the only difference between the OR and AND using single {IF} statements is the operator -- | for OR; & for AND. You can, of course, string as many conditions onto the single {IF} statement you wish, but only up to 129 characters for the entire expression. Note that WordPerfect considers a code or command in a macro as a single character; {IF}, {VAR 1}, and so forth each constitute one character.

IMPORTANT: The {IF} statement should contain only one terminating tilde at the very end. Do not place a tilde after each component of the {IF} statement. In addition, if you use quotes to identify a string comparison, you MUST use quotes on all conditions of the {IF} construction, even if the comparisons are numerical.

An example of a real-world application of OR/AND is testing the response from the user.


This segment tests that the user has pressed Y or y in response to a prompt. If the response is something else, then the macro quits.

    {PROMPT}Wrong amount; try again~

This segment tests that the number in the amount variable is between 100 and 200. If it is, the macro branches to the "continue" label. If the number is higher or lower (or isn't a number at all), a prompt message is displayed and the macro returns to the "amount" label.

Testing the State of WordPerfect

The {STATE} instruction allows you to test the current operating condition of WordPerfect. Depending on what the program is doing at the time, your macro may branch off in one direction or another. The current state of WordPerfect is reported as a number.

Although you don't need to know exactly how WordPerfect uses the state numbers, it's helpful if you want a full appreciation of what you can do with macros and the {STATE} instruction. State numbers actually represents a binary number (or "word") from 1 to 2048. The binary word is composed of 1s and 0s, layed out in this format:

2048 1024 512  256  128  64   32   16   8    4    2    1
0    0    0    0    0    0    0    0    0    0    0    0

For every 1, you add the number above it. If there is a 1 below 4 and 16, you add 4 and 16 together and you get 20. Here are the binary (also called bitwise) equivalents of the numbers used in reporting the current state of WordPerfect:

Number  Binary Equivalent  State 
1    	000000000001   	   Doc 1 active
2    	000000000010   	   Doc 2 active 
4    	000000000100   	   Main editing screen (typically on) 
8       000000001000   	   Editing structure other than main document 
16      000000010000   	   Macro definition active
32      000000100000       Macro execution active (always on) 
64      000001000000       Merge active
128     000010000000       Block active
256     000100000000       Typeover active
512     001000000000       Reveal codes active
1024    010000000000       Yes/No question active
2048    100000000000       In list

In addition to these numbers, the WordPerfect {STATE} variable returns a value of 32768 when the program is stopped at a prompt. This value is not documented in the WordPerfect manual; for this reason, you may not want to use it in your macros in case the feature is removed in a later version.

Notice that the position of the 1 in the binary string changes position right to left. Think of the binary string as a bank of switches. When the number is 0, the switch is off and that feature of WordPerfect is not active. If the number is 1, the switch is on; the corresponding feature is on.

If several conditions or modes are on at any one time, as they often are, they are added together. For example, reading the state during macro execution when WordPerfect is in Doc 1 and main editing screen, and when typeover is active, returns a value of 293.

The number for that state, with the appropriate "switches" flipped up, would be

1    00000000001    Doc 1 active
4    00000000100    Main editing screen
32   00000100000    Macro execution active
256  00100000000    Typeover active
=    00100100101    293

Entering {STATE} by itself in the macro causes WordPerfect to print the state in the document. You probably want to test for a particular operating mode by incorporating the {STATE} statement in an {IF}, {CASE}, {CASE CALL}, or {ASSIGN} instruction. You can separate the exact mode you want to test for by using the AND logical operator.



This instruction tests whether or not typeover is currently active. If typeover is ON, the value in variable 1 is 256 (the equivalent of the Typeover on state value). If typeover is OFF, the value is 0.

You can directly apply the ANDed {STATE} instruction in an {IF} structure. Here's one used several times in this book:


This routine begins to save a document using the name TEXT.TXT. The file may already exist, so the {IF} instruction tests for the Yes/No question ("do you want to replace the file?") with {STATE}&1024. If the Yes/No question is active, the result is 1024, which WordPerfect interprets as TRUE (to WordPerfect, any number other than 0 is considered TRUE). The macro enters a y for "yes" and jumps to the "finish" routine. If the Yes/No question is not active (the file doesn't already exist), the result is 0, which WordPerfect interprets as FALSE. The macro jumps directly to the "finish" routine. Another way of implementing the {STATE} instruction with an {IF} statement is to use {ASSIGN}. The following example checks to see if typeover is active. If it is, the macro jumps immediately to the "start" routine. If it isn't, the macro first turns typeover on, then jumps to "start."

{IF}{VAR 0}=256~

Testing Internal {SYSTEM} Variables

The {STATE} macro command represents a single WordPerfect internal variable. The variable contains a number of useful tidbits of information. You use the & AND operator, as described above, to test for the individual attributes of this one variable. WordPerfect 5.1 also offers the {SYSTEM} command, which provides for 25 different internal variables. After the {SYSTEM} command you enter the name or number of the internal variable you want to check.

As with {STATE}, the response to some (but not all) of the {SYSTEM} variables is a powers-of-two number (1, 2, 4, 8, 16, etc.). The individual attributes are decoded from the number WordPerfect provides. For example,


returns the number 256 when the current editing screen is "fresh" (never before used). If the cursor is within a table, and the document was recently saved, the number returned is 516. WordPerfect generates this peculiar number because it is the sum of all the document variable attributes:

512  Cursor is within table
  4  Document has been modified since last generated 
 516 TOTAL

The TOTAL is not as useful to you as the component numbers. As with {STATE}, use the & AND operator to test for component binary values. For example, to test that the cursor is within a table:

    <<within table>>
    <<not within table>>

The {IF} construction masks out all values but 512. If the statement is TRUE, the macro knows the cursor is currently within a table. If the statement is FALSE, then the cursor is not within a table.

You can use the same technique to test that the current document screen is empty.

     <<empty document>>
     <<document not empty>>

This {IF} statement test that the document is empty, not necessarily "fresh" (that is, a never-before-touched document -- the kind you get when you first start WordPerfect or clear the document with {Exit}nn). Entering text into a document, then clearing it will return a value of 261. That resolves to:

Of course, if you want to test that the document is absolutely "fresh" and never before used, insert an equals operator instead of the & operator:

     <<empty fresh>>
     <<document not fresh>>

Appendix C lists all of the values returned by the {SYSTEM} command, for the document internal variable as well as the 24 others that the command supports.

The {SYSTEM} variables that return powers-of-two numbers are:


Saving with Short or Long Names

WordPerfect 5.1 gives you the option of saving files with Short or Long names. Short names are the customary DOS filenames -- eight characters, a period, and an extension. Long names also include a DOS filename, but in addition include a 68 character full-text identifier that's stored with the document. You can see this full-text identifier in List files when the Long Document option is turned on. Out of the box, WordPerfect is set to Short names. To change it, select Environment under the Setup menu. One of the sub-menus, Document Management/Summary, offers an option Long Document Names. This option lets you turn the Long document name feature on or off. The setting of Long Document Names remains in place until you explicitly change it again. WordPerfect remembers it from session to session.

The procedure for saving files differs slightly depending on whether WordPerfect is set to Short or Long names. Macros that save files should be designed so that they anticipate the prompts asked by WordPerfect whether the Long Document Names feature is turned off or on.

Short file name saving procedure

  1. Press the Save key.
  2. Type the file name.
  3. Press [Enter].

If the file already exists, answer Y to overwrite.

Long file name saving procedure

  1. Press the Save key.
  2. Type the Long Document name.
  3. Press [Enter].
  4. Type the file type (optional).
  5. Press [Enter] 6. Type the DOS file name (WordPerfect suggests a name, using characters from the Long Document name you provided, but you can replace it with your own filename).
  6. Press [Enter].

If the file already exists, answer Y to overwrite.

As you can see, there are several additional steps when the Long names option is turned on. Fortunately, WordPerfect provides a means to detect when Short or Long names are required. The macro fragment that follows can be used in most any macro that saves files.


<<file saved; return to rest of your macro>>

<<file saved; return to rest of your macro>>

Be sure to provide at least some text for "longname," or WordPerfect will skip the "filetype" prompt. That could throw off your macro, making it execute unpredictably.



Of all WordPerfect's display codes, the {^P} code -- used to indicate an exact spot on the screen for a prompt message -- is the most versatile. Yet, it's also the hardest to grasp.

The {^P} code is followed with a two character argument that indicates the column and row for the start of the message string. How are these used? The standard screen display can be divided into 80 columns across by 25 lines deep. Let's say you want the message:

Press Enter Now

to start at the intersection of the 30th column and the 15th line. You'd enter,

{PROMPT}{^P}code for column 30; code for line 15 Press Enter Now~

You have two choices of character codes to use indicate the column and row numbers:


Using WordPerfect Control/Function Codes

WordPerfect's control and function codes have intrinsic numeric values. For example, Ctrl-A (which prints as {^A} on the screen) has a value of 1. Ctrl-B has a value of 2, and so forth. After the alphabet control keys start the function keys, including all the feature keys you use to access WordPerfect's menus -- the {Cancel} key has a value of 32; the {Print} key a value of 50, and so forth. You see these values when you execute a macro in STEP ON mode. At any rate, these function codes can be used to indicate the column and row in {^P} messages. To place the message at column 5, row 3, for instance, you'd enter in the macro editor:

{PROMPT}{^P}{^E}{^C} Message message goes here~

Of course, you can use the the {^P} code with other message commands -- {INPUT}, {TEXT}, {CHAR}, and {STATUS PROMPT}. You're not just limited to the {PROMPT} command shown in the example.

There are two disadvantages to using the control/function code method:

See Appendix C for a list of control/function codes and their corresponding numbers.

Using ASCII Characters

A more convenient and generally better-looking approach is to use ASCII characters. You can access all 254 printable characters directly with WordPerfect using either the Alt-keypad method or the program's built-in Compose key feature. With ASCII characters, ASCII number 1 is row/column 1. ASCII number 2 is row/column 2, and so forth.

To enter an ASCII character using the Alt-keypad method, press and hold the [Alt] key. Then, using the numeric keypad (not the numbers across the top row of the keyboard), enter the ASCII number you want. When you're done, release the [Alt] key. Note that not all computers support this method. If yours doesn't, you'll need to use the Compose key feature. With Compose, you can either enter the ASCII number, or the WordPerfect character set and number.

Understanding Screen Coordinates

You'd think that the very upper-left corner of the screen is the intersection of column 1 and row 1, but it's not. For at least the purposes of the {^P} display code, the WordPerfect screen starts at column and row 0 for the upper-left corner. The far right column is column 79 (assuming an 80-column display). Likewise, the last row is row 24. You should keep this in mind whenever planning message displays using the {^P} code.

The unusual coordinate system causes problems when you want to start a message at column 0 or on row 0. Using the ASCII code method you find that pressing [Alt] and 0 on the numeric keypad produces nothing. And while WordPerfect does have a function code with a value of zero (it's the {Compose} key code), it is not directly accessible from within the macro editor.

Here are two approaches you can use:


Using the {NTOK} Command for Cursor Placement

You can also use the {NTOK} macro command to indicate column and row coordinates. The {NTOK} code takes a number and converts it to a WordPerfect key. For use with the {^P} display code, you'll follow the NTOK command with a number from 0 to 79. You need a separate {NTOK} command for both the column and row coordinates. Here's an example:

{PROMPT}{^P}{NTOK}0~{NTOK}20~ Your Message Goes Here~

The first {NTOK} code places the cursor at column 0, or the very left of the display. The second {NTOK} code places the cursor at row 20, near the bottom of the screen. Remember to follow each {NTOK} code with a tilde.

The {NTOK} code is particularly handy when you're building elaborate macros where the messages change places. The BLACKJAK.WPM macro described in Chapter 17 is a good example of this. The {NTOK} code is used to vary the location of the cards, depending on whether the cards are being dealt to the player or dealer. The location of the cards are kept in a counter variable; that variable is then used with the {NTOK} code to convert the number to a screen display coordinate.

Here's a practical example of this technique. This macro writes a message starting from the upper left corner of the display and finishes at the lower right. Without the {NTOK} code, the macro would be a lot more complicated.

{NTOK}{VARIABLE}row~~Hello there~
{CHAR}key~Press a key  ~

The column and row coordinates are first set to 0. This places the first "Hello there" prompt at the upper-left corner of the display. The {PROMPT} message then uses the col and row variables with the {NTOK} command in a {FOR} loop. With each iteration of the loop, the col variable is incremented by 3, and the row variable is incremented by 1. With each new iteration, the {NTOK} command converts the number and provides the proper coordinate code to place the message (for example, to place the message at row 6, it furnishes a {^F} character to WordPerfect). The screen is not rewritten until after you press a key to continue, so all 24 of the "Hello there"'s remain on the screen until then.

Making Pop-Up Menus

One of the most exciting real-world applications of the {^P} display code is creating pop-up menus and windows. The pop-up is composed of several lines of message text, and has the affect of temporarily over-writing any text that's underneath. Once the window is removed, the original text re-appears. By formatting the lines of the message with a box frame (using characters from the IBM Extended Character Set), as shown below, you can make a realistic pop-up window. You have full control over the size and placement of your windows.

Making Menu and Window Boxes

Sadly, you cannot use WordPerfect's Line Draw feature within the macro editor to make box frames for your menus and windows (exception: see the tip below for a nifty work-around). Instead, you must create them within the macro editor using the Alt-keypad technique outlined above, or with WordPerfect's Compose key feature. Consult a DOS book for a run-down of the IBM Character set and the ASCII values for each character.

Tip: If you use Shell (part of the WordPerfect Office package), you can use it to copy a box made with Line Draw and paste it directly in the macro editor. From within the main WordPerfect editor, use Line Draw to create a box the size and shape you want. Press [Shift]-[Alt]-- (Shift, Alt, and minus key on the top row of the keyboard) to invoke Shell's screen copy mode. Indicate a Rectangle copy by pressing R or 1. Position the cursor at one corner of the box, press [Enter], then move the cursor to the opposite corner. Press [Enter] again, and select S for Save. Open the macro and from within the macro editor, position the cursor where you want the box to appear. Press [Shift]-[Alt]-+ (Shift, Alt, and plus key on the top row of the keyboard). The box will be immediately pasted into the macro editor screen.


Using the BOXMAKR Menu Framer Macro

If you don't have Shell you can't enjoy the time-saving tip discussed above. But you can also use the BOXMAKR.WPM macro to create fast and easy frames for pop-up menus and windows. This macro is provided on the Applications Disk in the MACTOOLS.WPK keyboard layout, detailed in Chapter 19.

The BOXMAKR.WPM macro makes any size boxes, using either single or double border frames, following your directions. For example, if you want a box 20 columns across and eight rows deep, indicate the dimensions as BOKMAKR prompts form them. Out comes a box the perfect size and shape.

Using {^P} Codes on All Lines of a Menu or Message

If you're placing a box anywhere on the screen but the far left edge, you'll need to enter separate {^P} codes and coordinates for each line of the menu or message. Otherwise, WordPerfect will place the first line of the message at the desired lotion on the screen, then wrap the next line one row down but at the far left of the screen.

When constructing pop-up menus and boxes messages, each line will contain the same column coordinate; the row coordinate will advance down one row.

Using {^P} codes and coordinates for each line is most beneficial in larger displays where the message may be broken if the screen is set to a size other than the standard 24 lines (the 25th line is reserved by WordPerfect). For example, if you currently have Reveal Codes on and display a box that extends beyond the middle of the screen, it will be broken at the ruler line that separates top and bottom halves of the Reveal Codes display.

Avoiding Large Menus and Windows

While pop-up menus and windows using macros provides for unique displays, they can get in the way when used in slower computer systems. When possible, avoid menus and windows larger than about one quarter of the screen (say, 20 columns wide by 12 rows deep). Larger menus and windows tend to write more slowly on the screen, and when used with a slow computer, the delay could stretch into several seconds.



This chapter discussed numerous strategies for working with WordPerfect macros. You learned:


 Top Contents

WordPerfect 5.1 Macros and Templates
Electronic Edition
Copyright 1990, 1997, Gordon McComb.  All Rights Reserved.
First published by Bantam Electronic Publishing, 1990.