ADD TEXT TO MULT_CHOICE – dynamic

Recently, we looked at how to use the ADD and CLEAR instructions in HotDocs to dynamically create an option for widows and widowers, so that regardless of gender of our client, the user was always presented with a gender appropriate reference, that still had an identical option under the hood.  This time, we’re going to look at the real power of these instructions: with dynamic repeating content.  For this article, we’re going to look at a situation where we have to address a single letter to multiple vendors and have those vendors specified by the user during the interview.  Here’s the pieces:

VENDOR RPT – repeating dialog that collects vendor data
VENDS Name Full TE – the full name of the vendor on VENDOR RPT
VENDS Addr Block CO – a computation that calculates for address block for each vendor (code not listed, it could just as easily be a text/memo field that is filled in)
LETT Vendors MS – a multi select, multiple choice variable that will ask the user which vendors they wish to send a letter to (dynamically created)
flt LETT Vendors CO – a filter that will look at the user selections in LETT Vendors MS, and filter out the ones that weren’t selected.
COUNTER – the HotDocs system variable that will return the number (as a number) of the current repeating dialog. This can ONLY be used inside a repeat instruction.

Here are the steps:

1) Clear LETT Vendors MS and ADD all vendors to it
2) Present LETT Vendors MS to the user for selection
3) REPEAT VENDORS RPT in the template with the appopriate filter, so only those vendors selected in LETT Vendors MS appear in the resulting document.

Firstly, somewhere in your interview process (you DO use interview computations to calculate, control and regulate data collection for your templates, right?), you will have ASKed the user to fill in the vendor details.  Presuming that we have already collected our vendor details, we now need to build the multiple choice variable.  So somewhere in your interview computation, but AFTER you have ASKed VENDOR RPT, we do this:

ASK NONE
CLEAR LETT Vendors MS //clear first, then ADD
REPEAT VENDOR RPT
ADD "«COUNTER»|«VENDS Name Full TE»" TO LETT Vendors MS //the option is the counter, the prompt is their name
//you could wrap the add instruction inside an IF statement, if you are uncertain as to whether VENDS Name Full TE is ANSWERED() or some other logic particular to your system
END REPEAT
ASK DEFAULT

We now have LETT Vendors MS containing a full list of all vendors.  So at somepoint after the above script runs, you would ASK LETT Vendors MS, most likely as part of a dialog that relates to the letter we are drafting.  Now for what our FILTER looks like.

"«LETT Vendors MS::a|b|c»" CONTAINS "«COUNTER»"

This is a little tricky.  Multiple choice variables store their results as text, but multi-select multiple choices store their values as an ARRAY of text – much like a repeat.  Because of this, a multi-select variable cannot be directly compared to a straight line of “regular” text.  Additionally, no multi choice variable can be compared directly to a number.  So there are three solutions in that one line of code.  The value of LETT Vendors MS is converted to a REGULAR line of text, using the chevrons embedded inside double quotes.  That’s the first solution.  The second solution is to use a custom list format, “a|b|c”, which means that each selection is split by a pipe | character.  I’ll explain this in a later!  The third solution was to wrap COUNTER in chevrons and quotes, which takes COUNTER – a numeric value, and converts it to a string.  With all of this going on, we can now use CONTAINS to correctly compare the selections of LETT Vendors MS and the value of COUNTER.

Now, for the template….

«REPEAT VENDOR RPT::::flt LETT Vendors CO»
«VENDS Name Full TE»
«VENDS Addr Block CO»

Dear «Some Variable Here»

Some letter content here....

{-- conditional page break --}
«END REPEAT»

This instruction will repeat the template infinitely whilever there are iterations inside VENDOR RPT, but will ONLY include iterations where the filter is true.  For the sake of this article, lets say there are three vendors: 1) John Doe 2) Jane Doe and 3) Billy Blogs.  When presented with LETT Vendors MS, it looks like this (brackets contains options):

(1) John Doe
(2) Jane Doe
(3) Billy Blogs

Lets say the user selects 1 and 3.  Here’s what our FILTER looked like:

“«LETT Vendors MS::a|b|c»” CONTAINS “«COUNTER»”

Here’s what happens when our template repeats:

Repeat #1: “1|3” CONTAINS “1” (evaluates to TRUE, John is included)
Repeat #2: “1|3” CONTAINS “2” (evaluates to FALSE, Jane is excluded)
Repeat #3: “1|3” CONTAINS “3” (evaluates to TRUE, Billy is included)

Congratulations.  Your multi select multiple choice variable has allowed you to quickly present a list of ALL vendors to the user and ask them which one gets a letter.  No databases (although you could use one), nothing too heavy; simply collect the vendors, build the multiple choice variable in HotDocs, ask which vendors get the letter, then repeat and filter for the selected values.

Now, I promised a bit more explanation on the whole “a|b|c” thing.  To do that, lets look at a concept called DELIMITING.  Delimiting is simply putting a specific character between each value you want to look at.  Common delimters are commas and pipes.  I prefer pipes, as they aren’t ever used in names, addresses and other pieces of data – they truly do identify the end of one bit of data and the start of the next one.  But lets say we DIDNT delimit our selections from LETT Vendors MS.  Lets say we have 14 vendors (wow!), and the user selected 1, 4, 5, 6, 12.  The value might look like this:

145612

That’s right – its just a string of numbers.  This would mean our filter would “break” when repeating vendor #14.  Because the text “14” appears inside “145612”, even though the user did not selection option #14.  However, with delimiters, our value looks like this:

1|4|5|6|12

And 14 does NOT appear in that value, so the comparison is run correctly.

Clear as mud? Its a bit to get your head around, but when comparing multiple selections in multiple choice options, it is definitely best practice to delimit your strings and use CONTAINS instructions.

ADD TEXT TO MULT_CHOICE – static

Two of the more useful instruction models in HotDocs for dynamic interviews and variables are ADD and CLEAR, which go hand in hand to dynamically construct multiple choice variables.  This is the first of two HotDocs tips, which will deal with the basic CLEAR/ADD instructions with “static” content.  The next article will be about dynamically building a multiple choice variable in HotDocs with a REPEAT instruction.

Lets say we wish to ask for a client’s gender (CLI Gender MC) and their marital status (CLI Marriage MC).  Because we have different language in our template that concerns married clients versus divorced or widowed clients, we need this variable.  However, if a client is a widow/widower, there are two options based on their gender.  Because our language content is the SAME for a widow or widower (with gender specific references), we only want ONE option to denote the widow(er) marriage status.  Here’s how we do it.  We create a computation (say, called build CLI Marriage CO)

ASK NONE
CLEAR CLI Marriage MC //always CLEAR before ADD, as ADD simply appends options to the multiple choice variable
ADD "Single" TO CLI Marriage MC
ADD "Married" TO CLI Marriage MC
IF CLI Gender MC"Male"
ADD "Widow|Widower" TO CLI Marriage MC
ELSE IF CLI Gender MC"Female"
ADD "Widow" TO CLI Marriage MC
ELSE
ADD "Widow|Widow/Widower" TO CLI Marriage MC
END IF
ASK DEFAULT

If the client is male, we add “Widow” as the option, but “Widower” as the prompt.  That’s what the pipe | character is for.  Anything BEFORE the pipe is the option. Everything AFTER the pipe is the prompt for that option, which is what the user sees.  Note that because we chose “Widow” as the generic option for someone who’s partner has deceased, we don’t actually need a prompt for the female specific entry – the option IS the prompt.  If there is no client gender specified, we run with a generic prompt, but the option NEVER actually changes for the widow(er) option.  That means we lessen our code on the template end of things, because our option value is generic.

So now, we have a dynamic looking MC variable that will produce its own options based upon the gender of the client.  No doubt, in the dialog that these variables appear on, you would have something like the following script:

IF !ANSWERED ( CLI Marriage MC )
build CLI Marriage MC
END IF

The dialog script basically says that if CLI Marriage MC is NOT answered, then run the computation that builds the options.  This would likely be a part of a SHOW instruction, so that the variable doesn’t show up until it has options.  Depending on your version of HotDocs, there may be alternate ways to structure this to ensure smooth running of the dialog.

And that’s all there is to it.  This is a very simple way to use logic and the CLEAR/ADD instructions in HotDocs.  It is far more powerful to use ADD in conjunction with a repeat, which we’ll be looking at in my next article.

Restarting and Rescusitating the Time Matters Indexer

The Time Matters indexer may get stuck or corrupted.  This article steps you through solution to that problem.

TRASH AND RECREATE THE LNDATA INDEX

1. Log Everyone out of Time Matters
2. Find the Index Folder and Rename LNDATA
e.g. P:TMW9DataIndexLNDATA
3. There may be a locked open file.  You need to make sure it gets unlocked before you move the file.
4. Log into Time Matters and leave it open to allow LNDATA to be recreated.
5. Check for the Icon in the system tray.

OPTIONAL STEP: ACTIVATE SYNCHRONIZATION
1. File -> Setup -> Program Level
2. Synchronization -> Activate Time Matters Synchronization
3. Give it a name:  MAIN OFFICE
4. Log out of Time Matters

OPTIONAL STEP: REINDEX DATABASE
Now Go to the Time Matter Utilities
1. Select the Database
2. Check box to Reindex Main Database

[Note: Potential problems if there is a SPACE in the File Path to the Data Folder]
[Caveat:  If you have extra licenses, you can leave the indexer running on the server]

Clearing out Temp Files

LOCATE THE USER PROFILE SPECIFIC “LNPTA” FOLDER and TRASH THAT
1. Make sure you can see Hidden Files.
2. You should rename the LNTPA folder.
C:Documents and Settings[UserProfile]Local SettingsTempLNTPA
3. You may need to copy the TMWORD.DAT into the new folder

Expression Model: ANSWERED(VAR) and ANSWERED(DIALOG)

This tip covered the expression models: ANSWERED(VAR) and ANSWERED(DIALOG).  Most often these are used in templates, but they are also used in computations to test whether a variable or a dialog has been answered.  Hotdocs scripts will be interrupted if the value of any required variable is not known.  For this reason, the use of the”answered” function gives a value where no value is known.

What are the elements?

  • ANSWERED: The function
  • VAR: Any variable.  All variables will have an “answered” or “unanswered” status.  Note, that you can force an answered status on a variable under two conditions: (1) if the variable has a “default” and the dialog on which the variable appears has been asked, or (2) the variable is a True/False variable on a dialog with an Ask All setting and that dialog has been asked.
  • DIALOG: Any dialog.  This tests whether the dialog has been “asked” in an interview.

Usage of ANSWERED expression:

  • Usage is disparaged by the software developers as “unnecessary”.  A properly designed template should have sufficient nesting of logic such that you need not test whether a particular variable has been answered.  This is particularly true when you use variable in IF EXPRESSIONS.

     

  • It is also disparaged because the way HotDocs does (or rather does NOT) clear data.  If a variable is “hidden” based on a dialog scripting rule, the hidden variable still retains its value.  For this reason, you should not depend on the answered status of a variable to determine whether a phrase should be included if there are parent conditions not expressed in the template.

     

  • Usage is recommended if you want something special to happen, other than the ordinary, if a variable has not been answered.  While you can use “tokens” in the advanced properties of a variable, you may want to put the rules into a computation.


CLIENT Address 1 TE
IF ANSWERED(CLIENT Address 2 TE)
RESULT + “
“ + CLIENT Address 2 TE
END IF

Expression Model: AGE(DATE)

This tip covers the instruction model: AGE(DATE).  Use this expression if you want to know the age in terms of years as of the current date.  If you want to know the age as of a specific date, other than today, then you will need to use YEARS FROM( DATE , DATE )

What are the elements?

  • AGE: The function 
  • DATE: The start date for measuring the age.  It can be a birth date or the date a debt was incurred.

How do you use it?

AGE(CLIENT Date of Birth DA)

Expression Model: ABSOLUTE VALUE(NUM)

This tip covers the instruction model: ABSOLUTE VALUE(NUM). This model returns the positive (or absolute) value of a number variable.  In some accounting formulas, the result of the formula will be a negative number.  You may want to not the value as a negative, but still be able to treat and format the number based on its positive value

What are the elements?

  • ABSOLUTE VALUE: The function

     

  • NUM: A number value, positive or negative

How do you use it?

Use it in a fillpoint or computation for a variable entered in the system

ABSOLUTE VALUE(Profits NU)

Use it to test the result of a calculation

ABSOLUTE VALUE(Gross Revenue NUExpenses NU)

Expression Model: ZERO(NUM)

This tip covers the use of the instruction model: ZERO(NUM).  When is a number not a number?  When it has no value.  That doesn’t present an issue unless you start running calculations based on an unanswered number.  The solution is ZERO(NUM).

What ZERO expression does is return the number value (if there is a number) or zero.

Use for a sum of different number variables

SET Fruit Total NU TO ZERO(Apples CNT) + ZERO(Oranges CNT) + ZERO(Tangerines CNT)

Use to provide a Total off a Repeat

0
REPEAT Inventory RPT
SET RESULT TO RESULT + ( ZERO(Item CNT) * ZERO(Item Price NU) )
END REPEAT

Limit Spreadsheet Lines Appearing

You want to control the number of lines that appear on a dialog that displays in “Spreadsheet” style.  Quite often, the default number of lines visible on a spreadsheet style dialog are aesthetically offensive. We need to control this for two reasons: 1) its ugly; and 2) screen real estate is quite often at a premium.

Basha Systems use a CNT prefix for specific purpose number variables, to differentiate between a “true” number variable used in document assembly templates, and those number variables used for tracking, counting & limiting. Lets presume we are dealing with a spreadsheet to enter in children’s names and DOB’s. In the dialog PRIOR to the spreadsheet dialog relating to children, create a variable something similar to Var_CNT. The prompt should be something like “How many children do you wish to enter?” In the script of the spreadsheet dialog, place the following:

LIMIT Var_CNT

This will ensure that the spreadsheet is LIMITed to the number of lines that the user has indicated are required. You may wish to REQUIRE the Var_CNT variable, so the user must enter a number to gain access.

If the spreadsheet dialog is actually “Spreadsheet on Parent”, you should script the dialog so that it doesn’t even appear until such time as the Var_CNT variable has been answered. Using this approach, the REQUIRE option is redundant.

Instruction Model: ADD TEXT TO MULT_CHOICE

This tip covers when to use and how to use the HotDocs Instruction Model: ADD TEXT TO MULT_CHOICE.  HotDocs supports dynamic multiple choice variables.  A list of options (and their associated prompts) for a multiple choice variable can be seen in the definition of a particular component. However, this restricts the user to options known at the time that a component file is authored. This instruction model lets the developer dynamically change the option values and their associated prompts based on answers given by the user during an assembly.

What are the elements?

  • ADD: The instruction to Add Text
  • TEXT: A Text Value, a Text Variable, or a Text String consisting of Text and Variables
  • MULT_CHOICE: A Multiple Choice Variable (Single select and Multi-Select)

Other Related Instructions?

  • CLEAR MULT_CHOICE:  Will clear ALL options and prompts for a Multiple Choice Variable

How do you use it?

1. Build from a Repeat

The sample below is used to set the options for a Beneficiary selector.  This option could itself appear on a REPEAT.  The beneficary variable is first CLEARed. Then the script loops through the list of children, adding each child’s name, one at a time to the option list.

CLEAR BENEFICIARY Name MC
REPEAT CHILDREN RPT
ADD CHLD Name TE TO BENEFICIARY Name MC
END REPEAT

2. Build from a Script

The sample below is used to set the options for a Beneficiary selector.  This option could itself appear on a REPEAT.  The beneficary variable is first CLEARed. Then the script loops through the list of children, adding each child’s name, one at a time to the option list.

CLEAR CLI Married MC
ADD "Married|Client is married" TO CLI Married MC
ADD "Single|Client is single" TO CLI Married MC
ADD "Divorced|Client is divorced" TO CLI Married MC
ADD "Widowed|Client is widowed" TO CLI Married MC

3. Build from a Repeat and Add Custom Prompt

The sample below is used to set the options for a list of children to disinherit from a will.  The variable is first CLEARed. Then the script loops through the list of children.  For the option value, it adds each child’s name.  However, for the prompt, it puts in the child’s relationship to the , one at a time to the option list.

CLEAR HEIR Disinherit Name MS
REPEAT CHILDREN RPT
// Change prompt based on gender of child
IF CHLD Gender MC = "Male"
ADD "«CHLD Name TE»|Client's son «CHLD Name TE»" TO HEIR Disinherit Name MS
ELSE
ADD "«CHLD Name TE»|Client's daughter «CHLD Name TE»" TO HEIR Disinherit Name MS
END IF
END REPEAT

SPECIAL NOTES:

  • You must create the Variable and assign a default option (e.g. “Name Goes Here” or “1″)

     

  • You must use a computation script for the CLEAR and ADD instructions.

     

  • The script must be processed before you display the Multiple Choice Variable.

     

  • However, given the way the HotDocs interview works, you can accomplish this by putting the computation on the Dialog Script where the Mutiple Choice Variable is used, or in an INTERVIEW script.  If you choose the latter option, it can go anywhere in the script.

SET Command and GRAYed Variables

You need to SET the value of a variable, but want users to be able to edit the value even after it is SET.  HotDocs will GRAY a variable (prohibiting editing) if the SET command is processed on the dialog, and DEFAULT will not overwrite a variable’s value.

A “regular” script to SET a variable to a value (based upon a Multiple Choice variable) probably looks something like this:

IF ANSWERED ( Var_MC )
IF Var_MC = “1”
SET Var1_TE TO “red”
ELSE
SET Var1_TE TO “blue”
END IF
END IF

As soon as Var_MC is answered, Var_TE will acquire an appropriate value, and subsequently GRAYed out – because it is processed dynamically by the dialog script, and whilever those conditions are met, the variable will not be editable.

We need to avoid HotDocs GRAYIng the variable. The solution? A button that calls a computation.

Lets say we create a variable called Var1_CO – this is the variable that will be called by the button on our dialog. The content of this computation will be exactly the same as the script above. We don’t wish to do anything different, we just wish to shift the source of the SET command.

In our dialog additional text section, we type

@COMPUTE:Var1_CO: Populate

@COMPUTE is the command to tell HotDocs we want a button to call a computation. Var1_CO is the name of the computation variable we are calling. Populate is the button text which will be displayed. When we click this button, the value is SET (provided all conditions have been made), and the variable is editable.